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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE.txt +21 -0
- data/NOTICE +16 -0
- data/README.md +1166 -0
- data/lib/inkmark/3.3/inkmark.bundle +0 -0
- data/lib/inkmark/3.4/inkmark.bundle +0 -0
- data/lib/inkmark/4.0/inkmark.bundle +0 -0
- data/lib/inkmark/event.rb +342 -0
- data/lib/inkmark/native.rb +8 -0
- data/lib/inkmark/options.rb +698 -0
- data/lib/inkmark/toc.rb +40 -0
- data/lib/inkmark/version.rb +6 -0
- data/lib/inkmark.rb +711 -0
- data/sig/inkmark.rbs +219 -0
- metadata +178 -0
|
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
|