Module: Coradoc::AsciiDoc::Parser::List

Defined in:
lib/coradoc/asciidoc/parser/list.rb

Instance Method Summary collapse

Instance Method Details

#asterisk_marker(nesting_level) ⇒ Object

AsciiDoc standard bullet: ‘*`, `**`, `***`, … matching the nesting level. Excludes table delimiters (`|===`) and deeper asterisk runs that belong to a sibling level.



84
85
86
87
88
# File 'lib/coradoc/asciidoc/parser/list.rb', line 84

def asterisk_marker(nesting_level)
  str('*' * nesting_level) >>
    str('*').absent? >>
    str('===').absent?
end

#dash_marker(nesting_level) ⇒ Object

Markdown-style dash bullet: ‘-`. Accepted only at the top level because Markdown nests via indentation rather than multi-char markers — deeper levels stay on the AsciiDoc `*` form. Guards exclude em-dashes (`–`), delimited-block fences (`—-`), and negative-number runs (`-1`, `-42`) which are not list markers in any common dialect.



96
97
98
99
100
101
102
# File 'lib/coradoc/asciidoc/parser/list.rb', line 96

def dash_marker(nesting_level)
  return match('').absent? unless nesting_level == 1

  str('-') >>
    str('-').absent? >>
    match('[0-9]').absent?
end

#definition_list(_delimiter = nil) ⇒ Object



32
33
34
35
36
# File 'lib/coradoc/asciidoc/parser/list.rb', line 32

def definition_list(_delimiter = nil)
  (attribute_list >> newline).maybe >>
    dlist_item.repeat(1).as(:definition_list) >>
    dlist_item.absent?
end

#dlist_definitionObject



151
152
153
154
# File 'lib/coradoc/asciidoc/parser/list.rb', line 151

def dlist_definition
  text
    .as(:definition) >> line_ending >> empty_line.repeat(0)
end

#dlist_delimiterObject



134
135
136
137
138
139
140
141
142
# File 'lib/coradoc/asciidoc/parser/list.rb', line 134

def dlist_delimiter
  (
    (str(':::::') >> match(':').absent?) |
    (str('::::') >> match(':').absent?) |
    (str(':::') >> match(':').absent?) |
    (str('::') >> match(':').absent?) |
    str(';;')
  ).as(:delimiter)
end

#dlist_item(_delimiter = nil) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/coradoc/asciidoc/parser/list.rb', line 156

def dlist_item(_delimiter = nil)
  # Both forms below produce the same AST shape:
  #   {terms: [<dlist_term>, ...], definition: <text>}
  # so the transformer's definition_list_item rule matches uniformly.
  #
  # Multi-line form: one or more term-lines (`term::` + newline +
  # optional blank lines), then the definition on its own line(s).
  # Single-line form: one term + inline space + definition.
  term_line = dlist_term >> line_ending >> empty_line.repeat(0)

  ((term_line.repeat(1).as(:terms) >> dlist_definition) |
   (dlist_term.repeat(1, 1).as(:terms) >> space >>
     dlist_definition)).as(:definition_list_item)
end

#dlist_term(_delimiter = nil) ⇒ Object



144
145
146
147
148
149
# File 'lib/coradoc/asciidoc/parser/list.rb', line 144

def dlist_term(_delimiter = nil)
  term_chars =
    (dlist_delimiter.absent? >> match("[^\n]")).repeat(1)
                                               .as(:text)
  (element_id_inline.maybe >> term_chars).as(:dlist_term) >> dlist_delimiter
end

#list(nesting_level = 1) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/coradoc/asciidoc/parser/list.rb', line 8

def list(nesting_level = 1)
  (
  unordered_list(nesting_level) |
     ordered_list(nesting_level) |
     definition_list
).as(:list)
end

#list_continuationObject



16
17
18
# File 'lib/coradoc/asciidoc/parser/list.rb', line 16

def list_continuation
  line_start? >> str("+\n")
end

#list_item_continuation_linesObject

