coradoc-adoc 2.0.7 → 2.0.9

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 (24) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/asciidoc/delimiter_mapping.rb +16 -0
  3. data/lib/coradoc/asciidoc/model/list/definition_item.rb +6 -0
  4. data/lib/coradoc/asciidoc/parser/list.rb +18 -13
  5. data/lib/coradoc/asciidoc/serializer/serializers/list/definition_item.rb +21 -1
  6. data/lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb +89 -0
  7. data/lib/coradoc/asciidoc/transform/element_transformers/document_transformer.rb +43 -0
  8. data/lib/coradoc/asciidoc/transform/element_transformers/inline_transformer.rb +56 -0
  9. data/lib/coradoc/asciidoc/transform/element_transformers/list_transformer.rb +96 -0
  10. data/lib/coradoc/asciidoc/transform/element_transformers/other_transformer.rb +61 -0
  11. data/lib/coradoc/asciidoc/transform/element_transformers/table_transformer.rb +49 -0
  12. data/lib/coradoc/asciidoc/transform/element_transformers.rb +16 -0
  13. data/lib/coradoc/asciidoc/transform/from_core_model.rb +19 -83
  14. data/lib/coradoc/asciidoc/transform/inline_transform_visitor.rb +59 -0
  15. data/lib/coradoc/asciidoc/transform/text_extract_visitor.rb +126 -0
  16. data/lib/coradoc/asciidoc/transform/to_core_model.rb +42 -569
  17. data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +31 -70
  18. data/lib/coradoc/asciidoc/transform/transformer_registry.rb +80 -0
  19. data/lib/coradoc/asciidoc/transform.rb +5 -1
  20. data/lib/coradoc/asciidoc/transformer/list_rules.rb +54 -11
  21. data/lib/coradoc/asciidoc/version.rb +1 -1
  22. data/lib/coradoc/asciidoc.rb +1 -0
  23. metadata +12 -2
  24. data/lib/coradoc/asciidoc/transform/registry.rb +0 -146
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a29195095ab66adca7be3bdfcb331f71fdd69954c09ea3fc0cef33c4583b8d8c
4
- data.tar.gz: 805db091f5043a01ce0b4ff1501c009814c4fdd079ca402a0232b2e3abf073dd
3
+ metadata.gz: ed044cb4af9fd1e18a9cb2c34ddc5c322d801fd24962058a5b6ec55e7a3a9c43
4
+ data.tar.gz: 751978667c8663723085bf0a79d5908cf4a3368e827366a1d703c2602671fcb3
5
5
  SHA512:
6
- metadata.gz: a306bb17db95c5732e1a7e76f101c45a00363c356ebdc0b3d699961caa1a82c6ce2be1f69c531922cb83f53eb49c58735ca814e14a0559a431ee8c9a5ed56a00
7
- data.tar.gz: 42c724be473f6bbdd0b9db339b0ac5a02590fa760f74178088536226380994ef52a812bb7730038e5fe66e25ad888a03b0a4b38c993dbdb5748a4f56e00923df
6
+ metadata.gz: caf485068682d2b714078ff0ec934601a35498fb546d5a97677cbae3b08aa237b598768ca7bafb3f1075868ae5524a01ab20a9fede25d2e4a374d8e67390baca
7
+ data.tar.gz: cf951b3c317c1a40ac4b2d170dba913b4a83d375aa60a8a7a8a16e47865d3ebe7609b61630436d90726fe682e3d78412beadac3ced3589bf642b865ad7250628
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module DelimiterMapping
6
+ CHAR_TO_SEMANTIC = {
7
+ '-' => :source_code,
8
+ '=' => :example,
9
+ '_' => :quote,
10
+ '*' => :sidebar,
11
+ '.' => :literal,
12
+ '+' => :pass
13
+ }.freeze
14
+ end
15
+ end
16
+ end
@@ -32,6 +32,12 @@ module Coradoc
32
32
  attribute :id, :string
33
33
  attribute :terms, Coradoc::AsciiDoc::Model::Term, collection: true
34
34
  attribute :contents, Coradoc::AsciiDoc::Model::TextElement, collection: true
