1e5c31af7Sopenharmony_ci# Copyright 2018-2022 The Khronos Group Inc. 2e5c31af7Sopenharmony_ci# 3e5c31af7Sopenharmony_ci# SPDX-License-Identifier: Apache-2.0 4e5c31af7Sopenharmony_ci 5e5c31af7Sopenharmony_cirequire 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' 6e5c31af7Sopenharmony_ci 7e5c31af7Sopenharmony_ciinclude ::Asciidoctor 8e5c31af7Sopenharmony_ci 9e5c31af7Sopenharmony_cimodule Asciidoctor 10e5c31af7Sopenharmony_ci 11e5c31af7Sopenharmony_ci# This addition to the parser class overrides the "is_delimited_block?" 12e5c31af7Sopenharmony_ci# method of the core parser, adding a new block delimiter of "~~~~" for open 13e5c31af7Sopenharmony_ci# blocks, which can be extended to an arbitrary number of braces to allow 14e5c31af7Sopenharmony_ci# nesting them, which is a limitation of the existing "only two dashes" 15e5c31af7Sopenharmony_ci# delimiter: https://github.com/asciidoctor/asciidoctor/issues/1121 16e5c31af7Sopenharmony_ci# The choice of tildes is based on comments in that bug. 17e5c31af7Sopenharmony_ci 18e5c31af7Sopenharmony_ciclass Parser 19e5c31af7Sopenharmony_ci # Storing the original method so we can still call it from the overriding 20e5c31af7Sopenharmony_ci # version 21e5c31af7Sopenharmony_ci @OLD_is_delimited_block = method(:is_delimited_block?) 22e5c31af7Sopenharmony_ci 23e5c31af7Sopenharmony_ci # Logic here matches the original Parser#is_delimited_block? method, see 24e5c31af7Sopenharmony_ci # there for details of base implementation. 25e5c31af7Sopenharmony_ci def self.is_delimited_block? line, return_match_data = false 26e5c31af7Sopenharmony_ci # Quick check for a single brace character before forwarding to the 27e5c31af7Sopenharmony_ci # original parser method. 28e5c31af7Sopenharmony_ci if line[0] != '~' 29e5c31af7Sopenharmony_ci return @OLD_is_delimited_block.(line, return_match_data) 30e5c31af7Sopenharmony_ci else 31e5c31af7Sopenharmony_ci line_len = line.length 32e5c31af7Sopenharmony_ci if line_len <= 4 33e5c31af7Sopenharmony_ci tip = line 34e5c31af7Sopenharmony_ci tl = line_len 35e5c31af7Sopenharmony_ci else 36e5c31af7Sopenharmony_ci tip = line[0..3] 37e5c31af7Sopenharmony_ci tl = 4 38e5c31af7Sopenharmony_ci end 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci # Hardcoded tilde delimiter, since that is the only thing this 41e5c31af7Sopenharmony_ci # function deals with. 42e5c31af7Sopenharmony_ci if tip == '~~~~' 43e5c31af7Sopenharmony_ci # tip is the full line when delimiter is minimum length 44e5c31af7Sopenharmony_ci if tl < 4 || tl == line_len 45e5c31af7Sopenharmony_ci if return_match_data 46e5c31af7Sopenharmony_ci context = :open 47e5c31af7Sopenharmony_ci masq = ['comment', 'example', 'literal', 'listing', 'pass', 'quote', 'sidebar', 'source', 'verse', 'admonition', 'abstract', 'partintro'].to_set 48e5c31af7Sopenharmony_ci BlockMatchData.new(context, masq, tip, tip) 49e5c31af7Sopenharmony_ci else 50e5c31af7Sopenharmony_ci true 51e5c31af7Sopenharmony_ci end 52e5c31af7Sopenharmony_ci elsif %(#{tip}#{tip[-1..-1] * (line_len - tl)}) == line 53e5c31af7Sopenharmony_ci if return_match_data 54e5c31af7Sopenharmony_ci context = :open 55e5c31af7Sopenharmony_ci masq = ['comment', 'example', 'literal', 'listing', 'pass', 'quote', 'sidebar', 'source', 'verse', 'admonition', 'abstract', 'partintro'].to_set 56e5c31af7Sopenharmony_ci BlockMatchData.new(context, masq, tip, line) 57e5c31af7Sopenharmony_ci else 58e5c31af7Sopenharmony_ci true 59e5c31af7Sopenharmony_ci end 60e5c31af7Sopenharmony_ci else 61e5c31af7Sopenharmony_ci nil 62e5c31af7Sopenharmony_ci end 63e5c31af7Sopenharmony_ci else 64e5c31af7Sopenharmony_ci nil 65e5c31af7Sopenharmony_ci end 66e5c31af7Sopenharmony_ci end 67e5c31af7Sopenharmony_ci end 68e5c31af7Sopenharmony_ciend 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ciend 71