Class: Metanorma::Standoc::LinkProtectPreprocessor
- Inherits:
-
Asciidoctor::Extensions::Preprocessor
- Object
- Asciidoctor::Extensions::Preprocessor
- Metanorma::Standoc::LinkProtectPreprocessor
- Defined in:
- lib/metanorma/standoc/macros.rb
Overview
refer github.com/asciidoctor/asciidoctor/blob/main/lib/asciidoctor/substitutors.rb Not using TreeProcessor because that is still too close to inline expressions being processed on access (e.g. titles)
Constant Summary collapse
- PASS_INLINE_MACROS =
%w(pass pass-format identifier std-link stem) .join("|").freeze
- PASS_INLINE_MACRO_STR =
<<~REGEX.freeze ( \\b(?<![-\\\\]) # word-separator, no hyphen or backslash (?: # don't capture these! (?:#{PASS_INLINE_MACROS}):[^\\s\\[]* | # macro name, :, second key. OR: span:uri \\b [^\\s\\[]* # span:uri, third key ) \\[.*?(?<!\\\\)\\] # [ ... ] not preceded by \\ ) REGEX
- PASS_INLINE_MACRO_RX =
/#{PASS_INLINE_MACRO_STR}/xo
- InlineLinkRx =
InlineLinkRx = %r((^|link:|#CG_BLANK|<|[>();“‘])(\?(?:https?|file|ftp|irc)://)(?:([^s]+)[(|#CC_ALL*?[^\])]|([^s<]*([^s,.?!<)]))))m
%r((^|(?<![-\\])\blink:(?!\+)|\p{Blank}|<|[<>\(\)\[\];"'])((?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)(?:(\[(|.*?[^\\])\])|([^\s\[\]<]*([^\s,.?!\[\]<\)])))))m
- BRACKETS =
{ "<" => ">", "<" => ">", "[" => "]", '"' => '"', "'" => "'", }.freeze
- InlineLinkMacroRx1 =
InlineLinkMacroRx = /\?(?:link|(mailto)):(|[^:s[^s[]*)[(|#CC_ALL*?)]/m
<<~REGEX.freeze (\\\\?)(\\b(?<!-) # optional backslash, no hyphen, word boundary (?:link|mailto):) # link: or mailto: (?!\\+) # no link:+ passthrough (|[^:\\s\\[][^\\s\\[]*) # link: ... up to [ (\\[(|.*?[^\\\\])\\]) # [ ... ], no ] REGEX
- InlineLinkMacroRx =
/#{InlineLinkMacroRx1}/x
Instance Method Summary collapse
- #inlinelink(text) ⇒ Object
- #inlinelink_escape(text) ⇒ Object
- #inlinelinkmacro(text) ⇒ Object
-
#linkcontents_escape(text) ⇒ Object
because links are escaped, https within link text also need to be escaped, # otherwise they will be treated as links themselves.
- #pass_inline_split(text) ⇒ Object
- #process(document, reader) ⇒ Object
Instance Method Details
#inlinelink(text) ⇒ Object
119 120 121 122 123 124 125 |
# File 'lib/metanorma/standoc/macros.rb', line 119 def inlinelink(text) text.include?("://") or return text /^\[.*\]\s*$/.match?(text) and return text pass_inline_split(text) do |x| inlinelink_escape(x) end.join end |
#inlinelink_escape(text) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/metanorma/standoc/macros.rb', line 127 def inlinelink_escape(text) text.gsub(InlineLinkRx) do p = $1 and s = $2 and body = $3 suffix = $4.nil? ? "[]" : "" wrapper = $6 if (!/^(<|[<\(\["'])$/.match?($1) || $6 != BRACKETS[$1]) && $4.nil? body += $6 wrapper = "" end # body, suffix = $4.nil? ? [$3 + $6, "[]"] : [$3, ""] b = linkcontents_escape($4) if p == "link:" "#{p}++#{s}#{body}++#{b}#{suffix}" else "#{p}link:++#{s}#{body}++#{b}#{suffix}#{wrapper}" end end end |
#inlinelinkmacro(text) ⇒ Object
179 180 181 182 183 184 185 186 187 |
# File 'lib/metanorma/standoc/macros.rb', line 179 def inlinelinkmacro(text) (text.include?("[") && ((text.include? "link:") || (text.include? "ilto:"))) or return text pass_inline_split(text) do |x| x.gsub(InlineLinkMacroRx) do "#{$1}#{$2}++#{$3}++#{linkcontents_escape($4)}" end end.join end |
#linkcontents_escape(text) ⇒ Object
because links are escaped, https within link text also need to be escaped, # otherwise they will be treated as links themselves
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/metanorma/standoc/macros.rb', line 156 def linkcontents_escape(text) text.nil? and return nil text # .gsub(InlineLinkMacroRx) do # $1.empty? ? "\\#{$2}#{$3}#{$4}" : text # end .gsub(InlineLinkRx) do esc = $1 == "link:" ? "" : "\\" x = $4 || "#{$5}#{$6}" "#{$1}#{esc}#{$2}#{$3}#{x}" end end |
#pass_inline_split(text) ⇒ Object
109 110 111 112 113 |
# File 'lib/metanorma/standoc/macros.rb', line 109 def pass_inline_split(text) text.split(PASS_INLINE_MACRO_RX).each.map do |x| PASS_INLINE_MACRO_RX.match?(x) ? x : yield(x) end end |
#process(document, reader) ⇒ Object
84 85 86 87 88 89 90 91 92 |
# File 'lib/metanorma/standoc/macros.rb', line 84 def process(document, reader) p = Metanorma::Utils::LineStatus.new lines = reader.lines.map do |t| p.process(t) !p.pass && t.include?(":") and t = inlinelinkmacro(inlinelink(t)) t end ::Asciidoctor::PreprocessorReader.new document, lines end |