inkmark 0.1.0-arm64-darwin

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.
Binary file
Binary file
Binary file
@@ -0,0 +1,342 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Inkmark
4
+ # Represents a parsed document element passed to {Inkmark#on} handlers.
5
+ #
6
+ # ## Reading fields
7
+ #
8
+ # Every event exposes:
9
+ # - {#kind} the element type as a Symbol
10
+ # - {#text} the concatenated plain text of all descendant text nodes
11
+ # - {#depth} the nesting depth (0 = top-level block)
12
+ # - {#parent_kind} the kind of the immediate parent, or +nil+ at the root
13
+ # - {#ancestor_kinds} an array of ancestor kinds from parent to root
14
+ # - {#children} child Event objects (containers only; empty for leaves)
15
+ # - {#children_of} children filtered by kind
16
+ #
17
+ # ## Mutating elements
18
+ #
19
+ # Set any mutable attribute inside a handler to transform the element's output:
20
+ # - {#html=} replace the element's entire output with a raw HTML string
21
+ # - {#dest=} rewrite the URL on +:link+ or +:image+ elements
22
+ # - {#title=} rewrite the title on +:link+ or +:image+ elements
23
+ # - {#level=} change the heading level (1–6) on +:heading+ elements
24
+ # - {#id=} change the heading +id+ attribute on +:heading+ elements
25
+ #
26
+ # Call {#delete} to suppress the element entirely (nothing emitted).
27
+ #
28
+ # ## Kind reference
29
+ #
30
+ # Handlers fire post-order: children are processed before parents, so
31
+ # container elements see their children already available.
32
+ #
33
+ # ### Container kinds
34
+ #
35
+ # Containers have matching Start/End events. Their handler fires after
36
+ # all children have been processed.
37
+ #
38
+ # #### +:heading+
39
+ # - +text+ plain text of the heading (emoji already resolved)
40
+ # - +level+ heading level 1–6 (mutable via +level=+)
41
+ # - +id+ slug from +headings: { ids: true }+ option, otherwise +nil+ (mutable via +id=+)
42
+ # - +children+ inline child nodes (text, strong, emphasis, link, code, …)
43
+ # - Mutable: +level=+, +id=+, +html=+
44
+ #
45
+ # #### +:paragraph+
46
+ # - +text+ plain text content
47
+ # - +children+ inline child nodes
48
+ # - Mutable: +html=+
49
+ #
50
+ # #### +:blockquote+
51
+ # - +text+ plain text of all descendant text nodes
52
+ # - +children+ block child nodes (paragraphs, nested blockquotes, …)
53
+ # - Mutable: +html=+
54
+ #
55
+ # #### +:list+
56
+ # - +children+ +:list_item+ elements
57
+ # - Mutable: +html=+
58
+ #
59
+ # #### +:ordered_list+
60
+ # - +children+ +:list_item+ elements
61
+ # - Mutable: +html=+
62
+ #
63
+ # #### +:list_item+
64
+ # - +text+ plain text content
65
+ # - +children+ block or inline child nodes
66
+ # - Mutable: +html=+
67
+ #
68
+ # #### +:code_block+
69
+ # - +text+ / +source+ source code (identical; +source+ is an alias)
70
+ # - +lang+ fenced language tag, or +nil+ for indented blocks
71
+ # - +children+ always empty; content is plain text, not parsed inline events
72
+ # - Mutable: +html=+
73
+ # - Note: even when +syntax_highlight: true+ is enabled, the handler still
74
+ # sees the event as +:code_block+. Setting +html=+ overrides the highlighter.
75
+ #
76
+ # #### +:table+
77
+ # - +children+ +:table_head+ and +:table_row+ elements
78
+ # - Use +children_of(:table_row)+ to get body rows; +children_of(:table_head)+
79
+ # to get the header.
80
+ # - Mutable: +html=+
81
+ #
82
+ # #### +:table_head+
83
+ # - +children+ +:table_row+ elements (the header row)
84
+ # - Mutable: +html=+
85
+ #
86
+ # #### +:table_row+
87
+ # - +text+ concatenated plain text of all cells
88
+ # - +children+ +:table_cell+ elements
89
+ # - Mutable: +html=+
90
+ #
91
+ # #### +:table_cell+
92
+ # - +text+ plain text of the cell
93
+ # - +children+ inline child nodes
94
+ # - Mutable: +html=+
95
+ #
96
+ # #### +:emphasis+
97
+ # - +text+ plain text of content
98
+ # - +children+ inline child nodes
99
+ # - Mutable: +html=+
100
+ #
101
+ # #### +:strong+
102
+ # - +text+ plain text of content
103
+ # - +children+ inline child nodes
104
+ # - Mutable: +html=+
105
+ #
106
+ # #### +:strikethrough+
107
+ # - +text+ plain text of content
108
+ # - +children+ inline child nodes
109
+ # - Mutable: +html=+
110
+ #
111
+ # #### +:link+
112
+ # - +text+ link label plain text
113
+ # - +dest+ URL (mutable via +dest=+)
114
+ # - +title+ tooltip/title attribute, or +nil+ (mutable via +title=+)
115
+ # - +children+ inline child nodes (text, image, strong, …)
116
+ # - Mutable: +dest=+, +title=+, +html=+
117
+ #
118
+ # #### +:image+
119
+ # - +text+ alt text
120
+ # - +dest+ image URL (mutable via +dest=+)
121
+ # - +title+ title attribute, or +nil+ (mutable via +title=+)
122
+ # - +children+ always empty; alt text is plain text, not parsed inline events
123
+ # - Mutable: +dest=+, +title=+, +html=+
124
+ #
125
+ # #### +:footnote_definition+
126
+ # - +text+ plain text of the footnote body
127
+ # - +children+ block child nodes
128
+ # - Mutable: +html=+
129
+ #
130
+ # ### Leaf kinds
131
+ #
132
+ # Leaves are single events with no children. Their handler fires on the
133
+ # event itself.
134
+ #
135
+ # #### +:code+ (inline code)
136
+ # - +text+ the code content, without backtick delimiters
137
+ # - +children+ always empty
138
+ # - Mutable: +html=+
139
+ #
140
+ # #### +:text+
141
+ # - +text+ the text string (after emoji resolution if enabled)
142
+ # - +children+ always empty
143
+ # - Mutable: +html=+
144
+ #
145
+ # #### +:html+ (inline raw HTML, when +suppress_raw_html: false+)
146
+ # - +text+ the raw HTML string
147
+ # - +children+ always empty
148
+ # - Mutable: +html=+
149
+ #
150
+ # #### +:rule+ (thematic break / horizontal rule)
151
+ # - +text+ always an empty string
152
+ # - +children+ always empty
153
+ # - Mutable: +html=+
154
+ #
155
+ # #### +:soft_break+
156
+ # - +text+ always an empty string
157
+ # - +children+ always empty
158
+ # - Mutable: +html=+
159
+ #
160
+ # #### +:hard_break+
161
+ # - +text+ always an empty string
162
+ # - +children+ always empty
163
+ # - Mutable: +html=+
164
+ #
165
+ # #### +:footnote_reference+
166
+ # - +text+ the footnote label
167
+ # - +children+ always empty
168
+ # - Mutable: +html=+
169
+ #
170
+ # ## Mutation precedence
171
+ #
172
+ # 1. {#delete} suppresses the element entirely (nothing emitted)
173
+ # 2. {#html=} emits a raw HTML string; skips all other rendering
174
+ # 3. {#markdown=} re-parses the string and splices the events in
175
+ # 4. Field mutations (+dest=+, +level=+, +id=+, +title=+)—modify the
176
+ # element's normal rendering
177
+ #
178
+ # When +html=+ is set, +markdown=+ and field mutations are ignored.
179
+ # When +markdown=+ is set, field mutations are ignored.
180
+ # {#delete} takes priority over everything.
181
+ #
182
+ # ## Filter interaction
183
+ #
184
+ # Enrichment filters run **before** handlers, so handlers always see:
185
+ # - Emoji shortcodes already resolved (+emoji_shortcodes: true+)
186
+ # - URLs already autolinked (+links: { autolink: true }+)
187
+ # - Heading +id+ already set (+headings: { ids: true }+)
188
+ # - Raw HTML already suppressed (+suppress_raw_html: true+—the default)
189
+ #
190
+ # Post-render filters (+syntax_highlight+, +links: { allowed_hosts: ... }+, etc.) run
191
+ # **after** handlers, so handler-set +dest=+ values are subject to allowlist
192
+ # filtering.
193
+ class Event
194
+ # The element kind.
195
+ # @return [Symbol]
196
+ attr_reader :kind
197
+
198
+ # Concatenated plain text of all descendant text nodes.
199
+ # For leaf elements this is the element's own text.
200
+ # @return [String]
201
+ attr_reader :text
202
+
203
+ # Raw source code for +:code_block+ elements. Identical to +text+.
204
+ # +nil+ for all other kinds.
205
+ # @return [String, nil]
206
+ attr_reader :source
207
+
208
+ # Language tag for +:code_block+ elements (e.g. +"ruby"+, +"javascript"+).
209
+ # +nil+ for indented code blocks and all other element kinds.
210
+ # @return [String, nil]
211
+ attr_reader :lang
212
+
213
+ # Byte offsets of this element in the source string, as an exclusive Ruby
214
+ # Range (+start...end+). Use it to slice the original source:
215
+ #
216
+ # source[event.byte_range] # → the raw markdown for this element
217
+ #
218
+ # Populated for: all container kinds (+:heading+, +:paragraph+,
219
+ # +:blockquote+, +:code_block+, +:table+, +:list+, +:link+, +:image+, …)
220
+ # and the leaf kinds +:code+ (inline code), +:rule+, +:inline_math+,
221
+ # +:display_math+.
222
+ #
223
+ # +nil+ for +:text+, +:soft_break+, +:hard_break+, and +:footnote_reference+
224
+ # (those events can be split or merged by filters).
225
+ #
226
+ # +:link+ byte ranges are also +nil+ when +links: { autolink: true }+ is
227
+ # enabled—the autolink filter inserts new link events that would shift
228
+ # the queue, so ranges for that kind are suppressed.
229
+ #
230
+ # @return [Range, nil]
231
+ attr_reader :byte_range
232
+
233
+ # Nesting depth of this element. Top-level blocks have depth 0;
234
+ # a paragraph inside a blockquote has depth 1.
235
+ # @return [Integer]
236
+ attr_reader :depth
237
+
238
+ # Kind of the immediate parent element, or +nil+ when this element
239
+ # is at the document root.
240
+ # @return [Symbol, nil]
241
+ attr_reader :parent_kind
242
+
243
+ # Ancestor kinds from immediate parent to root, nearest first.
244
+ # Empty when this element is at the document root.
245
+ # @return [Array<Symbol>]
246
+ attr_reader :ancestor_kinds
247
+
248
+ # URL for +:link+ and +:image+ elements. Setting this rewrites the +href+
249
+ # or +src+ in the rendered output. Subject to allowlist filters after handlers run.
250
+ # +nil+ for all other kinds.
251
+ # @return [String, nil]
252
+ attr_accessor :dest
253
+
254
+ # Title attribute for +:link+ and +:image+ elements (rendered as the
255
+ # +title+ tooltip). +nil+ when no title was specified or for other kinds.
256
+ # @return [String, nil]
257
+ attr_accessor :title
258
+
259
+ # Heading level (1–6) for +:heading+ elements. Setting this changes the
260
+ # rendered tag (e.g. +<h2>+ → +<h3>+). +nil+ for all other kinds.
261
+ # @return [Integer, nil]
262
+ attr_accessor :level
263
+
264
+ # HTML +id+ attribute for +:heading+ elements. Set automatically when
265
+ # +headings: { ids: true }+ is enabled; +nil+ otherwise. Setting this overrides
266
+ # the generated slug. +nil+ for all other kinds.
267
+ # @return [String, nil]
268
+ attr_accessor :id
269
+
270
+ # Replace this element's entire output with a raw HTML string.
271
+ # When set, all other mutations and the element's default rendering
272
+ # are ignored. The string is emitted verbatim—no escaping applied.
273
+ # Takes priority over {#markdown=}.
274
+ # @return [String, nil]
275
+ attr_accessor :html
276
+
277
+ # Replace this element's output by re-rendering a markdown string.
278
+ # The replacement is parsed with the same options as the main document
279
+ # (emoji expansion, heading IDs, raw HTML suppression, etc.) and is
280
+ # subject to post-render filters (+syntax_highlight+, allowlists, etc.).
281
+ # Handlers do NOT fire on elements within the replacement.
282
+ # {#html=} takes priority when both are set; {#delete} takes priority
283
+ # over everything.
284
+ # Has no effect when called inside a {Inkmark#walk} block (walk produces
285
+ # no output).
286
+ # @return [String, nil]
287
+ attr_accessor :markdown
288
+
289
+ def initialize(data) # :nodoc:
290
+ @kind = data[:kind].to_sym
291
+ @text = data[:text] || ""
292
+ @source = @text
293
+ @lang = data[:lang]
294
+ @dest = data[:dest]
295
+ @title = data[:title]
296
+ @level = data[:level]
297
+ @id = data[:id]
298
+ @byte_range = data[:byte_range]
299
+ @depth = data[:depth] || 0
300
+ @parent_kind = data[:parent_kind]&.to_sym
301
+ @ancestor_kinds = (data[:ancestor_kinds] || []).map(&:to_sym)
302
+ @children_data = data[:children] || []
303
+ @html = nil
304
+ @markdown = nil
305
+ @deleted = false
306
+ end
307
+
308
+ # Direct child elements of this node (lazy, cached).
309
+ # For leaf elements (text, code, rule, soft_break, hard_break,
310
+ # footnote_reference, html) this is always an empty array.
311
+ # @return [Array<Event>]
312
+ def children
313
+ @children ||= @children_data.map { |d| Event.new(d) }
314
+ end
315
+
316
+ # Direct children filtered by kind.
317
+ #
318
+ # @example Get body rows from a table
319
+ # md.on(:table) { |t| rows = t.children_of(:table_row) }
320
+ # @example Get cells from a row
321
+ # row.children_of(:table_cell).map(&:text)
322
+ #
323
+ # @param kind [Symbol] element kind to select (e.g. +:table_row+)
324
+ # @return [Array<Event>]
325
+ def children_of(kind)
326
+ children.select { |c| c.kind == kind }
327
+ end
328
+
329
+ # Suppress this element—nothing is emitted to the HTML output.
330
+ # Takes precedence over {#html=} and all other mutations.
331
+ # @return [void]
332
+ def delete
333
+ @deleted = true
334
+ end
335
+
336
+ # Returns +true+ if {#delete} was called on this element.
337
+ # @return [Boolean]
338
+ def deleted?
339
+ @deleted
340
+ end
341
+ end
342
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ ruby_version = RUBY_VERSION[/\d+\.\d+/]
5
+ require_relative "#{ruby_version}/inkmark"
6
+ rescue LoadError
7
+ require_relative "inkmark"
8
+ end