This commit is contained in:
Alex Kotov 2024-02-19 05:29:18 +04:00
parent 16de2d44e6
commit 9dca64928b
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
13 changed files with 59 additions and 195 deletions

View File

@ -7,8 +7,7 @@ $LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib
require 'json'
require 'referator'
$stdin.sync = true
$stdout.sync = true
RE = /\A\s*#\s*@referator\s+(.+)\z/
def serialize_err(err)
{
@ -19,22 +18,29 @@ def serialize_err(err)
}.freeze
end
workdir = ARGV.first
$stdin.sync = true
$stdout.sync = true
workdir = ARGV[0]
workdir = Dir.pwd if String(workdir).strip.empty?
workdir = File.expand_path(workdir).freeze
machine = Referator::Machine.new workdir
while machine.running?
while (line = $stdin.gets&.chomp)
begin
line = $stdin.gets&.strip || 'exit'
line = 'null' if line.empty?
match = RE.match line
if match.nil?
puts line
next
end
command = Referator::Command.parse line
command = Referator::Command.parse match[1]
result = machine.call command
puts "OK #{result.to_json}"
puts result if result
rescue => e
puts "ERR #{serialize_err(e).to_json}"
$stderr.puts "ERR #{serialize_err(e).to_json}"
raise
end
end

View File

@ -8,7 +8,6 @@ require 'pathname'
require_relative 'referator/command'
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'
@ -21,7 +20,7 @@ module Referator
NAME_RE = /\A\w+(_\w+)*\z/
SLUG_RE = /\A\w+(-\w+)*\z/
SCRIPT_ENUMS = %i[format template].sort.freeze
SCRIPT_ENUMS = %i[template].sort.freeze
SCRIPT_OBJS = %i[note notes].sort.freeze
SCRIPT_VARS = [*SCRIPT_ENUMS, *SCRIPT_OBJS].sort.freeze

View File

@ -7,7 +7,6 @@ module Referator
index = str.index(' ') || str.length
name = str[0...index].downcase.to_sym
rest = str[index..].strip
rest = 'null' if rest.empty?
new name, rest
end

View File

@ -11,7 +11,6 @@ module Referator
def freeze
scripts.freeze
categories.freeze
formats.freeze
repo.freeze
super
end
@ -24,10 +23,6 @@ module Referator
@categories ||= Categories.new self
end
def formats
@formats ||= Formats.new self
end
def repo
@repo ||= Repo.new self
end

View File

@ -1,82 +0,0 @@
# frozen_string_literal: true
module Referator
class Config
class Formats
attr_reader :config
def initialize(config)
self.config = config
@scripts = {}
end
def freeze
@scripts.freeze
super
end
def register(name:, script:)
name = String(name).to_sym
script = String(script).to_sym
Referator.validate_name! name
Referator.validate_name! script
config.scripts.vars! script, script_vars.keys
raise 'Already exists' if @scripts.key? name
@scripts[name] = script
nil
end
def exists!(name)
Referator.validate_name! name
@scripts[name] or raise 'Unknown format'
nil
end
def render_footnotes(name, notes)
name = String(name).to_sym
exists! name
config.scripts.run(
@scripts[name],
**script_vars(
template: :footnotes,
format: name,
notes: notes.to_json,
),
)
end
def render_cite_sup(name, note)
name = String(name).to_sym
exists! name
config.scripts.run(
@scripts[name],
**script_vars(
template: :cite_sup,
format: name,
note: note.to_json,
),
)
end
private
def config=(config)
unless config.instance_of? Config
raise TypeError, "Expected #{Config}, got #{config.class}"
end
@config = config
end
def script_vars(template: 'null',
format: 'null',
note: 'null',
notes: 'null')
{ template:, format:, notes:, note: }.freeze
end
end
end
end

View File

@ -10,7 +10,7 @@ module Referator
@references = {}
end
def make_ref(category, id)
def make_ref(category:, id:)
category = category.to_sym if category.instance_of? String
config.categories.exists! category
@references[category] ||= []
@ -19,7 +19,7 @@ module Referator
end
reference = config.repo[category, id]
@references[category] << reference
reference
render_cite_sup(category:, id:)
end
def fetch_footnotes = notes
@ -39,13 +39,17 @@ module Referator
raise 'Unused note'
end
def render_footnotes(format)
format = format.to_sym if format.instance_of? String
config.formats.render_footnotes format, notes
def render_footnotes
config.scripts.run(
:default,
**script_vars(
template: :footnotes,
notes: notes.to_json,
),
)
end
def render_cite_sup(format:, category:, id:)
format = format.to_sym if format.instance_of? String
def render_cite_sup(category:, id:)
category = category.to_sym if category.instance_of? String
note = notes.flat_map(&:last).find do |curr_note|
curr_note[:category] == String(category).to_sym &&
@ -53,7 +57,13 @@ module Referator
end
raise 'Unknown note' if note.nil?
config.formats.render_cite_sup format, note
config.scripts.run(
:default,
**script_vars(
template: :cite_sup,
note: note.to_json,
),
)
end
private
@ -66,6 +76,12 @@ module Referator
@config = config
end
def script_vars(template: 'null',
note: 'null',
notes: 'null')
{ template:, notes:, note: }.freeze
end
def notes
index = 0

