Change ordering

This commit is contained in:
Alex Kotov 2023-09-30 04:27:26 +04:00
parent 5944a20b56
commit dbda041877
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
4 changed files with 81 additions and 52 deletions

View file

@ -60,10 +60,10 @@ while (line = $stdin.gets)
data = JSON.parse rest data = JSON.parse rest
config.repo.register_ref(**data.transform_keys(&:to_sym)) config.repo.register_ref(**data.transform_keys(&:to_sym))
success success
when 'ADD_NOTE' when 'MAKE_REF'
config.freeze config.freeze
data = JSON.parse rest data = JSON.parse rest
success footnotes.add_note( success footnotes.make_ref(
String(data['kind']).to_sym, String(data['kind']).to_sym,
String(data['id']), String(data['id']),
).to_h ).to_h
@ -74,6 +74,13 @@ while (line = $stdin.gets)
String(data['kind']).to_sym, String(data['kind']).to_sym,
String(data['id']), String(data['id']),
].to_h ].to_h
when 'FETCH_NOTE'
config.freeze
data = JSON.parse rest
success footnotes.fetch_note(
String(data['kind']).to_sym,
String(data['id']),
).to_h
when 'RENDER_FOOTNOTES' when 'RENDER_FOOTNOTES'
config.freeze config.freeze
data = JSON.parse rest data = JSON.parse rest

View file

@ -7,16 +7,32 @@ module Referator
def initialize(config) def initialize(config)
self.config = config self.config = config
@notes = [] @references = {}
end end
def add_note(kind, id) def make_ref(kind, id)
config.kinds.exists! kind config.kinds.exists! kind
@references[kind] ||= []
@references[kind].each do |reference|
return reference if reference.kind == kind && reference.id == id
end
reference = config.repo[kind, id] reference = config.repo[kind, id]
new_note = Note.new self, @notes.count + 1, reference @references[kind] << reference
@notes.each { |note| return note if note.eql? new_note } reference
@notes << new_note end
new_note
def fetch_note(kind, id)
config.kinds.exists! kind
index = 0
config.kinds.names.each do |cur_kind|
(@references[cur_kind] ||= []).each do |reference|
index += 1
next if cur_kind != kind
return Note.new index, reference if reference.id == id
end
end
raise 'Unused note'
end end
def render(format) def render(format)
@ -34,10 +50,15 @@ module Referator
end end
def notes def notes
config.kinds.names.to_h do |name| index = 0
config.kinds.names.to_h do |kind|
[ [
name, kind,
@notes.select { |note| note.kind == name }.map(&:to_h).freeze, (@references[kind] ||= [])
.map { |reference| Note.new (index += 1), reference }
.map(&:to_h)
.freeze,
] ]
end.freeze end.freeze
end end

View file

@ -2,14 +2,9 @@
module Referator module Referator
class Note class Note
extend Forwardable attr_reader :index, :reference
attr_reader :footnotes, :index, :reference def initialize(index, reference)
def_delegators :reference, :kind, :anchor, :fragment
def initialize(footnotes, index, reference)
self.footnotes = footnotes
self.index = index self.index = index
self.reference = reference self.reference = reference
end end
@ -18,24 +13,8 @@ module Referator
@to_h ||= reference.to_h.merge(index:).freeze @to_h ||= reference.to_h.merge(index:).freeze
end end
def eql?(other)
other.instance_of?(self.class) &&
footnotes == other.footnotes &&
anchor == other.anchor
end
def ==(other) = eql?(other) && index == other.index
private private
def footnotes=(footnotes)
unless footnotes.instance_of? Footnotes
raise TypeError, "Expected #{Footnotes}, got #{footnotes.class}"
end
@footnotes = footnotes
end
def index=(index) def index=(index)
index = Integer index index = Integer index
raise ArgumentError, 'Invalid index' unless index.positive? raise ArgumentError, 'Invalid index' unless index.positive?

58
test.rb
View file

