Module: RedQuilt::Indentation
- Defined in:
- lib/red_quilt/indentation.rb
Overview
Stateless CommonMark indentation / column arithmetic, shared by the block parser and its collaborator parsers (List, Blockquote, Footnote). Tabs expand to the next multiple of 4 columns.
Class Method Summary collapse
-
.leading_columns(text) ⇒ Object
Leading-whitespace width of
textin columns (tabs expanded to the next tab stop of 4). -
.leading_ws_bytes(text) ⇒ Object
Bytes of literal leading 0x20 / 0x09 in
text. -
.strip_columns(text, n) ⇒ Object
Strips up to
ncolumns of leading whitespace fromtextand returns the rest. -
.strip_leading_spaces(text, max) ⇒ Object
Strips up to
maxleading 0x20 (space) bytes fromtext, returning the rest. -
.strip_leading_whitespace(text) ⇒ Object
Strips all leading 0x20 / 0x09 bytes from
text(spaces and tabs, no column cap).
Class Method Details
.leading_columns(text) ⇒ Object
Leading-whitespace width of text in columns (tabs expanded to the
next tab stop of 4).
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/red_quilt/indentation.rb', line 12 def leading_columns(text) col = 0 i = 0 bytes = text.bytesize while i < bytes b = text.getbyte(i) if b == 0x20 col += 1 elsif b == 0x09 col = ((col / 4) + 1) * 4 else break end i += 1 end col end |
.leading_ws_bytes(text) ⇒ Object
Bytes of literal leading 0x20 / 0x09 in text.
96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/red_quilt/indentation.rb', line 96 def leading_ws_bytes(text) i = 0 bytes = text.bytesize while i < bytes b = text.getbyte(i) break unless b == 0x20 || b == 0x09 i += 1 end i end |
.strip_columns(text, n) ⇒ Object
Strips up to n columns of leading whitespace from text and
returns the rest. Leading whitespace is normalised to spaces in the
returned string so subsequent strips compose correctly regardless of
where they land relative to the original tab stops.
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 |
# File 'lib/red_quilt/indentation.rb', line 34 def strip_columns(text, n) return text if n <= 0 col = 0 i = 0 bytes = text.bytesize while i < bytes b = text.getbyte(i) if b == 0x20 col += 1 elsif b == 0x09 col = ((col / 4) + 1) * 4 else break end i += 1 end # text[0...i] is all leading whitespace representing `col` cols. if n >= col i.zero? ? text : text.byteslice(i..) else # Keep the unstripped portion as a run of spaces. (" " * (col - n)) + text.byteslice(i..) end end |
.strip_leading_spaces(text, max) ⇒ Object
Strips up to max leading 0x20 (space) bytes from text, returning
the rest. Unlike #strip_columns this is a plain byte strip (tabs are
not expanded); used where the spec counts literal spaces, e.g. a
fenced code block stripping its own opening indent. No-alloc return
when text already starts at a non-space byte.
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/red_quilt/indentation.rb', line 65 def strip_leading_spaces(text, max) return text if max <= 0 bytes = text.bytesize i = 0 while i < max && i < bytes && text.getbyte(i) == 0x20 i += 1 end return text if i.zero? text.byteslice(i..) end |
.strip_leading_whitespace(text) ⇒ Object
Strips all leading 0x20 / 0x09 bytes from text (spaces and tabs,
no column cap). Same no-alloc return as #strip_leading_spaces when
text already starts at a non-whitespace byte.
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/red_quilt/indentation.rb', line 81 def strip_leading_whitespace(text) bytes = text.bytesize i = 0 while i < bytes b = text.getbyte(i) break unless b == 0x20 || b == 0x09 i += 1 end return text if i.zero? text.byteslice(i..) end |