35
+ attribute :delimiter, :string, default: -> { '::' }
36
+ attribute :nested,
37
+ Coradoc::AsciiDoc::Model::Base,
38
+ polymorphic: [Coradoc::AsciiDoc::Model::List::Definition],
39
+ collection: true,
40
+ initialize_empty: true
35
41
 
36
42
  def to_adoc(delimiter: '')
37
43
  Coradoc::AsciiDoc::Serializer.serialize(self, delimiter: delimiter)
@@ -29,10 +29,10 @@ module Coradoc
29
29
  attrs >> r.repeat(1).as(:unordered)
30
30
  end
31
31
 
32
- def definition_list(delimiter = '::')
32
+ def definition_list(_delimiter = nil)
33
33
  (attribute_list >> newline).maybe >>
34
- dlist_item(delimiter).repeat(1).as(:definition_list) >>
35
- dlist_item(delimiter).absent?
34
+ dlist_item.repeat(1).as(:definition_list) >>
35
+ dlist_item.absent?
36
36
  end
37
37
 
38
38
  def list_marker(nesting_level = 1)
@@ -98,27 +98,32 @@ module Coradoc
98
98
  end
99
99
 
100
100
  def dlist_delimiter
101
- (str('::') | str(':::') | str('::::') | str(';;')
101
+ (
102
+ (str(':::::') >> match(':').absent?) |
103
+ (str('::::') >> match(':').absent?) |
104
+ (str(':::') >> match(':').absent?) |
105
+ (str('::') >> match(':').absent?) |
106
+ str(';;')
102
107
  ).as(:delimiter)
103
108
  end
104
109
 
105
- def dlist_term(_delimiter)
106
- (element_id_inline.maybe >>
107
- match("[^\n:]").repeat(1)
108
- .as(:text)
109
- ).as(:dlist_term) >> dlist_delimiter
110
+ def dlist_term(_delimiter = nil)
111
+ term_chars =
112
+ (dlist_delimiter.absent? >> match("[^\n]")).repeat(1)
113
+ .as(:text)
114
+ (element_id_inline.maybe >> term_chars).as(:dlist_term) >> dlist_delimiter
110
115
  end
111
116
 
112
117
  def dlist_definition
113
- text # >> empty_line.repeat(0)
118
+ text
114
119
  .as(:definition) >> line_ending >> empty_line.repeat(0)
115
120
  end
116
121
 
117
- def dlist_item(delimiter)
118
- (((dlist_term(delimiter).as(:terms).repeat(1) >> line_ending >>
122
+ def dlist_item(_delimiter = nil)
123
+ (((dlist_term.as(:terms).repeat(1) >> line_ending >>
119
124
  empty_line.repeat(0)).repeat(1) >>
120
125
  dlist_definition) |
121
- (dlist_term(delimiter).repeat(1, 1).as(:terms) >> space >>
126
+ (dlist_term.repeat(1, 1).as(:terms) >> space >>
122
127
  dlist_definition)
123
128
  ).as(:definition_list_item)
124
129
  end
@@ -8,7 +8,8 @@ module Coradoc
8
8
  class DefinitionItem < Base
9
9
  def to_adoc(model, options_or_context = {})
10
10
  context = normalize_context(options_or_context)
11
- delimiter = context.option(:delimiter, '')
11
+ delimiter = model.delimiter.to_s
12
+ delimiter = context.option(:delimiter, '::') if delimiter.empty?
12
13
  _anchor = model.anchor.nil? ? '' : serialize_child(model.anchor, context)
13
14
  content = +''
14
15
 
@@ -26,6 +27,25 @@ module Coradoc
26
27
 
27
28
  d = model.contents ? serialize_children(model.contents, context) : ''
28
29
  content << "#{d}\n"
30
+
31
+ nested_delimiter = "#{delimiter}:"
32
+ Array(model.nested).each do |nested_list|
33
+ next unless nested_list.is_a?(Coradoc::AsciiDoc::Model::List::Definition)
34
+
35
+ nested_list.items.each do |nested_item|
36
+ content << serialize_with_options(nested_item, delimiter: nested_delimiter)
37
+ end
38
+ end
39
+
40
+ content
41
+ end
42
+
43
+ private
44
+
45
+ def serialize_with_options(child, options = {})
46
+ serializer_class = ElementRegistry.lookup(child.class)
47
+ serializer = serializer_class.new
48
+ serializer.to_adoc(child, options)
29
49
  end
30
50
  end
31
51
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ class BlockTransformer
8
+ class << self
9
+ def transform_paragraph(para)
10
+ children = ToCoreModel.transform_inline_content(para.content)
11
+
12
+ Coradoc::CoreModel::ParagraphBlock.new(
13
+ id: para.id,
14
+ content: ToCoreModel.extract_text_content(para.content),
15
+ children: children
16
+ )
17
+ end
18
+
19
+ def transform_source_block(block)
20
+ non_break_lines = Array(block.lines).reject do |line|
21
+ line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
22
+ line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
23
+ end
24
+ content_lines = non_break_lines.map do |line|
25
+ ToCoreModel.extract_text_content(line)
26
+ end.join("\n")
27
+
28
+ language = ToCoreModel.extract_block_language(block)
29
+
30
+ Coradoc::CoreModel::SourceBlock.new(
31
+ id: block.id,
32
+ title: ToCoreModel.extract_title_text(block.title),
33
+ content: content_lines,
34
+ language: language
35
+ )
36
+ end
37
+
38
+ def transform_block(block, semantic_type_or_delimiter)
39
+ content_lines = ToCoreModel.extract_block_lines(block)
40
+ semantic_type = if semantic_type_or_delimiter.is_a?(Symbol)
41
+ semantic_type_or_delimiter
42
+ else
43
+ ToCoreModel.asciidoc_delimiter_to_semantic(semantic_type_or_delimiter)
44
+ end
45
+
46
+ Coradoc::CoreModel::Block.new(
47
+ block_semantic_type: semantic_type,
48
+ delimiter_type: semantic_type_or_delimiter.is_a?(String) ? semantic_type_or_delimiter : nil,
49
+ id: block.id,
50
+ title: ToCoreModel.extract_title_text(block.title),
51
+ content: content_lines,
52
+ language: ToCoreModel.extract_block_language(block)
53
+ )
54
+ end
55
+
56
+ def transform_typed_block(block, klass, extra_attrs = {})
57
+ lines = Array(block.lines).reject do |line|
58
+ line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
59
+ line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
60
+ end
61
+
62
+ has_nested_blocks = lines.any?(Coradoc::AsciiDoc::Model::Block::Core)
63
+
64
+ if has_nested_blocks
65
+ children = lines.map { |line| ToCoreModel.transform(line) }
66
+ klass.new(
67
+ id: block.id,
68
+ title: ToCoreModel.extract_title_text(block.title),
69
+ children: children,
70
+ language: ToCoreModel.extract_block_language(block),
71
+ **extra_attrs
72
+ )
73
+ else
74
+ content_lines = lines.map { |line| ToCoreModel.extract_text_content(line) }.join("\n")
75
+ klass.new(
76
+ id: block.id,
77
+ title: ToCoreModel.extract_title_text(block.title),
78
+ content: content_lines,
79
+ language: ToCoreModel.extract_block_language(block),
80
+ **extra_attrs
81
+ )
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ class DocumentTransformer
8
+ class << self
9
+ def transform_document(doc)
10
+ title_text = ToCoreModel.extract_title_text(doc.header&.title)
11
+ attributes = ToCoreModel.extract_document_attributes(doc)
12
+ Coradoc::CoreModel::DocumentElement.new(
13
+ id: doc.id,
14
+ title: title_text,
15
+ attributes: attributes,
16
+ children: ToCoreModel.transform(doc.sections || doc.contents || [])
17
+ )
18
+ end
19
+
20
+ def transform_section(section, parent_id: nil)
21
+ title_text = ToCoreModel.extract_title_text(section.title)
22
+ section_id = section.id || Coradoc::CoreModel::IdGenerator.generate_from_title(
23
+ title_text, parent_id: parent_id
24
+ )
25
+
26
+ content_children = ToCoreModel.transform(section.contents || [])
27
+ nested_sections = (section.sections || []).map do |child|
28
+ transform_section(child, parent_id: section_id)
29
+ end
30
+
31
+ Coradoc::CoreModel::SectionElement.new(
32
+ id: section_id,
33
+ level: section.level,
34
+ title: title_text,
35
+ children: content_children + nested_sections
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ class InlineTransformer
8
+ class << self
9
+ def transform_inline(inline, format_type)
10
+ klass = Coradoc::CoreModel::InlineElement.format_type_class(format_type)
11
+ klass.new(
12
+ content: ToCoreModel.extract_text_content(inline.content)
13
+ )
14
+ end
15
+
16
+ def transform_inline_text(inline, format_type)
17
+ klass = Coradoc::CoreModel::InlineElement.format_type_class(format_type)
18
+ klass.new(
19
+ content: inline.text.to_s
20
+ )
21
+ end
22
+
23
+ def transform_inline_footnote(footnote)
24
+ parsed_content = ToCoreModel.parse_and_transform_inline(footnote.text.to_s)
25
+ Coradoc::CoreModel::FootnoteElement.new(
26
+ target: footnote.id,
27
+ content: parsed_content
28
+ )
29
+ end
30
+
31
+ def transform_link(link)
32
+ Coradoc::CoreModel::LinkElement.new(
33
+ target: link.path,
34
+ content: link.name || link.path
35
+ )
36
+ end
37
+
38
+ def transform_cross_reference(xref)
39
+ Coradoc::CoreModel::CrossReferenceElement.new(
40
+ target: xref.href,
41
+ content: xref.args&.first || xref.href
42
+ )
43
+ end
44
+
45
+ def transform_stem(stem)
46
+ Coradoc::CoreModel::StemElement.new(
47
+ content: stem.content,
48
+ stem_type: stem.type || 'stem'
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ class ListTransformer
8
+ class << self
9
+ def transform_list(list, marker_type)
10
+ items = Array(list.items).map do |item|
11
+ if item.is_a?(Coradoc::AsciiDoc::Model::List::DefinitionItem)
12
+ transform_definition_item(item)
13
+ else
14
+ transform_list_item(item)
15
+ end
16
+ end
17
+
18
+ if marker_type == 'definition'
19
+ Coradoc::CoreModel::DefinitionList.new(items: items)
20
+ else
21
+ Coradoc::CoreModel::ListBlock.new(
22
+ marker_type: marker_type,
23
+ items: items
24
+ )
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def transform_definition_item(item)
31
+ term_content = item.terms
32
+ def_content = item.contents
33
+
34
+ term_parts = term_content.is_a?(Array) ? term_content : [term_content]
35
+ parsed_terms = term_parts.flat_map do |part|
36
+ ToCoreModel.parse_inline_text(part)
37
+ end
38
+
39
+ parsed_defs = ToCoreModel.parse_inline_text(def_content)
40
+
41
+ term_children = ToCoreModel.transform_inline_content(parsed_terms)
42
+ def_children = ToCoreModel.transform_inline_content(parsed_defs)
43
+
44
+ di = Coradoc::CoreModel::DefinitionItem.new(
45
+ term: ToCoreModel.extract_text_content(term_children),
46
+ definitions: [ToCoreModel.extract_text_content(def_children)],
47
+ term_children: term_children,
48
+ definition_children: def_children
49
+ )
50
+ di.id = item.id if item.id
51
+
52
+ nested_adoc = Array(item.nested).find do |n|
53
+ n.is_a?(Coradoc::AsciiDoc::Model::List::Definition) && n.items.any?
54
+ end
55
+ di.nested = transform_list(nested_adoc, 'definition') if nested_adoc
56
+
57
+ di
58
+ end
59
+
60
+ def transform_list_item(item)
61
+ content_val = item.content
62
+ children = ToCoreModel.transform_inline_content(content_val)
63
+
64
+ li = Coradoc::CoreModel::ListItem.new(
65
+ content: ToCoreModel.extract_text_content(content_val),
66
+ marker: item.marker
67
+ )
68
+ li.children = children
69
+
70
+ if item.nested.is_a?(Coradoc::AsciiDoc::Model::List::Core)
71
+ nested_core = transform_list(item.nested, list_marker_type(item.nested))
72
+ li.children << nested_core
73
+ elsif item.nested.is_a?(Array)
74
+ item.nested.each do |n|
75
+ next unless n.is_a?(Coradoc::AsciiDoc::Model::List::Core)
76
+
77
+ li.children << transform_list(n, list_marker_type(n))
78
+ end
79
+ end
80
+
81
+ li
82
+ end
83
+
84
+ def list_marker_type(list)
85
+ case list
86
+ when Coradoc::AsciiDoc::Model::List::Ordered then 'ordered'
87
+ when Coradoc::AsciiDoc::Model::List::Definition then 'definition'
88
+ else 'unordered'
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ class OtherTransformer
8
+ class << self
9
+ def transform_term(term)
10
+ Coradoc::CoreModel::Term.new(
11
+ text: term.term.to_s,
12
+ type: term.type&.to_s || 'preferred',
13
+ lang: term.lang&.to_s || 'en'
14
+ )
15
+ end
16
+
17
+ def transform_admonition(admonition)
18
+ children = ToCoreModel.transform_inline_content(admonition.content)
19
+ block = Coradoc::CoreModel::AnnotationBlock.new(
20
+ annotation_type: admonition.type,
21
+ content: ToCoreModel.extract_text_content(admonition.content)
22
+ )
23
+ block.children = children
24
+ block
25
+ end
26
+
27
+ def transform_image(image)
28
+ Coradoc::CoreModel::Image.new(
29
+ src: image.src,
30
+ alt: image.title&.to_s,
31
+ width: image.attributes&.[]('width'),
32
+ height: image.attributes&.[]('height')
33
+ )
34
+ end
35
+
36
+ def transform_bibliography(bib)
37
+ entries = Array(bib.entries).map do |entry|
38
+ transform_bibliography_entry(entry)
39
+ end
40
+
41
+ Coradoc::CoreModel::Bibliography.new(
42
+ id: bib.id,
43
+ title: bib.title.to_s,
44
+ level: nil,
45
+ entries: entries
46
+ )
47
+ end
48
+
49
+ def transform_bibliography_entry(entry)
50
+ Coradoc::CoreModel::BibliographyEntry.new(
51
+ anchor_name: entry.anchor_name,
52
+ document_id: entry.document_id,
53
+ ref_text: entry.ref_text.to_s
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ class TableTransformer
8
+ class << self
9
+ def transform_table(table)
10
+ rows = Array(table.rows).map do |row|
11
+ transform_table_row(row)
12
+ end
13
+
14
+ Coradoc::CoreModel::Table.new(
15
+ id: table.id,
16
+ title: table.title&.to_s,
17
+ rows: rows
18
+ )
19
+ end
20
+
21
+ def transform_table_row(row)
22
+ cells = Array(row.columns).map do |cell|
23
+ transform_table_cell(cell)
24
+ end
25
+ Coradoc::CoreModel::TableRow.new(
26
+ cells: cells,
27
+ header: row.header
28
+ )
29
+ end
30
+
31
+ def transform_table_cell(cell)
32
+ children = ToCoreModel.transform_inline_content(cell.content)
33
+
34
+ Coradoc::CoreModel::TableCell.new(
35
+ content: ToCoreModel.extract_text_content(cell.content),
36
+ alignment: cell.horizontal_alignment,
37
+ vertical_alignment: cell.vertical_alignment,
38
+ colspan: cell.colspan,
39
+ rowspan: cell.rowspan,
40
+ style: cell.style_name,
41
+ children: children
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ module ElementTransformers
7
+ autoload :DocumentTransformer, "#{__dir__}/element_transformers/document_transformer"
8
+ autoload :BlockTransformer, "#{__dir__}/element_transformers/block_transformer"
9
+ autoload :ListTransformer, "#{__dir__}/element_transformers/list_transformer"
10
+ autoload :InlineTransformer, "#{__dir__}/element_transformers/inline_transformer"
11
+ autoload :TableTransformer, "#{__dir__}/element_transformers/table_transformer"
12
+ autoload :OtherTransformer, "#{__dir__}/element_transformers/other_transformer"
13
+ end
14
+ end
15
+ end
16
+ end