@ -77,7 +77,9 @@ def cmd(name, data)
@stdin.puts "#{name} #{data.to_json}" @stdin.puts "#{name} #{data.to_json}"
result = @stdout.gets.chomp result = @stdout.gets.chomp
if result.start_with? 'OK ' if result.start_with? 'OK '
JSON.parse(result[3..]).freeze result = JSON.parse(result[3..]).freeze
yield result if block_given?
result
elsif result.start_with? 'ERR ' elsif result.start_with? 'ERR '
raise "Error response: #{result[4..]}" raise "Error response: #{result[4..]}"
else else
@ -121,39 +123,59 @@ cmd :REGISTER_REF, RAW_REFS[:link][:causa_arcana_com]
# REF # # REF #
####### #######
cmd(:REF, { kind: :self, id: '/blog/foo' }).tap do |result| cmd :REF, { kind: :self, id: '/blog/foo' } do |result|
raise unless result == REFS[:self][:foo] raise unless result == REFS[:self][:foo]
end end
cmd(:REF, { kind: :self, id: '/blog/bar' }).tap do |result| cmd :REF, { kind: :self, id: '/blog/bar' } do |result|
raise unless result == REFS[:self][:bar] raise unless result == REFS[:self][:bar]
end end
cmd(:REF, { kind: :link, id: :example_com }).tap do |result| cmd :REF, { kind: :link, id: :example_com } do |result|
raise unless result == REFS[:link][:example_com] raise unless result == REFS[:link][:example_com]
end end
cmd(:REF, { kind: :link, id: :causa_arcana_com }).tap do |result| cmd :REF, { kind: :link, id: :causa_arcana_com } do |result|
raise unless result == REFS[:link][:causa_arcana_com] raise unless result == REFS[:link][:causa_arcana_com]
end end
############ ############
# ADD_NOTE # # MAKE_REF #
############ ############
cmd(:ADD_NOTE, { kind: :self, id: '/blog/foo' }).tap do |result| cmd :MAKE_REF, { kind: :self, id: '/blog/foo' } do |result|
raise unless result == REFS[:self][:foo]
end
cmd :MAKE_REF, { kind: :link, id: :example_com } do |result|
raise unless result == REFS[:link][:example_com]
end
cmd :MAKE_REF, { kind: :self, id: '/blog/bar' } do |result|
raise unless result == REFS[:self][:bar]
end
cmd :MAKE_REF, { kind: :link, id: :causa_arcana_com } do |result|
raise unless result == REFS[:link][:causa_arcana_com]
end
##############
# FETCH_NOTE #
##############
cmd :FETCH_NOTE, { kind: :self, id: '/blog/foo' } do |result|
raise unless result == REFS[:self][:foo].merge('index' => 1) raise unless result == REFS[:self][:foo].merge('index' => 1)
end end
cmd(:ADD_NOTE, { kind: :link, id: :example_com }).tap do |result| cmd :FETCH_NOTE, { kind: :self, id: '/blog/bar' } do |result|
raise unless result == REFS[:link][:example_com].merge('index' => 2) raise unless result == REFS[:self][:bar].merge('index' => 2)
end end
cmd(:ADD_NOTE, { kind: :self, id: '/blog/bar' }).tap do |result| cmd :FETCH_NOTE, { kind: :link, id: :example_com } do |result|
raise unless result == REFS[:self][:bar].merge('index' => 3) raise unless result == REFS[:link][:example_com].merge('index' => 3)
end end
cmd(:ADD_NOTE, { kind: :link, id: :causa_arcana_com }).tap do |result| cmd :FETCH_NOTE, { kind: :link, id: :causa_arcana_com } do |result|
raise unless result == REFS[:link][:causa_arcana_com].merge('index' => 4) raise unless result == REFS[:link][:causa_arcana_com].merge('index' => 4)
end end
@ -161,7 +183,7 @@ end
# RENDER_FOOTNOTES # # RENDER_FOOTNOTES #
#################### ####################
cmd(:RENDER_FOOTNOTES, :html).tap do |result| cmd :RENDER_FOOTNOTES, :html do |result|
expected = <<~HTML expected = <<~HTML
<h2>Self references</h2> <h2>Self references</h2>
@ -169,7 +191,7 @@ cmd(:RENDER_FOOTNOTES, :html).tap do |result|
<li id="self-blog-foo" value="1"> <li id="self-blog-foo" value="1">
<a href="/blog/foo.html">Foo</a> <a href="/blog/foo.html">Foo</a>
</li> </li>
<li id="self-blog-bar" value="3"> <li id="self-blog-bar" value="2">
<a href="/blog/bar.html">Bar</a> <a href="/blog/bar.html">Bar</a>
</li> </li>
</ol> </ol>
@ -177,7 +199,7 @@ cmd(:RENDER_FOOTNOTES, :html).tap do |result|
<h2>Link references</h2> <h2>Link references</h2>
<ol> <ol>
<li id="link-example-com" value="2"> <li id="link-example-com" value="3">
<a href="https://example.com">Example Domain</a> <a href="https://example.com">Example Domain</a>
</li> </li>
<li id="link-causa-arcana-com" value="4"> <li id="link-causa-arcana-com" value="4">
@ -189,7 +211,7 @@ cmd(:RENDER_FOOTNOTES, :html).tap do |result|
raise unless result == expected raise unless result == expected
end end
cmd(:RENDER_FOOTNOTES, :json).tap do |result| cmd :RENDER_FOOTNOTES, :json do |result|
expected = <<~JSON expected = <<~JSON
{ {
"self": [ "self": [
@ -204,7 +226,7 @@ cmd(:RENDER_FOOTNOTES, :json).tap do |result|
"text": "Foo" "text": "Foo"
}, },
{ {
"index": 3, "index": 2,
"kind": "self", "kind": "self",
"id": "/blog/bar", "id": "/blog/bar",
"slug": "blog-bar", "slug": "blog-bar",
@ -216,7 +238,7 @@ cmd(:RENDER_FOOTNOTES, :json).tap do |result|
], ],
"link": [ "link": [
{ {
"index": 2, "index": 3,
"kind": "link", "kind": "link",
"id": "example_com", "id": "example_com",
"slug": "example-com", "slug": "example-com",