diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2023-04-22 23:13:27 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-22 23:13:27 -0600 |
| commit | 0ef6afea4ea85faa3e5591717683bbac04b3d8b2 (patch) | |
| tree | 65b2a23ed169ec7c777c5e593674bb1268dc2849 | |
| parent | 4a70aa35b6942136e5238bd3d568b7ae9927b716 (diff) | |
resolves #4268 implicitly attach nested list that starts with block attribute lines to dlist entry (PR #4439)
| -rw-r--r-- | CHANGELOG.adoc | 1 | ||||
| -rw-r--r-- | lib/asciidoctor/parser.rb | 23 | ||||
| -rw-r--r-- | test/lists_test.rb | 83 |
3 files changed, 103 insertions, 4 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 46c4e01c..6a5dfd91 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -74,6 +74,7 @@ Bug Fixes:: * Don't allow target of include directive to start with a space (to distinguish it from a dlist item) or to end with a space * Manify alt text of block image in manpage output (#4401) * Adjust font size of term in horizontal dlist to match font size of term in regular dlist + * Implicitly attach nested list that starts with block attribute lines to dlist entry (#4268) == 2.0.18 (2022-10-15) - @mojavelinux diff --git a/lib/asciidoctor/parser.rb b/lib/asciidoctor/parser.rb index fe78b229..bb7f29fe 100644 --- a/lib/asciidoctor/parser.rb +++ b/lib/asciidoctor/parser.rb @@ -1443,11 +1443,26 @@ class Parser # we're being more strict here about the terminator, but I think that's a good thing buffer.concat reader.read_lines_until terminator: match.terminator, read_last_line: true, context: nil continuation = :inactive - # technically BlockAttributeLineRx only breaks if ensuing line is not a list item - # which really means BlockAttributeLineRx only breaks if it's acting as a block delimiter - # FIXME to be AsciiDoc compliant, we shouldn't break if style in attribute line is "literal" (i.e., [literal]) + # BlockAttributeLineRx only breaks dlist if ensuing line is not a list item elsif dlist && continuation != :active && (BlockAttributeLineRx.match? this_line) - break + block_attribute_lines = [this_line] + while (next_line = reader.peek_line) + if is_delimited_block? next_line + interrupt = true + elsif next_line.empty? || ((next_line.start_with? '[') && (BlockAttributeLineRx.match? next_line)) + block_attribute_lines << reader.read_line + next + elsif (AnyListRx.match? next_line) && !(is_sibling_list_item? next_line, list_type, sibling_trait) + buffer.concat block_attribute_lines + else # rubocop:disable Lint/DuplicateBranch + interrupt = true + end + break + end + if interrupt + reader.unshift_lines block_attribute_lines + break + end elsif continuation == :active && !this_line.empty? # literal paragraphs have special considerations (and this is one of # two entry points into one) diff --git a/test/lists_test.rb b/test/lists_test.rb index bc9de773..857dbef5 100644 --- a/test/lists_test.rb +++ b/test/lists_test.rb @@ -4155,6 +4155,89 @@ context 'Description lists redux' do assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="paragraph"]', output, 1 assert_xpath '//*[@class="dlist"]/following-sibling::*[@class="paragraph"]/p[text()="detached"]', output, 1 end + + test 'block attribute lines above nested horizontal list does not break list' do + input = <<~'EOS' + Operating Systems:: + [horizontal] + Linux::: Fedora + BSD::: OpenBSD + + Cloud Providers:: + PaaS::: OpenShift + IaaS::: AWS + EOS + + output = convert_string_to_embedded input + assert_xpath '//dl', output, 2 + assert_xpath '/*[@class="dlist"]/dl', output, 1 + assert_xpath '(//dl)[1]/dd', output, 2 + assert_xpath '((//dl)[1]/dd)[1]//table', output, 1 + assert_xpath '((//dl)[1]/dd)[2]//table', output, 0 + end + + test 'block attribute lines above nested list with style does not break list' do + input = <<~'EOS' + TODO List:: + * get groceries + Grocery List:: + [square] + * bread + * milk + * lettuce + EOS + + output = convert_string_to_embedded input + assert_xpath '//dl', output, 1 + assert_xpath '(//dl)[1]/dd', output, 2 + assert_xpath '((//dl)[1]/dd)[2]//ul[@class="square"]', output, 1 + end + + test 'multiple block attribute lines above nested list does not break list' do + input = <<~'EOS' + Operating Systems:: + [[variants]] + [horizontal] + Linux::: Fedora + BSD::: OpenBSD + + Cloud Providers:: + PaaS::: OpenShift + IaaS::: AWS + EOS + + output = convert_string_to_embedded input + assert_xpath '//dl', output, 2 + assert_xpath '/*[@class="dlist"]/dl', output, 1 + assert_xpath '(//dl)[1]/dd', output, 2 + assert_xpath '(//dl)[1]/dd/*[@id="variants"]', output, 1 + assert_xpath '((//dl)[1]/dd)[1]//table', output, 1 + assert_xpath '((//dl)[1]/dd)[2]//table', output, 0 + end + + test 'multiple block attribute lines separated by empty line above nested list does not break list' do + input = <<~'EOS' + Operating Systems:: + [[variants]] + + [horizontal] + + Linux::: Fedora + BSD::: OpenBSD + + Cloud Providers:: + PaaS::: OpenShift + IaaS::: AWS + EOS + + output = convert_string_to_embedded input + assert_xpath '//dl', output, 2 + assert_xpath '/*[@class="dlist"]/dl', output, 1 + assert_xpath '(//dl)[1]/dd', output, 2 + assert_xpath '(//dl)[1]/dd/*[@id="variants"]', output, 1 + assert_xpath '((//dl)[1]/dd)[1]//table', output, 1 + assert_xpath '((//dl)[1]/dd)[2]//table', output, 0 + end end context 'Item with text inline' do |
