26 val line_source: line -> Antiquote.text_antiquote list |
26 val line_source: line -> Antiquote.text_antiquote list |
27 val line_is_item: line -> bool |
27 val line_is_item: line -> bool |
28 val line_content: line -> Antiquote.text_antiquote list |
28 val line_content: line -> Antiquote.text_antiquote list |
29 val make_line: Antiquote.text_antiquote list -> line |
29 val make_line: Antiquote.text_antiquote list -> line |
30 val empty_line: line |
30 val empty_line: line |
31 datatype block = Paragraph of line list | List of {indent: int, kind: kind, body: block list} |
31 datatype block = Par of line list | List of {indent: int, kind: kind, body: block list} |
32 val read_lines: line list -> block list |
32 val read_lines: line list -> block list |
33 val read_antiquotes: Antiquote.text_antiquote list -> block list |
33 val read_antiquotes: Antiquote.text_antiquote list -> block list |
34 val read_source: Input.source -> block list |
34 val read_source: Input.source -> block list |
35 val text_reports: Antiquote.text_antiquote list -> Position.report list |
35 val text_reports: Antiquote.text_antiquote list -> Position.report list |
36 val reports: block list -> Position.report list |
36 val reports: block list -> Position.report list |
122 end; |
122 end; |
123 |
123 |
124 |
124 |
125 (* document blocks *) |
125 (* document blocks *) |
126 |
126 |
127 datatype block = |
127 datatype block = Par of line list | List of {indent: int, kind: kind, body: block list}; |
128 Paragraph of line list | List of {indent: int, kind: kind, body: block list}; |
128 |
129 |
129 fun block_lines (Par lines) = lines |
130 fun block_lines (Paragraph lines) = lines |
|
131 | block_lines (List {body, ...}) = maps block_lines body; |
130 | block_lines (List {body, ...}) = maps block_lines body; |
132 |
131 |
133 fun block_range (Paragraph lines) = Antiquote.range (maps line_content lines) |
132 fun block_range (Par lines) = Antiquote.range (maps line_content lines) |
134 | block_range (List {body, ...}) = Antiquote.range (maps line_source (maps block_lines body)); |
133 | block_range (List {body, ...}) = Antiquote.range (maps line_source (maps block_lines body)); |
135 |
134 |
136 fun block_indent (List {indent, ...}) = indent |
135 fun block_indent (List {indent, ...}) = indent |
137 | block_indent (Paragraph (Line {indent, ...} :: _)) = indent |
136 | block_indent (Par (Line {indent, ...} :: _)) = indent |
138 | block_indent _ = 0; |
137 | block_indent _ = 0; |
139 |
138 |
140 fun block_list indent0 kind0 (List {indent, kind, body}) = |
139 fun block_list indent0 kind0 (List {indent, kind, body}) = |
141 if indent0 = indent andalso kind0 = kind then SOME body else NONE |
140 if indent0 = indent andalso kind0 = kind then SOME body else NONE |
142 | block_list _ _ _ = NONE; |
141 | block_list _ _ _ = NONE; |
165 |
164 |
166 val parse_paragraph = |
165 val parse_paragraph = |
167 Scan.one (fn line => line <> eof_line) -- Scan.many plain_line >> (fn (line, lines) => |
166 Scan.one (fn line => line <> eof_line) -- Scan.many plain_line >> (fn (line, lines) => |
168 let |
167 let |
169 val Line {indent, item, ...} = line; |
168 val Line {indent, item, ...} = line; |
170 val block = Paragraph (line :: lines); |
169 val block = Par (line :: lines); |
171 in (indent, item, [block]) end); |
170 in (indent, item, [block]) end); |
172 |
171 |
173 val parse_document = |
172 val parse_document = |
174 parse_paragraph ::: Scan.repeat (Scan.option (Scan.one line_is_empty) |-- parse_paragraph) |
173 parse_paragraph ::: Scan.repeat (Scan.option (Scan.one line_is_empty) |-- parse_paragraph) |
175 >> (fn pars => fold_rev build pars []); |
174 >> (fn pars => fold_rev build pars []); |
197 fun line_reports depth (Line {item_pos, content, ...}) = |
196 fun line_reports depth (Line {item_pos, content, ...}) = |
198 cons (item_pos, Markup.markdown_item depth) #> append (text_reports content); |
197 cons (item_pos, Markup.markdown_item depth) #> append (text_reports content); |
199 |
198 |
200 fun block_reports depth block = |
199 fun block_reports depth block = |
201 (case block of |
200 (case block of |
202 Paragraph lines => |
201 Par lines => |
203 cons (#1 (block_range block), Markup.markdown_paragraph) #> |
202 cons (#1 (block_range block), Markup.markdown_paragraph) #> |
204 fold (line_reports depth) lines |
203 fold (line_reports depth) lines |
205 | List {kind, body, ...} => |
204 | List {kind, body, ...} => |
206 cons (#1 (block_range block), Markup.markdown_list (print_kind kind)) #> |
205 cons (#1 (block_range block), Markup.markdown_list (print_kind kind)) #> |
207 fold (block_reports (depth + 1)) body); |
206 fold (block_reports (depth + 1)) body); |