diff --git a/exe/referator b/exe/referator index 2552cf8..e36e739 100755 --- a/exe/referator +++ b/exe/referator @@ -51,16 +51,17 @@ while (line = $stdin.gets) ########## # Config # ########## + when 'REGISTER_SCRIPT' + data = JSON.parse rest + config.scripts.register(**data.transform_keys(&:to_sym)) + success when 'REGISTER_CATEGORY' data = JSON.parse rest config.categories.register String(data).to_sym success when 'REGISTER_FORMAT' data = JSON.parse rest - config.formats.register( - String(data['name']).to_sym, - **data.except('name').transform_keys(&:to_sym), - ) + config.formats.register(**data.transform_keys(&:to_sym)) success when 'REGISTER_REF' data = JSON.parse rest diff --git a/lib/referator.rb b/lib/referator.rb index 846611f..360e937 100644 --- a/lib/referator.rb +++ b/lib/referator.rb @@ -9,6 +9,7 @@ require_relative 'referator/config' require_relative 'referator/config/categories' require_relative 'referator/config/formats' require_relative 'referator/config/repo' +require_relative 'referator/config/scripts' require_relative 'referator/footnotes' require_relative 'referator/note' require_relative 'referator/reference' diff --git a/lib/referator/config.rb b/lib/referator/config.rb index ef4d4a1..8106c54 100644 --- a/lib/referator/config.rb +++ b/lib/referator/config.rb @@ -9,12 +9,17 @@ module Referator end def freeze + scripts.freeze categories.freeze formats.freeze repo.freeze super end + def scripts + @scripts ||= Scripts.new self + end + def categories @categories ||= Categories.new self end diff --git a/lib/referator/config/formats.rb b/lib/referator/config/formats.rb index bedb0d1..900c838 100644 --- a/lib/referator/config/formats.rb +++ b/lib/referator/config/formats.rb @@ -3,40 +3,40 @@ module Referator class Config class Formats - attr_reader :config, :names, :scripts + attr_reader :config def initialize(config) self.config = config - @names = [] @scripts = {} end def freeze - @names.freeze @scripts.freeze super end - def register(name, **kwargs) + def register(name:, script:) + name = String(name).to_sym + script = String(script).to_sym Referator.validate_name! name - raise 'Already exists' if names.index(name) || scripts.key?(name) + Referator.validate_name! script + config.scripts.vars! script, script_vars.keys + raise 'Already exists' if @scripts.key? name - script = Script.new(**kwargs.merge(workdir: config.workdir, - vars: script_vars.keys)) - - names << name - scripts[name] = script + @scripts[name] = script nil end def exists!(name) - scripts[name] or raise 'Unknown format' + Referator.validate_name! name + @scripts[name] or raise 'Unknown format' nil end def render(template, name, notes) exists! name - scripts[name].call( + config.scripts.run( + @scripts[name], **script_vars( template:, format: name, diff --git a/lib/referator/config/scripts.rb b/lib/referator/config/scripts.rb new file mode 100644 index 0000000..6b42ab7 --- /dev/null +++ b/lib/referator/config/scripts.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module Referator + class Config + class Scripts + attr_reader :config + + def initialize(config) + self.config = config + @scripts = {} + end + + def freeze + @scripts.freeze + super + end + + def register(name:, workdir: nil, vars: [], **kwargs) + name = String(name).to_sym + Referator.validate_name! name + raise 'Already exists' if @scripts.key? name + + script = Script.new( + **kwargs, + workdir: workdir || config.workdir, + vars: vars.map { |var| var.instance_of?(String) ? var.to_sym : var }, + ) + + @scripts[name] = script + nil + end + + def vars!(name, vars) + unless vars.instance_of? Array + raise TypeError, "Expected #{Array}, got #{vars.class}" + end + + Referator.validate_name! name + vars.each { |var| Referator.validate_script_var! var } + + script = @scripts[name] or raise 'Invalid script' + + raise 'Invalid vars' unless script.vars.sort == vars.sort + end + + def run(name, **vars) + vars! name, vars.keys + @scripts[name].call(**vars) + end + + private + + def config=(config) + unless config.instance_of? Config + raise TypeError, "Expected #{Config}, got #{config.class}" + end + + @config = config + end + end + end +end diff --git a/test.rb b/test.rb index c2f80df..c349de3 100755 --- a/test.rb +++ b/test.rb @@ -87,6 +87,20 @@ def cmd(name, data) end end +################### +# REGISTER_SCRIPT # +################### + +cmd :REGISTER_SCRIPT, + { name: :render, + vars: %i[template format notes], + args: ['test/render.rb', + { template: nil }, + { format: nil }], + stdin: ['{"notes":', + { notes: nil }, + '}'] } + ##################### # REGISTER_CATEGORY # ##################### @@ -98,21 +112,8 @@ cmd :REGISTER_CATEGORY, :link # REGISTER_FORMAT # ################### -cmd :REGISTER_FORMAT, { name: :html, - args: ['test/render.rb', - { template: nil }, - { format: nil }], - stdin: ['{"notes":', - { notes: nil }, - '}'] } - -cmd :REGISTER_FORMAT, { name: :json, - args: ['test/render.rb', - { template: nil }, - { format: nil }], - stdin: ['{"notes":', - { notes: nil }, - '}'] } +cmd :REGISTER_FORMAT, { name: :html, script: :render } +cmd :REGISTER_FORMAT, { name: :json, script: :render } ################ # REGISTER_REF #