| # Copyright 2018-2021 The Khronos Group Inc. |
| # |
| # SPDX-License-Identifier: Apache-2.0 |
| |
| require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' |
| |
| include ::Asciidoctor |
| |
| module Asciidoctor |
| |
| # This addition to the parser class overrides the "is_delimited_block?" |
| # method of the core parser, adding a new block delimiter of "~~~~" for open |
| # blocks, which can be extended to an arbitrary number of braces to allow |
| # nesting them, which is a limitation of the existing "only two dashes" |
| # delimiter: https://github.com/asciidoctor/asciidoctor/issues/1121 |
| # The choice of tildes is based on comments in that bug. |
| |
| class Parser |
| # Storing the original method so we can still call it from the overriding |
| # version |
| @OLD_is_delimited_block = method(:is_delimited_block?) |
| |
| # Logic here matches the original Parser#is_delimited_block? method, see |
| # there for details of base implementation. |
| def self.is_delimited_block? line, return_match_data = false |
| # Quick check for a single brace character before forwarding to the |
| # original parser method. |
| if line[0] != '~' |
| return @OLD_is_delimited_block.(line, return_match_data) |
| else |
| line_len = line.length |
| if line_len <= 4 |
| tip = line |
| tl = line_len |
| else |
| tip = line[0..3] |
| tl = 4 |
| end |
| |
| # Hardcoded tilde delimiter, since that's the only thing this |
| # function deals with. |
| if tip == '~~~~' |
| # tip is the full line when delimiter is minimum length |
| if tl < 4 || tl == line_len |
| if return_match_data |
| context = :open |
| masq = ['comment', 'example', 'literal', 'listing', 'pass', 'quote', 'sidebar', 'source', 'verse', 'admonition', 'abstract', 'partintro'].to_set |
| BlockMatchData.new(context, masq, tip, tip) |
| else |
| true |
| end |
| elsif %(#{tip}#{tip[-1..-1] * (line_len - tl)}) == line |
| if return_match_data |
| context = :open |
| masq = ['comment', 'example', 'literal', 'listing', 'pass', 'quote', 'sidebar', 'source', 'verse', 'admonition', 'abstract', 'partintro'].to_set |
| BlockMatchData.new(context, masq, tip, line) |
| else |
| true |
| end |
| else |
| nil |
| end |
| else |
| nil |
| end |
| end |
| end |
| end |
| |
| end |