coradoc-mirror 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/lib/coradoc/mirror/core_model_to_mirror.rb +181 -0
  3. data/lib/coradoc/mirror/handler_registry.rb +105 -0
  4. data/lib/coradoc/mirror/handlers/admonition.rb +29 -0
  5. data/lib/coradoc/mirror/handlers/bibliography.rb +43 -0
  6. data/lib/coradoc/mirror/handlers/blockquote.rb +19 -0
  7. data/lib/coradoc/mirror/handlers/code_block.rb +69 -0
  8. data/lib/coradoc/mirror/handlers/comment.rb +14 -0
  9. data/lib/coradoc/mirror/handlers/definition_list.rb +69 -0
  10. data/lib/coradoc/mirror/handlers/example.rb +19 -0
  11. data/lib/coradoc/mirror/handlers/footnote.rb +18 -0
  12. data/lib/coradoc/mirror/handlers/frontmatter.rb +71 -0
  13. data/lib/coradoc/mirror/handlers/generic_block.rb +24 -0
  14. data/lib/coradoc/mirror/handlers/horizontal_rule.rb +14 -0
  15. data/lib/coradoc/mirror/handlers/image.rb +58 -0
  16. data/lib/coradoc/mirror/handlers/inline.rb +213 -0
  17. data/lib/coradoc/mirror/handlers/list.rb +80 -0
  18. data/lib/coradoc/mirror/handlers/open_block.rb +16 -0
  19. data/lib/coradoc/mirror/handlers/paragraph.rb +16 -0
  20. data/lib/coradoc/mirror/handlers/reviewer.rb +14 -0
  21. data/lib/coradoc/mirror/handlers/sidebar.rb +19 -0
  22. data/lib/coradoc/mirror/handlers/structural.rb +84 -0
  23. data/lib/coradoc/mirror/handlers/table.rb +82 -0
  24. data/lib/coradoc/mirror/handlers/toc.rb +48 -0
  25. data/lib/coradoc/mirror/handlers/verse.rb +22 -0
  26. data/lib/coradoc/mirror/handlers.rb +38 -0
  27. data/lib/coradoc/mirror/mark.rb +181 -0
  28. data/lib/coradoc/mirror/mark_reverse_builder.rb +142 -0
  29. data/lib/coradoc/mirror/mirror_json_format.rb +42 -0
  30. data/lib/coradoc/mirror/mirror_to_core_model.rb +73 -0
  31. data/lib/coradoc/mirror/mirror_yaml_format.rb +41 -0
  32. data/lib/coradoc/mirror/node.rb +856 -0
  33. data/lib/coradoc/mirror/output.rb +62 -0
  34. data/lib/coradoc/mirror/partitioner.rb +62 -0
  35. data/lib/coradoc/mirror/reverse_builder.rb +600 -0
  36. data/lib/coradoc/mirror/transformer.rb +41 -0
  37. data/lib/coradoc/mirror/version.rb +7 -0
  38. data/lib/coradoc/mirror.rb +161 -0
  39. data/lib/coradoc-mirror.rb +14 -0
  40. metadata +140 -0
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'yaml'
5
+
6
+ module Coradoc
7
+ module Mirror
8
+ # Output processors that integrate with the Coradoc::Output pipeline.
9
+ #
10
+ # Enables:
11
+ # Coradoc.serialize(doc, to: :mirror_json)
12
+ # Coradoc.serialize(doc, to: :mirror_yaml)
13
+ module Output
14
+ # JSON output processor for the Coradoc::Output pipeline.
15
+ class MirrorJson
16
+ class << self
17
+ def processor_id
18
+ :mirror_json
19
+ end
20
+
21
+ def processor_match?(filename)
22
+ filename.downcase.end_with?('.mirror.json')
23
+ end
24
+
25
+ def processor_execute(input, options = {})
26
+ pretty = options[:pretty] != false
27
+ input.each_with_object({}) do |(filename, document), result|
28
+ node = Coradoc::Mirror.transform(document)
29
+ result[filename] = pretty ? JSON.pretty_generate(node.to_hash) : JSON.generate(node.to_hash)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # YAML output processor for the Coradoc::Output pipeline.
36
+ class MirrorYaml
37
+ class << self
38
+ def processor_id
39
+ :mirror_yaml
40
+ end
41
+
42
+ def processor_match?(filename)
43
+ filename.downcase.end_with?('.mirror.yaml', '.mirror.yml')
44
+ end
45
+
46
+ def processor_execute(input, _options = {})
47
+ input.each_with_object({}) do |(filename, document), result|
48
+ node = Coradoc::Mirror.transform(document)
49
+ result[filename] = YAML.dump(node.to_hash)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ # Register with the Coradoc::Output pipeline if available.
59
+ if defined?(Coradoc::Output)
60
+ Coradoc::Output.define(Coradoc::Mirror::Output::MirrorJson)
61
+ Coradoc::Output.define(Coradoc::Mirror::Output::MirrorYaml)
62
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module Mirror
5
+ # Doc-level structural partitioning of built Mirror nodes into the
6
+ # [preface, sections, *bibliography, *trailing] shape per the
7
+ # @metanorma/mirror JS contract.
8
+ #
9
+ # Extracted from Handlers::Structural so handlers stay focused on
10
+ # mapping one CoreModel element → one Mirror node, while the
11
+ # post-emission restructure lives in its own module (MECE).
12
+ module Partitioner
13
+ # Mirror node types that count as "section" for partition bucketing.
14
+ # Includes the legacy 'section' type plus all JS SECTION_TYPES
15
+ # (clause, annex, abstract, foreword, introduction, terms,
16
+ # definitions, references, content_section, acknowledgements).
17
+ SECTION_TYPES = Set.new(%w[
18
+ clause annex content_section abstract foreword introduction
19
+ acknowledgements terms definitions references section
20
+ ]).freeze
21
+
22
+ module_function
23
+
24
+ # Single-pass state machine over a flat list of built Mirror nodes.
25
+ #
26
+ # Loose blocks before any section appears → :preface.
27
+ # Once a section appears → :sections; subsequent loose blocks also
28
+ # go into :sections (preserves document order).
29
+ # Once a bibliography appears → :trailing.
30
+ # Footnotes blocks always go into :trailing regardless of state.
31
+ #
32
+ # @param children [Array<Node>] flat list of built Mirror nodes
33
+ # @return [Hash{Symbol=>Array<Node>}] buckets under :preface,
34
+ # :sections, :bibliography, :trailing
35
+ def partition(children)
36
+ buckets = { preface: [], sections: [], bibliography: [], trailing: [] }
37
+ state = :preface
38
+
39
+ children.each do |child|
40
+ case child.type
41
+ when 'preface'
42
+ buckets[:preface].concat(child.content || [])
43
+ when 'bibliography'
44
+ buckets[:bibliography] << child
45
+ state = :trailing
46
+ else
47
+ if SECTION_TYPES.include?(child.type)
48
+ buckets[:sections] << child
49
+ state = :sections
50
+ elsif child.type == 'footnotes'
51
+ buckets[:trailing] << child
52
+ else
53
+ buckets[state] << child
54
+ end
55
+ end
56
+ end
57
+
58
+ buckets
59
+ end
60
+ end
61
+ end
62
+ end