Module: RedQuilt::Blockquote
- Defined in:
- lib/red_quilt/blockquote.rb
Overview
CommonMark spec 5.1 blockquotes.
Module-level functions are stateless helpers used by BlockParser’s predicate dispatch. ‘Blockquote::Parser` is a cached collaborator created once in BlockParser#initialize and reused for every blockquote (including nested ones) — per-call state lives in method locals so reentrant `#parse` calls are safe.
Defined Under Namespace
Classes: Parser
Constant Summary collapse
- BLOCKQUOTE_PREFIX_RE =
/\A {0,3}>/
Class Method Summary collapse
- .match?(text) ⇒ Boolean
-
.strip_prefix(line) ⇒ Object
Strip the leading ‘>` (and at most one column of whitespace after it) from a blockquote line.
Class Method Details
.match?(text) ⇒ Boolean
16 17 18 |
# File 'lib/red_quilt/blockquote.rb', line 16 def match?(text) text.match?(BLOCKQUOTE_PREFIX_RE) end |
.strip_prefix(line) ⇒ Object
Strip the leading ‘>` (and at most one column of whitespace after it) from a blockquote line. Returns a new Line whose content is the inner text. If the line has no `>` prefix, the original line is returned unchanged (wrapped in a fresh Line so the caller treats it uniformly).
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/red_quilt/blockquote.rb', line 25 def strip_prefix(line) content = line.content bytes = content.bytesize i = 0 abs_col = 0 # Up to 3 spaces of indent before `>`. while i < 3 && i < bytes && content.getbyte(i) == 0x20 i += 1 abs_col += 1 end unless i < bytes && content.getbyte(i) == 0x3E return Line.new(content, line.start_byte, line.end_byte, !content.match?(/\S/)) end i += 1 abs_col += 1 # consume `>` # Count column width of leading whitespace after `>` using # absolute-column tracking so a tab right after `>` (at col 1) is # correctly billed as only 3 columns of indent, not 4. ws_start_col = abs_col j = i while j < bytes b = content.getbyte(j) if b == 0x20 abs_col += 1 elsif b == 0x09 abs_col = ((abs_col / 4) + 1) * 4 else break end j += 1 end ws_cols = abs_col - ws_start_col if ws_cols >= 1 tail = (" " * (ws_cols - 1)) + content.byteslice(j..) offset = j else tail = content.byteslice(i..) offset = i end Line.new(tail, line.start_byte + offset, line.end_byte, !tail.match?(/\S/)) end |