View File

@ -7,14 +7,10 @@ module Referator
def initialize(workdir)
self.workdir = workdir
@running = true
@config = Config.new self.workdir
@footnotes = Footnotes.new @config
end
def running? = @running
def call(command)
method_name = "do_#{command.name}"
raise 'Invalid command' unless respond_to? method_name, true
@ -36,23 +32,10 @@ module Referator
# Administrative #
##################
def do_exit(_command)
@running = false
nil
end
def do_null(_command)
nil
end
def do_ping(_command)
:pong
end
def do_exec(command)
File.open File.expand_path command.data, workdir do |file|
code = ''
while running?
loop do
line = file.gets&.strip
break if line.nil?
next if line.empty? || line.start_with?('#')
@ -82,56 +65,27 @@ module Referator
nil
end
def do_register_format(command)
@config.formats.register(**command.data_kwargs!)
nil
end
def do_register_ref(command)
@config.repo.register_ref(**command.data_kwargs!)
nil
end
########
# Info #
########
def do_ref(command)
@config.freeze
@config.repo[*category_and_id(**command.data_kwargs!)].to_h
end
############
# Creation #
############
def do_make_ref(command)
@config.freeze
@footnotes.make_ref(*category_and_id(**command.data_kwargs!)).to_h
String @footnotes.make_ref(**command.data_kwargs!)
end
#############
# Rendering #
#############
def do_fetch_footnotes(_command)
def do_render_footnotes(_command)
@config.freeze
@footnotes.fetch_footnotes
end
def do_fetch_note(command)
@config.freeze
@footnotes.fetch_note(*category_and_id(**command.data_kwargs!)).to_h
end
def do_render_footnotes(command)
@config.freeze
String @footnotes.render_footnotes command.data
end
def do_render_cite_sup(command)
@config.freeze
String @footnotes.render_cite_sup(**command.data_kwargs!)
String @footnotes.render_footnotes
end
#########

View File

@ -89,13 +89,6 @@ def cmd(name, data = nil)
end
end
########
# NULL #
########
cmd('') { |result| raise unless result.nil? }
cmd(:NULL) { |result| raise unless result.nil? }
###################
# REGISTER_SCRIPT #
###################

View File

@ -1,30 +0,0 @@
{
"self": [
<%- notes['self'].each_with_index do |note, index| -%>
{
"index": <%= Integer(note['index']).to_json %>,
"category": "self",
"id": <%= String(note['id']).to_json %>,
"slug": <%= String(note['slug']).to_json %>,
"anchor": <%= String(note['anchor']).to_json %>,
"fragment": <%= String(note['fragment']).to_json %>,
"url": <%= "#{note['id']}.html".to_json %>,
"text": <%= String(note['text']).to_json %>
}<%= ',' unless index == notes['self'].count - 1 %>
<%- end -%>
],
"link": [
<%- notes['link'].each_with_index do |note, index| -%>
{
"index": <%= Integer(note['index']).to_json %>,
"category": "link",
"id": <%= String(note['id']).to_json %>,
"slug": <%= String(note['slug']).to_json %>,
"anchor": <%= String(note['anchor']).to_json %>,
"fragment": <%= String(note['fragment']).to_json %>,
"url": <%= String(note['url']).to_json %>,
"text": <%= String(note['text']).to_json %>
}<%= ',' unless index == notes['link'].count - 1 %>
<%- end -%>
]
}

14
test/input Normal file
View File

@ -0,0 +1,14 @@
# @referator register_script { "name": "default", "vars": ["template", "notes", "note"], "args": ["./render.rb", {"template": null}], "stdin": ["{\"notes\":", {"notes": null}, ",\"note\":", {"note": null}, "}"] }
# @referator register_category "self"
# @referator register_category "link"
# @referator register_ref { "category": "self", "id": "/blog/foo", "slug": "blog-foo", "text": "Foo" }
# @referator register_ref { "category": "link", "id": "example_com", "slug": "example-com", "url": "https://example.com", "text": "Example Domain" }
# @referator exec "conf_register_ref"
<p>
# @referator make_ref { "category": "self", "id": "/blog/foo" }
# @referator make_ref { "category": "link", "id": "example_com" }
# @referator make_ref { "category": "self", "id": "/blog/bar" }
# @referator make_ref { "category": "link", "id": "causa_arcana_com" }
</p>
# @referator render_footnotes "html"

View File

@ -12,7 +12,7 @@ def template(filename)
end.freeze
end
name = "#{ARGV[0]}.#{ARGV[1]}.erb".freeze
name = "#{ARGV[0]}.erb".freeze
vars = JSON.parse($stdin.read).freeze
puts template(name).result_with_hash(vars).strip