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`.
-
.label_too_long?(text) ⇒ Boolean
True when ‘text` exceeds 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`. 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 |