Continuation lines of a list item’s first paragraph. AsciiDoc joins consecutive non-blank lines into one paragraph within the item, but the lines must not start a sibling construct (another list marker, block delimiter, attribute list, section, element id, table boundary, list continuation, or list prefix). ‘line_not_text?` (from Paragraph) is that exact lookahead.



130
131
132
# File 'lib/coradoc/asciidoc/parser/list.rb', line 130

def list_item_continuation_lines
  (line_not_text? >> text_line(true, unguarded: true)).repeat(0)
end

#list_marker(nesting_level = 1) ⇒ Object



38
39
40
# File 'lib/coradoc/asciidoc/parser/list.rb', line 38

def list_marker(nesting_level = 1)
  olist_marker(nesting_level) | ulist_marker(nesting_level)
end

#olist_item(nesting_level = 1) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/coradoc/asciidoc/parser/list.rb', line 53

def olist_item(nesting_level = 1)
  item = olist_marker(nesting_level).as(:marker) >>
         match("\n").absent? >> space >>
         (text_line(true, unguarded: true) >>
          list_item_continuation_lines).as(:lines)

  att = (list_continuation.present? >>
          list_continuation >>
          (admonition_line | paragraph | block)
        ).repeat(0).as(:attached)
  item >>= att.maybe

  if nesting_level <= 4
    item >>= (list_marker(nesting_level + 1).present? >>
           list(nesting_level + 1)).repeat(0).as(:nested)
  end
  olist_marker(nesting_level).present? >> item.as(:list_item)
end

#olist_marker(nesting_level = 1) ⇒ Object



42
43
44
45
46
47
48
49
50
51
# File 'lib/coradoc/asciidoc/parser/list.rb', line 42

def olist_marker(nesting_level = 1)
  # Don't match table cell format specs like ".2+^.^|"
  line_start? >>
    (nesting_level > 1 ? literal_space.maybe : str('')) >>
    str('.' * nesting_level) >>
    str('.').absent? >>
    (
      (match['0-9.<>^'] | str('+')).repeat(0, 3) >> str('|')
    ).absent?
end

#ordered_list(nesting_level = 1) ⇒ Object



20
21
22
23
24
# File 'lib/coradoc/asciidoc/parser/list.rb', line 20

def ordered_list(nesting_level = 1)
  attrs = (attribute_list >> newline).maybe
  r = olist_item(nesting_level)
  attrs >> olist_item(nesting_level).present? >> r.repeat(1).as(:ordered)
end

#ulist_item(nesting_level = 1) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/coradoc/asciidoc/parser/list.rb', line 104

def ulist_item(nesting_level = 1)
  item = ulist_marker(nesting_level).as(:marker) >>
         str(' [[[').absent? >>
         match("\n").absent? >> space >>
         (text_line(true, unguarded: true) >>
          list_item_continuation_lines).as(:lines)

  att = (list_continuation.present? >>
          list_continuation >>
          (admonition_line | paragraph | block)
        ).repeat(0).as(:attached)
  item >>= att.maybe

  if nesting_level <= 4
    item >>= (list_marker(nesting_level + 1).present? >>
           list(nesting_level + 1)).repeat(0).as(:nested)
  end
  ulist_marker(nesting_level).present? >> item.as(:list_item)
end

#ulist_marker(nesting_level = 1) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/coradoc/asciidoc/parser/list.rb', line 72

def ulist_marker(nesting_level = 1)
  line_start? >>
    (nesting_level > 1 ? literal_space.maybe : str('')) >>
    (
      asterisk_marker(nesting_level) |
      dash_marker(nesting_level)
    )
end

#unordered_list(nesting_level = 1) ⇒ Object



26
27
28
29
30
# File 'lib/coradoc/asciidoc/parser/list.rb', line 26

def unordered_list(nesting_level = 1)
  attrs = (attribute_list >> newline).maybe
  r = ulist_item(nesting_level)
  attrs >> r.repeat(1).as(:unordered)
end