coradoc-adoc 2.0.0

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 (217) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/lib/coradoc/asciidoc/model/admonition.rb +37 -0
  4. data/lib/coradoc/asciidoc/model/anchorable.rb +64 -0
  5. data/lib/coradoc/asciidoc/model/attached.rb +26 -0
  6. data/lib/coradoc/asciidoc/model/attribute.rb +22 -0
  7. data/lib/coradoc/asciidoc/model/attribute_list/matchers.rb +45 -0
  8. data/lib/coradoc/asciidoc/model/attribute_list.rb +230 -0
  9. data/lib/coradoc/asciidoc/model/attribute_list_attribute.rb +11 -0
  10. data/lib/coradoc/asciidoc/model/audio.rb +44 -0
  11. data/lib/coradoc/asciidoc/model/author.rb +36 -0
  12. data/lib/coradoc/asciidoc/model/base.rb +141 -0
  13. data/lib/coradoc/asciidoc/model/bibliography.rb +37 -0
  14. data/lib/coradoc/asciidoc/model/bibliography_entry.rb +38 -0
  15. data/lib/coradoc/asciidoc/model/block/core.rb +139 -0
  16. data/lib/coradoc/asciidoc/model/block/example.rb +14 -0
  17. data/lib/coradoc/asciidoc/model/block/listing.rb +14 -0
  18. data/lib/coradoc/asciidoc/model/block/literal.rb +14 -0
  19. data/lib/coradoc/asciidoc/model/block/open.rb +14 -0
  20. data/lib/coradoc/asciidoc/model/block/pass.rb +14 -0
  21. data/lib/coradoc/asciidoc/model/block/quote.rb +14 -0
  22. data/lib/coradoc/asciidoc/model/block/reviewer_comment.rb +14 -0
  23. data/lib/coradoc/asciidoc/model/block/side.rb +14 -0
  24. data/lib/coradoc/asciidoc/model/block/source_code.rb +14 -0
  25. data/lib/coradoc/asciidoc/model/block.rb +21 -0
  26. data/lib/coradoc/asciidoc/model/break.rb +33 -0
  27. data/lib/coradoc/asciidoc/model/comment_block.rb +33 -0
  28. data/lib/coradoc/asciidoc/model/comment_line.rb +30 -0
  29. data/lib/coradoc/asciidoc/model/content_list.rb +334 -0
  30. data/lib/coradoc/asciidoc/model/document.rb +197 -0
  31. data/lib/coradoc/asciidoc/model/document_attributes.rb +43 -0
  32. data/lib/coradoc/asciidoc/model/glossaries.rb +11 -0
  33. data/lib/coradoc/asciidoc/model/header.rb +57 -0
  34. data/lib/coradoc/asciidoc/model/highlight.rb +11 -0
  35. data/lib/coradoc/asciidoc/model/image/block_image/attribute_list.rb +23 -0
  36. data/lib/coradoc/asciidoc/model/image/block_image.rb +25 -0
  37. data/lib/coradoc/asciidoc/model/image/core/attribute_list.rb +43 -0
  38. data/lib/coradoc/asciidoc/model/image/core.rb +72 -0
  39. data/lib/coradoc/asciidoc/model/image/inline_image.rb +17 -0
  40. data/lib/coradoc/asciidoc/model/image.rb +14 -0
  41. data/lib/coradoc/asciidoc/model/include.rb +66 -0
  42. data/lib/coradoc/asciidoc/model/inline/anchor.rb +41 -0
  43. data/lib/coradoc/asciidoc/model/inline/attribute_reference.rb +25 -0
  44. data/lib/coradoc/asciidoc/model/inline/base.rb +15 -0
  45. data/lib/coradoc/asciidoc/model/inline/bold.rb +38 -0
  46. data/lib/coradoc/asciidoc/model/inline/cross_reference.rb +29 -0
  47. data/lib/coradoc/asciidoc/model/inline/cross_reference_arg.rb +15 -0
  48. data/lib/coradoc/asciidoc/model/inline/footnote.rb +34 -0
  49. data/lib/coradoc/asciidoc/model/inline/hard_line_break.rb +24 -0
  50. data/lib/coradoc/asciidoc/model/inline/highlight.rb +36 -0
  51. data/lib/coradoc/asciidoc/model/inline/italic.rb +38 -0
  52. data/lib/coradoc/asciidoc/model/inline/link.rb +46 -0
  53. data/lib/coradoc/asciidoc/model/inline/monospace.rb +39 -0
  54. data/lib/coradoc/asciidoc/model/inline/quotation.rb +25 -0
  55. data/lib/coradoc/asciidoc/model/inline/small.rb +25 -0
  56. data/lib/coradoc/asciidoc/model/inline/span.rb +38 -0
  57. data/lib/coradoc/asciidoc/model/inline/stem.rb +24 -0
  58. data/lib/coradoc/asciidoc/model/inline/strikethrough.rb +39 -0
  59. data/lib/coradoc/asciidoc/model/inline/subscript.rb +33 -0
  60. data/lib/coradoc/asciidoc/model/inline/superscript.rb +33 -0
  61. data/lib/coradoc/asciidoc/model/inline/underline.rb +25 -0
  62. data/lib/coradoc/asciidoc/model/inline.rb +31 -0
  63. data/lib/coradoc/asciidoc/model/line_break.rb +11 -0
  64. data/lib/coradoc/asciidoc/model/list/core.rb +61 -0
  65. data/lib/coradoc/asciidoc/model/list/definition.rb +27 -0
  66. data/lib/coradoc/asciidoc/model/list/definition_item.rb +43 -0
  67. data/lib/coradoc/asciidoc/model/list/item.rb +72 -0
  68. data/lib/coradoc/asciidoc/model/list/nestable.rb +14 -0
  69. data/lib/coradoc/asciidoc/model/list/ordered.rb +34 -0
  70. data/lib/coradoc/asciidoc/model/list/unordered.rb +34 -0
  71. data/lib/coradoc/asciidoc/model/list.rb +29 -0
  72. data/lib/coradoc/asciidoc/model/named_attribute.rb +12 -0
  73. data/lib/coradoc/asciidoc/model/paragraph.rb +59 -0
  74. data/lib/coradoc/asciidoc/model/rejected_positional_attribute.rb +12 -0
  75. data/lib/coradoc/asciidoc/model/resolvable.rb +71 -0
  76. data/lib/coradoc/asciidoc/model/resolver.rb +430 -0
  77. data/lib/coradoc/asciidoc/model/reviewer_note.rb +54 -0
  78. data/lib/coradoc/asciidoc/model/revision.rb +47 -0
  79. data/lib/coradoc/asciidoc/model/section.rb +109 -0
  80. data/lib/coradoc/asciidoc/model/serialization/asciidoc_adapter.rb +28 -0
  81. data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping.rb +42 -0
  82. data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping_rule.rb +41 -0
  83. data/lib/coradoc/asciidoc/model/serialization/asciidoc_transform.rb +211 -0
  84. data/lib/coradoc/asciidoc/model/serialization/errors.rb +57 -0
  85. data/lib/coradoc/asciidoc/model/serialization.rb +39 -0
  86. data/lib/coradoc/asciidoc/model/spacing.rb +282 -0
  87. data/lib/coradoc/asciidoc/model/table.rb +44 -0
  88. data/lib/coradoc/asciidoc/model/table_cell.rb +122 -0
  89. data/lib/coradoc/asciidoc/model/table_row.rb +26 -0
  90. data/lib/coradoc/asciidoc/model/tag.rb +36 -0
  91. data/lib/coradoc/asciidoc/model/term.rb +48 -0
  92. data/lib/coradoc/asciidoc/model/text_element.rb +66 -0
  93. data/lib/coradoc/asciidoc/model/title.rb +85 -0
  94. data/lib/coradoc/asciidoc/model/video/attribute_list.rb +43 -0
  95. data/lib/coradoc/asciidoc/model/video.rb +49 -0
  96. data/lib/coradoc/asciidoc/model.rb +75 -0
  97. data/lib/coradoc/asciidoc/parse_error.rb +161 -0
  98. data/lib/coradoc/asciidoc/parser/admonition.rb +26 -0
  99. data/lib/coradoc/asciidoc/parser/attribute_list.rb +110 -0
  100. data/lib/coradoc/asciidoc/parser/base.rb +159 -0
  101. data/lib/coradoc/asciidoc/parser/bibliography.rb +31 -0
  102. data/lib/coradoc/asciidoc/parser/block.rb +186 -0
  103. data/lib/coradoc/asciidoc/parser/block_assembler.rb +183 -0
  104. data/lib/coradoc/asciidoc/parser/cache.rb +155 -0
  105. data/lib/coradoc/asciidoc/parser/citation.rb +32 -0
  106. data/lib/coradoc/asciidoc/parser/content.rb +76 -0
  107. data/lib/coradoc/asciidoc/parser/document_attributes.rb +27 -0
  108. data/lib/coradoc/asciidoc/parser/fix_files.rb +76 -0
  109. data/lib/coradoc/asciidoc/parser/header.rb +31 -0
  110. data/lib/coradoc/asciidoc/parser/inline.rb +199 -0
  111. data/lib/coradoc/asciidoc/parser/list.rb +130 -0
  112. data/lib/coradoc/asciidoc/parser/metadata_detector.rb +164 -0
  113. data/lib/coradoc/asciidoc/parser/paragraph.rb +64 -0
  114. data/lib/coradoc/asciidoc/parser/section.rb +62 -0
  115. data/lib/coradoc/asciidoc/parser/stem.rb +19 -0
  116. data/lib/coradoc/asciidoc/parser/table.rb +166 -0
  117. data/lib/coradoc/asciidoc/parser/term.rb +70 -0
  118. data/lib/coradoc/asciidoc/parser/text.rb +156 -0
  119. data/lib/coradoc/asciidoc/parser.rb +10 -0
  120. data/lib/coradoc/asciidoc/serializer/adoc_serializer.rb +86 -0
  121. data/lib/coradoc/asciidoc/serializer/element_registry.rb +95 -0
  122. data/lib/coradoc/asciidoc/serializer/fallback_serializer.rb +21 -0
  123. data/lib/coradoc/asciidoc/serializer/formatter.rb +144 -0
  124. data/lib/coradoc/asciidoc/serializer/registrations.rb +108 -0
  125. data/lib/coradoc/asciidoc/serializer/serialization_context.rb +238 -0
  126. data/lib/coradoc/asciidoc/serializer/serializers/admonition.rb +19 -0
  127. data/lib/coradoc/asciidoc/serializer/serializers/attribute.rb +23 -0
  128. data/lib/coradoc/asciidoc/serializer/serializers/attribute_list.rb +40 -0
  129. data/lib/coradoc/asciidoc/serializer/serializers/attribute_list_attribute.rb +18 -0
  130. data/lib/coradoc/asciidoc/serializer/serializers/audio.rb +33 -0
  131. data/lib/coradoc/asciidoc/serializer/serializers/author.rb +20 -0
  132. data/lib/coradoc/asciidoc/serializer/serializers/base.rb +152 -0
  133. data/lib/coradoc/asciidoc/serializer/serializers/bibliography.rb +35 -0
  134. data/lib/coradoc/asciidoc/serializer/serializers/bibliography_entry.rb +24 -0
  135. data/lib/coradoc/asciidoc/serializer/serializers/block/core.rb +70 -0
  136. data/lib/coradoc/asciidoc/serializer/serializers/block/example.rb +17 -0
  137. data/lib/coradoc/asciidoc/serializer/serializers/block/listing.rb +22 -0
  138. data/lib/coradoc/asciidoc/serializer/serializers/block/literal.rb +17 -0
  139. data/lib/coradoc/asciidoc/serializer/serializers/block/open.rb +22 -0
  140. data/lib/coradoc/asciidoc/serializer/serializers/block/pass.rb +17 -0
  141. data/lib/coradoc/asciidoc/serializer/serializers/block/quote.rb +17 -0
  142. data/lib/coradoc/asciidoc/serializer/serializers/block/reviewer_comment.rb +17 -0
  143. data/lib/coradoc/asciidoc/serializer/serializers/block/side.rb +22 -0
  144. data/lib/coradoc/asciidoc/serializer/serializers/block/source_code.rb +22 -0
  145. data/lib/coradoc/asciidoc/serializer/serializers/block.rb +23 -0
  146. data/lib/coradoc/asciidoc/serializer/serializers/break.rb +18 -0
  147. data/lib/coradoc/asciidoc/serializer/serializers/comment_block.rb +22 -0
  148. data/lib/coradoc/asciidoc/serializer/serializers/comment_line.rb +22 -0
  149. data/lib/coradoc/asciidoc/serializer/serializers/document.rb +65 -0
  150. data/lib/coradoc/asciidoc/serializer/serializers/document_attributes.rb +21 -0
  151. data/lib/coradoc/asciidoc/serializer/serializers/header.rb +24 -0
  152. data/lib/coradoc/asciidoc/serializer/serializers/highlight.rb +23 -0
  153. data/lib/coradoc/asciidoc/serializer/serializers/image/core.rb +30 -0
  154. data/lib/coradoc/asciidoc/serializer/serializers/image.rb +14 -0
  155. data/lib/coradoc/asciidoc/serializer/serializers/include.rb +19 -0
  156. data/lib/coradoc/asciidoc/serializer/serializers/inline/anchor.rb +20 -0
  157. data/lib/coradoc/asciidoc/serializer/serializers/inline/attribute_reference.rb +20 -0
  158. data/lib/coradoc/asciidoc/serializer/serializers/inline/bold.rb +26 -0
  159. data/lib/coradoc/asciidoc/serializer/serializers/inline/cross_reference.rb +30 -0
  160. data/lib/coradoc/asciidoc/serializer/serializers/inline/cross_reference_arg.rb +20 -0
  161. data/lib/coradoc/asciidoc/serializer/serializers/inline/footnote.rb +24 -0
  162. data/lib/coradoc/asciidoc/serializer/serializers/inline/hard_line_break.rb +20 -0
  163. data/lib/coradoc/asciidoc/serializer/serializers/inline/highlight.rb +26 -0
  164. data/lib/coradoc/asciidoc/serializer/serializers/inline/italic.rb +26 -0
  165. data/lib/coradoc/asciidoc/serializer/serializers/inline/link.rb +38 -0
  166. data/lib/coradoc/asciidoc/serializer/serializers/inline/monospace.rb +26 -0
  167. data/lib/coradoc/asciidoc/serializer/serializers/inline/quotation.rb +21 -0
  168. data/lib/coradoc/asciidoc/serializer/serializers/inline/small.rb +20 -0
  169. data/lib/coradoc/asciidoc/serializer/serializers/inline/span.rb +35 -0
  170. data/lib/coradoc/asciidoc/serializer/serializers/inline/stem.rb +23 -0
  171. data/lib/coradoc/asciidoc/serializer/serializers/inline/strikethrough.rb +29 -0
  172. data/lib/coradoc/asciidoc/serializer/serializers/inline/subscript.rb +29 -0
  173. data/lib/coradoc/asciidoc/serializer/serializers/inline/superscript.rb +26 -0
  174. data/lib/coradoc/asciidoc/serializer/serializers/inline/underline.rb +20 -0
  175. data/lib/coradoc/asciidoc/serializer/serializers/inline.rb +32 -0
  176. data/lib/coradoc/asciidoc/serializer/serializers/line_break.rb +18 -0
  177. data/lib/coradoc/asciidoc/serializer/serializers/list/core.rb +47 -0
  178. data/lib/coradoc/asciidoc/serializer/serializers/list/definition.rb +35 -0
  179. data/lib/coradoc/asciidoc/serializer/serializers/list/definition_item.rb +38 -0
  180. data/lib/coradoc/asciidoc/serializer/serializers/list/item.rb +120 -0
  181. data/lib/coradoc/asciidoc/serializer/serializers/list/ordered.rb +24 -0
  182. data/lib/coradoc/asciidoc/serializer/serializers/list/unordered.rb +29 -0
  183. data/lib/coradoc/asciidoc/serializer/serializers/list.rb +19 -0
  184. data/lib/coradoc/asciidoc/serializer/serializers/named_attribute.rb +22 -0
  185. data/lib/coradoc/asciidoc/serializer/serializers/paragraph.rb +65 -0
  186. data/lib/coradoc/asciidoc/serializer/serializers/reviewer_note.rb +28 -0
  187. data/lib/coradoc/asciidoc/serializer/serializers/revision.rb +26 -0
  188. data/lib/coradoc/asciidoc/serializer/serializers/section.rb +37 -0
  189. data/lib/coradoc/asciidoc/serializer/serializers/table.rb +24 -0
  190. data/lib/coradoc/asciidoc/serializer/serializers/table_cell.rb +75 -0
  191. data/lib/coradoc/asciidoc/serializer/serializers/table_row.rb +24 -0
  192. data/lib/coradoc/asciidoc/serializer/serializers/tag.rb +19 -0
  193. data/lib/coradoc/asciidoc/serializer/serializers/term.rb +20 -0
  194. data/lib/coradoc/asciidoc/serializer/serializers/text_element.rb +23 -0
  195. data/lib/coradoc/asciidoc/serializer/serializers/title.rb +55 -0
  196. data/lib/coradoc/asciidoc/serializer/serializers/video.rb +33 -0
  197. data/lib/coradoc/asciidoc/serializer/spacing_strategy.rb +70 -0
  198. data/lib/coradoc/asciidoc/serializer.rb +75 -0
  199. data/lib/coradoc/asciidoc/transform/from_core_model.rb +502 -0
  200. data/lib/coradoc/asciidoc/transform/from_core_model_registrations.rb +126 -0
  201. data/lib/coradoc/asciidoc/transform/registry.rb +146 -0
  202. data/lib/coradoc/asciidoc/transform/to_core_model.rb +564 -0
  203. data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +257 -0
  204. data/lib/coradoc/asciidoc/transform.rb +13 -0
  205. data/lib/coradoc/asciidoc/transformer/block_rules.rb +101 -0
  206. data/lib/coradoc/asciidoc/transformer/header_rules.rb +91 -0
  207. data/lib/coradoc/asciidoc/transformer/inline_rules.rb +179 -0
  208. data/lib/coradoc/asciidoc/transformer/list_rules.rb +131 -0
  209. data/lib/coradoc/asciidoc/transformer/misc_rules.rb +196 -0
  210. data/lib/coradoc/asciidoc/transformer/structural_rules.rb +216 -0
  211. data/lib/coradoc/asciidoc/transformer/text_rules.rb +107 -0
  212. data/lib/coradoc/asciidoc/transformer.rb +406 -0
  213. data/lib/coradoc/asciidoc/version.rb +7 -0
  214. data/lib/coradoc/asciidoc.rb +148 -0
  215. data/lib/coradoc/util/asciidoc.rb +71 -0
  216. data/lib/coradoc/util.rb +8 -0
  217. metadata +343 -0
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+
5
+ module Coradoc
6
+ module AsciiDoc
7
+ module Parser
8
+ # Parser cache for optimizing repeated parses of the same content
9
+ #
10
+ # This is an opt-in feature that caches parse results based on content hashing.
11
+ # Useful for IDE integrations, watch mode, or any scenario where the same
12
+ # content is parsed multiple times.
13
+ #
14
+ # @example Basic usage
15
+ # cache = Coradoc::AsciiDoc::Parser::Cache.new
16
+ # ast = cache.fetch_or_parse(content) { Parser::Base.parse(content) }
17
+ #
18
+ # @example With size limit
19
+ # cache = Coradoc::AsciiDoc::Parser::Cache.new(max_size: 100)
20
+ #
21
+ # @example Global cache (use with caution)
22
+ # Coradoc::AsciiDoc::Parser::Cache.global do |c|
23
+ # c.fetch_or_parse(content) { Parser::Base.parse(content) }
24
+ # end
25
+ class Cache
26
+ # Default maximum cache size
27
+ DEFAULT_MAX_SIZE = 50
28
+
29
+ # Get the global cache instance
30
+ # @return [Cache, nil] The global cache instance
31
+ def self.global
32
+ @global ||= nil
33
+ end
34
+
35
+ # Set the global cache instance
36
+ # @param cache [Cache, nil] The cache instance
37
+ class << self
38
+ attr_writer :global
39
+ end
40
+
41
+ # Execute a block with a global cache
42
+ # @param max_size [Integer] Maximum cache entries
43
+ # @yield [Cache] The cache instance
44
+ # @return [Object] The block result
45
+ def self.with_global(max_size: DEFAULT_MAX_SIZE)
46
+ previous = @global
47
+ @global = new(max_size: max_size)
48
+ begin
49
+ yield @global
50
+ ensure
51
+ @global = previous
52
+ end
53
+ end
54
+
55
+ # Clear the global cache
56
+ def self.clear_global!
57
+ @global&.clear
58
+ end
59
+
60
+ # Initialize a new cache
61
+ # @param max_size [Integer] Maximum number of entries to cache
62
+ def initialize(max_size: DEFAULT_MAX_SIZE)
63
+ @max_size = max_size
64
+ @cache = {}
65
+ @access_order = []
66
+ @mutex = Mutex.new
67
+ end
68
+
69
+ # Fetch a cached result or parse and cache
70
+ #
71
+ # @param content [String] The content to parse
72
+ # @yield Block to execute if cache miss
73
+ # @return [Object] The parsed AST
74
+ def fetch_or_parse(content)
75
+ key = content_hash(content)
76
+
77
+ mutex.synchronize do
78
+ if cache.key?(key)
79
+ # Move to end of access order (most recently used)
80
+ access_order.delete(key)
81
+ access_order.push(key)
82
+ return cache[key]
83
+ end
84
+ end
85
+
86
+ # Parse outside the lock for concurrency
87
+ result = yield if block_given?
88
+
89
+ mutex.synchronize do
90
+ # Evict oldest if at capacity
91
+ evict_oldest if cache.size >= max_size
92
+
93
+ cache[key] = result
94
+ access_order.push(key)
95
+ end
96
+
97
+ result
98
+ end
99
+
100
+ # Check if content is cached
101
+ # @param content [String] The content to check
102
+ # @return [Boolean] True if cached
103
+ def cached?(content)
104
+ key = content_hash(content)
105
+ mutex.synchronize { cache.key?(key) }
106
+ end
107
+
108
+ # Get cache statistics
109
+ # @return [Hash] Statistics including size, max_size, hits, misses
110
+ def stats
111
+ mutex.synchronize do
112
+ {
113
+ size: cache.size,
114
+ max_size: max_size,
115
+ keys: access_order.dup
116
+ }
117
+ end
118
+ end
119
+
120
+ # Clear the cache
121
+ def clear
122
+ mutex.synchronize do
123
+ cache.clear
124
+ access_order.clear
125
+ end
126
+ end
127
+
128
+ # Get the current cache size
129
+ # @return [Integer] Number of cached entries
130
+ def size
131
+ mutex.synchronize { cache.size }
132
+ end
133
+
134
+ private
135
+
136
+ attr_reader :cache, :max_size, :access_order, :mutex
137
+
138
+ # Generate a hash key for content
139
+ # @param content [String] The content
140
+ # @return [String] SHA256 hash of content
141
+ def content_hash(content)
142
+ Digest::SHA256.hexdigest(content)
143
+ end
144
+
145
+ # Evict the oldest (least recently used) entry
146
+ def evict_oldest
147
+ return if access_order.empty?
148
+
149
+ oldest_key = access_order.shift
150
+ cache.delete(oldest_key)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Parser
6
+ module Citation
7
+ def xref_anchor
8
+ match('[^,>]').repeat(1).as(:href_arg).repeat(1, 1)
9
+ end
10
+
11
+ def xref_str
12
+ match('[^,>]').repeat(1).as(:text)
13
+ end
14
+
15
+ def xref_arg
16
+ (str('section') | str('paragraph') | str('clause') | str('annex') | str('table')).as(:key) >>
17
+ match('[ =]').as(:delimiter) >>
18
+ match('[^,>=]').repeat(1).as(:value)
19
+ end
20
+
21
+ def cross_reference
22
+ (str('<<') >> xref_anchor >>
23
+ ((str(',') >> xref_arg).repeat(1) |
24
+ (str(',') >> xref_str).repeat(1)
25
+ ).maybe >>
26
+ str('>>')
27
+ ).as(:cross_reference)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Parser
6
+ module Content
7
+ def literal_space
8
+ (match[' '] | match[' \t']).repeat(1)
9
+ end
10
+
11
+ # Override
12
+ def literal_space?
13
+ literal_space.maybe
14
+ end
15
+
16
+ def list_prefix
17
+ (line_start? >>
18
+ ((match('^[*]') >> str('*').repeat(1, 5)) |
19
+ (match('^[\.]') >> str('.').repeat(1, 5))) >>
20
+ str(' '))
21
+ end
22
+
23
+ # Text
24
+ # :zero :one :many
25
+ def text_line(many_breaks = false, unguarded: false, verbatim: false)
26
+ tl = if verbatim
27
+ text_any.as(:text)
28
+ elsif unguarded
29
+ literal_space? >> text_any.as(:text)
30
+ else
31
+ (asciidoc_char_with_id.absent? | element_id_inline) >>
32
+ literal_space? >> text_any.as(:text)
33
+ end
34
+ if many_breaks
35
+ tl >> (line_ending.repeat(1).as(:line_break) | eof?)
36
+ else
37
+ tl >> (line_ending.as(:line_break) | eof?)
38
+ end
39
+ end
40
+
41
+ def asciidoc_char
42
+ line_start? >> match['*_:+=\-']
43
+ end
44
+
45
+ def asciidoc_char_with_id
46
+ asciidoc_char | str('[#') | str('[[')
47
+ end
48
+
49
+ def element_id
50
+ line_start? >>
51
+ ((str('[[') >> keyword.as(:id) >> str(']]')) |
52
+ (str('[#') >> keyword.as(:id) >> str(']'))
53
+ ) >> newline
54
+ end
55
+
56
+ def element_id_inline
57
+ (str('[[') >> keyword.as(:id) >> str(']]')) |
58
+ (str('[#') >> keyword.as(:id) >> str(']'))
59
+ end
60
+
61
+ def glossary
62
+ keyword.as(:key) >> str('::') >> (str(' ') | newline) >>
63
+ text.as(:value) >> line_ending.as(:line_break)
64
+ end
65
+
66
+ def glossaries
67
+ glossary.repeat(1)
68
+ end
69
+
70
+ def page_break
71
+ str('<<<') >> line_ending
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Parser
6
+ module DocumentAttributes
7
+ def attribute_name
8
+ match('[a-zA-Z0-9_-]').repeat(1)
9
+ end
10
+
11
+ def attribute_value
12
+ text | (str('') >> str("\n").absent?)
13
+ end
14
+
15
+ def document_attributes
16
+ document_attribute.repeat(1)
17
+ .as(:document_attributes)
18
+ end
19
+
20
+ def document_attribute
21
+ str(':') >> attribute_name.as(:key) >> str(':') >>
22
+ space? >> (attribute_value | str('')).as(:value) >> (line_ending | eof?)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Script to fix parser file structure
4
+
5
+ files = %w[attribute_list.rb bibliography.rb block.rb block_assembler.rb citation.rb
6
+ content.rb document_attributes.rb header.rb inline.rb list.rb
7
+ metadata_detector.rb paragraph.rb section.rb table.rb term.rb text.rb]
8
+
9
+ files.each do |filename|
10
+ next unless File.exist?(filename)
11
+
12
+ content = File.read(filename)
13
+ lines = content.lines
14
+
15
+ # The correct structure should be:
16
+ # module Coradoc
17
+ # module AsciiDoc
18
+ # module Parser
19
+ # module SomeModule
20
+ # ...content...
21
+ # end
22
+ # end
23
+ # end
24
+ # end
25
+
26
+ # Count structure
27
+ puts "=== #{filename} ==="
28
+
29
+ # Find all lines that are just "end" with various indentation
30
+ end_lines = lines.each_with_index.select { |line, _i| line.strip == 'end' }
31
+ puts "Found #{end_lines.size} 'end' statements"
32
+
33
+ # We should have exactly 4 'end' statements for the module nesting
34
+ # (Coradoc, AsciiDoc, Parser, SomeModule)
35
+ # But we might have a class inside which adds more
36
+
37
+ # Let's just fix the pattern: if we have " end" followed by "end" at the end,
38
+ # the " end" is extra
39
+
40
+ new_lines = []
41
+ i = 0
42
+ while i < lines.size
43
+ line = lines[i]
44
+
45
+ # Check for the pattern: " end" followed by " end" followed by "end"
46
+ if line == " end\n" && i + 2 < lines.size &&
47
+ lines[i + 1] == " end\n" && lines[i + 2] == "end\n"
48
+ # Keep the " end", skip the extra " end", keep "end"
49
+ new_lines << line
50
+ new_lines << lines[i + 2]
51
+ i += 3
52
+ next
53
+ end
54
+
55
+ # Check for pattern: " end" followed by " end" followed by " end" followed by "end"
56
+ if line == " end\n" && i + 3 < lines.size &&
57
+ lines[i + 1] == " end\n" && lines[i + 2] == " end\n" && lines[i + 3] == "end\n"
58
+ # This is: end (class/module), end (Parser), end (AsciiDoc), end (Coradoc)
59
+ # But we have an extra one - the correct should be:
60
+ # end (inner module), end (Parser), end (AsciiDoc), end (Coradoc)
61
+ # Let's see what's inside...
62
+ new_lines << line
63
+ new_lines << " end\n"
64
+ new_lines << " end\n"
65
+ new_lines << "end\n"
66
+ i += 4
67
+ next
68
+ end
69
+
70
+ new_lines << line
71
+ i += 1
72
+ end
73
+
74
+ File.write(filename, new_lines.join)
75
+ puts "Fixed: #{filename}"
76
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Parser
6
+ module Header
7
+ def header
8
+ header_title >>
9
+ author.maybe.as(:author) >>
10
+ revision.maybe.as(:revision) >> newline.maybe
11
+ end
12
+
13
+ def header_title
14
+ match('^=') >> str('=').absent? >> space? >> text.as(:title) >> newline
15
+ end
16
+
17
+ def author
18
+ words.as(:first_name) >> str(',') >>
19
+ space? >> words.as(:last_name) >>
20
+ space? >> str('<') >> email.as(:email) >> str('>') >> newline
21
+ end
22
+
23
+ def revision
24
+ (word >> (str('.') >> word).maybe).as(:number) >>
25
+ str(',') >> space? >> date.as(:date) >> str(':') >>
26
+ space? >> words.as(:remark) >> newline
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Parser
6
+ module Inline
7
+ def attribute_reference
8
+ str('{').present? >> str('{') >>
9
+ match('[a-zA-Z0-9_-]').repeat(1).as(:attribute_reference) >>
10
+ str('}')
11
+ end
12
+
13
+ def bold_constrained
14
+ (str('*').present? >> str('*') >>
15
+ match('[^*\n]').repeat(1).as(:text).repeat(1, 1) >>
16
+ str('*') >> str('*').absent? >>
17
+ str("\n\n").absent?
18
+ ).as(:bold_constrained)
19
+ end
20
+
21
+ def bold_unconstrained
22
+ (str('**').present? >> str('**') >>
23
+ match('[^*\n]').repeat(1).as(:text).repeat(1, 1) >>
24
+ str('**')
25
+ ).as(:bold_unconstrained)
26
+ end
27
+
28
+ def span_constrained
29
+ (attribute_list >>
30
+ str('#') >>
31
+ match('[^#\n]').repeat(1).as(:text) >>
32
+ str('#') >> str('#').absent?
33
+ ).as(:span_constrained)
34
+ end
35
+
36
+ def span_unconstrained
37
+ (attribute_list >>
38
+ str('##') >>
39
+ match('[^#\n]').repeat(1).as(:text) >>
40
+ str('##')
41
+ ).as(:span_unconstrained)
42
+ end
43
+
44
+ def italic_constrained
45
+ (str('_') >> str('_').absent? >>
46
+ match('[^_\n]').repeat(1).as(:text).repeat(1, 1) >>
47
+ str('_') >> str('_').absent?
48
+ ).as(:italic_constrained)
49
+ end
50
+
51
+ def italic_unconstrained
52
+ (str('__') >>
53
+ match('[^_\n]').repeat(1).as(:text).repeat(1, 1) >>
54
+ str('__')
55
+ ).as(:italic_unconstrained)
56
+ end
57
+
58
+ def highlight_constrained
59
+ (str('#') >>
60
+ match('[^#\n]').repeat(1).as(:text).repeat(1, 1) >>
61
+ str('#') >> str('#').absent?
62
+ ).as(:highlight_constrained)
63
+ end
64
+
65
+ def highlight_unconstrained
66
+ (str('##') >>
67
+ match('[^#\n]').repeat(1).as(:text).repeat(1, 1) >>
68
+ str('##')
69
+ ).as(:highlight_unconstrained)
70
+ end
71
+
72
+ def monospace_constrained
73
+ (str('`') >>
74
+ match('[^`\n]').repeat(1).as(:text).repeat(1, 1) >>
75
+ str('`') >> str('`').absent?
76
+ ).as(:monospace_constrained)
77
+ end
78
+
79
+ def monospace_unconstrained
80
+ (str('``') >>
81
+ match('[^`\n]').repeat(1).as(:text).repeat(1, 1) >>
82
+ str('``')
83
+ ).as(:monospace_unconstrained)
84
+ end
85
+
86
+ def superscript
87
+ (str('^') >>
88
+ match('[^^\n]').repeat(1).as(:text).repeat(1, 1) >>
89
+ str('^')
90
+ ).as(:superscript)
91
+ end
92
+
93
+ def subscript
94
+ (str('~') >>
95
+ match('[^~\n]').repeat(1).as(:text).repeat(1, 1) >>
96
+ str('~')
97
+ ).as(:subscript)
98
+ end
99
+
100
+ def span
101
+ attribute_list >>
102
+ (str('#') >>
103
+ match('[^#\n]').repeat(1).as(:text) >>
104
+ str('#') >> str('#').absent?
105
+ ).as(:span)
106
+ end
107
+
108
+ def link
109
+ ((str('http').present? | str('https').present? | str('ftp').present?) >>
110
+ match('[A-Za-z0-9_.\\-:/&?=+,%#~;]+').repeat(1).as(:path) >>
111
+ (str('[') >> match('[^\\]]').repeat(1).as(:text) >> str(']')).maybe
112
+ ).as(:link) |
113
+ (str('link:').present? >> str('link:') >>
114
+ match('[A-Za-z0-9_.\\-:/&?=+,%#~;]+').repeat(1).as(:path) >>
115
+ (str('[') >> match('[^\\]]').repeat(1).as(:text) >> str(']')).maybe
116
+ ).as(:link)
117
+ end
118
+
119
+ def inline_image
120
+ (str('image:').present? >> str('image:') >>
121
+ match('[A-Za-z0-9_.\\-:/&?=+,%#~;]+').repeat(1).as(:path) >>
122
+ (str('[') >> match('[^\\]]').repeat(1).as(:text) >> str(']')).maybe
123
+ ).as(:inline_image)
124
+ end
125
+
126
+ def underline
127
+ (attribute_list >> match('\\[.underline\\]').as(:role) >>
128
+ str('#') >>
129
+ match('[^#\n]').repeat(1).as(:text) >>
130
+ str('#')
131
+ ).as(:underline)
132
+ end
133
+
134
+ def small
135
+ (attribute_list >> match('\\[.small\\]').as(:role) >>
136
+ str('#') >>
137
+ match('[^#\n]').repeat(1).as(:text) >>
138
+ str('#')
139
+ ).as(:small)
140
+ end
141
+
142
+ def inline_chars?
143
+ match('[\[*#_{<^~`]').present? |
144
+ str('http').present? |
145
+ str('https').present? |
146
+ str('link:').present? |
147
+ str('image:').present? |
148
+ term_type.present? |
149
+ str('footnote').present? |
150
+ stem_type.present?
151
+ end
152
+
153
+ def inline
154
+ bold_unconstrained |
155
+ bold_constrained |
156
+ span_unconstrained |
157
+ span_constrained |
158
+ italic_unconstrained |
159
+ italic_constrained |
160
+ highlight_unconstrained |
161
+ highlight_constrained |
162
+ monospace_unconstrained |
163
+ monospace_constrained |
164
+ superscript |
165
+ subscript |
166
+ attribute_reference |
167
+ cross_reference |
168
+ term_inline |
169
+ term_inline2 |
170
+ footnote |
171
+ stem |
172
+ link |
173
+ inline_image |
174
+ underline |
175
+ small
176
+ end
177
+
178
+ def text_unformatted
179
+ # line_not_text? >>
180
+ (inline.absent? >>
181
+ match("[^\n]")
182
+ ).repeat(1)
183
+ end
184
+
185
+ def text_formatted
186
+ (inline_chars? >> inline)
187
+ end
188
+
189
+ def text_any
190
+ (text_formatted |
191
+ text_unformatted.as(:text)
192
+ ).repeat(2) |
193
+ text_formatted.repeat(1, 1) |
194
+ text_unformatted
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end