Skip to content

Commit

Permalink
add support for attribute value continuation across multiple lines
Browse files Browse the repository at this point in the history
  • Loading branch information
mojavelinux committed Jul 22, 2023
1 parent 0e3e105 commit 6820069
Show file tree
Hide file tree
Showing 34 changed files with 279 additions and 1 deletion.
43 changes: 42 additions & 1 deletion grammar/asciidoc-block.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,51 @@ attribute_entry = ':' negatedPrefix:'!'? name:attribute_name negatedSuffix:'!'?
return [name, negatedPrefix || negatedSuffix ? null : value || '', range()]
}
attribute_entry_head = ':' '!'? attribute_name '!'? ':' (space / eol)
// TODO permit non-ASCII letters in attribute name
attribute_name = $([a-zA-Z0-9_] [a-zA-Z0-9_-]*)
attribute_value = space @$(!lf .)+
attribute_value = space lines:($(!lf .)*)|1.., &{ let idx = offset(), count = 0; while (input[--idx] === '\\') count++; return !!(count % 2) } lf (&space / !(attribute_entry_head / eol / any_block_delimiter_line / block_attribute_line))|
{
const lastLineIdx = lines.length - 1
if (!lastLineIdx) {
const line0 = lines[0]
if (!line0) return line0
if (line0[line0.length - 1] !== '\\') return line0[0] === ' ' ? line0.trimStart() : line0
}
let hardWrapNext = false
return lines.reduce((buf, line, lineIdx) => {
const hardWrap = hardWrapNext
if (hardWrap) buf = buf.slice(0, -2) + '\n'
if (lineIdx < lastLineIdx) {
if (!(line = line.slice(0, -1)) && !(hardWrapNext = false)) return buf
if (line[line.length - 1] === '\\') line = line.replace(/\\+$/, (m) => m.slice(0, m.length / 2))
} else if (line[line.length - 1] === '\\') {
line = line.replace(/\\+$/, (m) => m.slice(0, m.length % 2 ? (m.length - 1) / 2 + 1 : m.length / 2))
}
hardWrapNext = line.length > 1 && line[line.length - 2] === ' ' && line[line.length - 1] === ' '
return buf + (hardWrap || line[0] !== ' ' ? line : line.trimStart())
}, '')
}
//attribute_value = space lines:($(!('\\' / lf) . / '\\' !lf .)*)|1.., '\\' lf (&space / !(attribute_entry_head / eol / any_block_delimiter_line / block_attribute_line))| trailer:('\\' / '')
//{
// if (lines.length === 1) {
// const line0 = lines[0]
// if (!line0) return trailer
// if (line0[line0.length - 1] !== '\\') return (line0[0] === ' ' ? line0.trimStart() : line0) + trailer
// }
// let hardWrapNext = false
// return lines.reduce((buf, line) => {
// const hardWrap = hardWrapNext
// if (hardWrap) buf = buf.slice(0, -2) + '\n'
// if (!line && !(hardWrapNext = false)) return buf
// if (line[line.length - 1] === '\\') line = line.replace(/\\+$/, (m) => m.slice(0, m.length / 2))
// hardWrapNext = line.length > 1 && line[line.length - 2] === ' ' && line[line.length - 1] === ' '
// return buf + (hardWrap || line[0] !== ' ' ? line : line.trimStart())
// }, '') + trailer
//}
body = @section_block* remainder
Expand Down
1 change: 1 addition & 0 deletions test/tests/block/attribute/backslash-only-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:bs: \
11 changes: 11 additions & 0 deletions test/tests/block/attribute/backslash-only-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"bs": { "value": "\\", "location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 6 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 6 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 6 }]
}
5 changes: 5 additions & 0 deletions test/tests/block/attribute/empty-lines-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
:lines: foo \
\
bar \
\
baz
11 changes: 11 additions & 0 deletions test/tests/block/attribute/empty-lines-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"lines": { "value": "foo\nbar\nbaz", "location": [{ "line": 1, "col": 1 }, { "line": 5, "col": 3 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 5, "col": 3 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 5, "col": 3 }]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:drive: C:\\
11 changes: 11 additions & 0 deletions test/tests/block/attribute/escaped-value-continuation-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"drive": { "value": "C:\\", "location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 12 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 12 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 12 }]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:dbs: \\\\
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"dbs": { "value": "\\\\", "location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 10 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 10 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 10 }]
}
2 changes: 2 additions & 0 deletions test/tests/block/attribute/hard-line-break-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:bars: Roses are red, + \
Violets are blue.
11 changes: 11 additions & 0 deletions test/tests/block/attribute/hard-line-break-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"bars": { "value": "Roses are red, +\nViolets are blue.", "location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 17 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 17 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 17 }]
}
4 changes: 4 additions & 0 deletions test/tests/block/attribute/hard-wrap-indented-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:filetree: article.adoc \
assets/ \
example.rb \
image.png
11 changes: 11 additions & 0 deletions test/tests/block/attribute/hard-wrap-indented-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"filetree": { "value": "article.adoc\nassets/\n example.rb\n image.png", "location": [{ "line": 1, "col": 1 }, { "line": 4, "col": 11 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 4, "col": 11 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 4, "col": 11 }]
}
2 changes: 2 additions & 0 deletions test/tests/block/attribute/hard-wrap-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:output: 499 passing \
1 pending
11 changes: 11 additions & 0 deletions test/tests/block/attribute/hard-wrap-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"output": { "value": "499 passing\n1 pending", "location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 9 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 9 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 9 }]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:bs: \
:org: ACME
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"bs": { "value": "\\", "location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 6 }] },
"org": { "value": "ACME", "location": [{ "line": 2, "col": 1 }, { "line": 2, "col": 10 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 10 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 10 }]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"options": {
"parseInlines": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:appsdir: C:\Program Files\

Look for the installed application in {appsdir}.
26 changes: 26 additions & 0 deletions test/tests/block/attribute/interrupted-by-empty-line-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"appsdir": { "value": "C:\\Program Files\\", "location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 27 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 27 }]
},
"blocks": [
{
"name": "paragraph",
"type": "block",
"inlines": [
{
"name": "text",
"type": "string",
"value": "Look for the installed application in C:\\Program Files\\.",
"location": [{ "line": 3, "col": 1 }, { "line": 3, "col": 48 }]
}
],
"location": [{ "line": 3, "col": 1 }, { "line": 3, "col": 48 }]
}
],
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 48 }]
}
3 changes: 3 additions & 0 deletions test/tests/block/attribute/leading-indentation-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:icons: font
:toc: preamble
:toclevels: 1
13 changes: 13 additions & 0 deletions test/tests/block/attribute/leading-indentation-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"icons": { "value": "font", "location": [{ "line": 1, "col": 1 }, { "line": 1, "col": 16 }] },
"toc": { "value": "preamble", "location": [{ "line": 2, "col": 1 }, { "line": 2, "col": 20 }] },
"toclevels": { "value": "1", "location": [{ "line": 3, "col": 1 }, { "line": 3, "col": 13 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 13 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 13 }]
}
3 changes: 3 additions & 0 deletions test/tests/block/attribute/soft-wrap-after-space-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:lml: lightweight \
markup \
language
11 changes: 11 additions & 0 deletions test/tests/block/attribute/soft-wrap-after-space-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"lml": { "value": "lightweight markup language", "location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 8 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 8 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 8 }]
}
2 changes: 2 additions & 0 deletions test/tests/block/attribute/soft-wrap-indented-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:description: This is the description. \
It summaries the contents of this article.
11 changes: 11 additions & 0 deletions test/tests/block/attribute/soft-wrap-indented-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"description": { "value": "This is the description. It summaries the contents of this article.", "location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 56 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 56 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 56 }]
}
2 changes: 2 additions & 0 deletions test/tests/block/attribute/soft-wrap-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:ad: Ascii\
Doc
11 changes: 11 additions & 0 deletions test/tests/block/attribute/soft-wrap-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"ad": { "value": "AsciiDoc", "location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 3 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 3 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 3 }]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:dir: C:\\\
Program Files\\\
Application
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"dir": { "value": "C:\\Program Files\\Application", "location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 11 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 11 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 3, "col": 11 }]
}
2 changes: 2 additions & 0 deletions test/tests/block/attribute/start-with-hard-wrap-input.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:source: \
preceded by newline
11 changes: 11 additions & 0 deletions test/tests/block/attribute/start-with-hard-wrap-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"source": { "value": "\npreceded by newline", "location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 19 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 19 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 19 }]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:description: \
Describe me.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "document",
"type": "block",
"header": {
"attributes": {
"description": { "value": "Describe me.", "location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 12 }] }
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 12 }]
},
"location": [{ "line": 1, "col": 1 }, { "line": 2, "col": 12 }]
}

0 comments on commit 6820069

Please sign in to comment.