Module: RedQuilt::ReferenceDefinition
- Defined in:
- lib/red_quilt/reference_definition.rb
Overview
CommonMark link reference definitions ([label]: dest "title").
Module-level functions are stateless helpers reused by BlockParser
(fenced-code info string also calls unescape_text) and
Inline::Builder (reference lookup uses normalize_label).
ReferenceDefinition::Parser carries the per-call state (@lines,
@index) and walks the lines for one definition attempt.
Defined Under Namespace
Classes: Parser
Constant Summary collapse
- REF_DEF_RE =
A reference label may contain
\[/\](backslash-escaped), but never an unescaped[or]. Newlines inside the label are allowed and collapsed by normalize_label. /\A {0,3}\[((?:[^\\\[\]]|\\.)+)\]:(.*)\z/m- TITLE_CLOSERS =
{ '"' => '"', "'" => "'", "(" => ")" }.freeze
- LABEL_MAX_LENGTH =
CommonMark spec: "A link label can have at most 999 characters inside the square brackets." Applies to both reference definitions and reference link uses.
999- LINK_TAIL_WS_RE =
CommonMark 6.3 link-tail whitespace: space/tab only (line endings are handled separately by the caller). Intentionally narrower than Ruby's
strip/lstrip, which also match FF (U+000C) and VT (U+000B). Mirrors Inline::Builder#link_tail_whitespace_byte?. /[ \t]/
Class Method Summary collapse
-
.consume(lines, index) ⇒ Object
Attempts to consume a reference definition starting at
lines[index]. -
.label_too_long?(text) ⇒ Boolean
True when
textexceeds the spec's link-label length limit. -
.link_blank?(text) ⇒ Boolean
True when the string is empty or contains only spaces and tabs.
-
.link_lstrip(text) ⇒ Object
Narrow lstrip: only space and tab.
-
.normalize_label(label) ⇒ Object
Spec-required normalization: full Unicode case fold + whitespace collapse.
-
.unescape_text(text) ⇒ Object
Unescape Markdown text: backslash-escapes for ASCII punctuation and HTML entity references.
Class Method Details
.consume(lines, index) ⇒ Object
Attempts to consume a reference definition starting at lines[index].
Returns { reference: { label:, destination:, title: }, consumed: N, source_span: SourceSpan } or nil. The reference hash is what
BlockParser should store in its @references table; the source_span
covers the byte range of the consumed lines (useful for
duplicate-definition diagnostics).
55 56 57 |
# File 'lib/red_quilt/reference_definition.rb', line 55 def consume(lines, index) Parser.new(lines, index).consume end |
.label_too_long?(text) ⇒ Boolean
True when text exceeds the spec's link-label length limit.
33 34 35 |
# File 'lib/red_quilt/reference_definition.rb', line 33 def label_too_long?(text) text.to_s.length > LABEL_MAX_LENGTH end |
.link_blank?(text) ⇒ Boolean
True when the string is empty or contains only spaces and tabs.
45 46 47 |
# File 'lib/red_quilt/reference_definition.rb', line 45 def link_blank?(text) text.match?(/\A[ \t]*\z/) end |
.link_lstrip(text) ⇒ Object
Narrow lstrip: only space and tab. Used for the spec-defined whitespace around link destinations and titles in reference definitions.
40 41 42 |
# File 'lib/red_quilt/reference_definition.rb', line 40 def link_lstrip(text) text.sub(/\A[ \t]+/, "") end |
.normalize_label(label) ⇒ Object
Spec-required normalization: full Unicode case fold + whitespace collapse. Inline::Builder uses the same rule when looking up the destination of a reference link.
70 71 72 73 74 75 76 |
# File 'lib/red_quilt/reference_definition.rb', line 70 def normalize_label(label) # CommonMark spec: full Unicode case fold (`downcase(:fold)`), not # the default per-codepoint lowercase. This makes labels like `ẞ` # (U+1E9E) match a definition of `SS` because the case-fold of `ẞ` # is `ss`. label.to_s.strip.downcase(:fold).gsub(/[ \t\r\n]+/, " ") end |
.unescape_text(text) ⇒ Object
Unescape Markdown text: backslash-escapes for ASCII punctuation and HTML entity references. Also used by BlockParser#fenced_code_start for the info string, which shares the same unescape semantics.
62 63 64 65 |
# File 'lib/red_quilt/reference_definition.rb', line 62 def unescape_text(text) out = text.gsub(/\\([!-\/:-@\[-`{-~])/, "\\1") out.gsub(Inline::ENTITY_RE) { |m| Inline.decode_entity(m) } end |