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.freeze
- 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.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.freeze
Instance Method Summary collapse
- #init ⇒ Object
- #inlinelink(text) ⇒ Object
- #inlinelink_escape(text) ⇒ Object
- #inlinelinkmacro(text) ⇒ Object
- #pass_inline_split(text) ⇒ Object
- #pass_status(status, text) ⇒ Object
- #process(document, reader) ⇒ Object
Instance Method Details
#init ⇒ Object
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/metanorma/standoc/macros.rb', line 77 def init pass = true # process as passthrough: init = true until # hit end of doc header is_delim = false # current line is a no-substititon block delimiter pass_delim = false # current line is a passthrough delimiter delimln = "" # delimiter line of current block(s); # init value looks for end of doc header { pass: pass, is_delim: is_delim, pass_delim: pass_delim, delimln: delimln } end |
#inlinelink(text) ⇒ Object
147 148 149 150 151 152 153 |
# File 'lib/metanorma/standoc/macros.rb', line 147 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
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/metanorma/standoc/macros.rb', line 155 def inlinelink_escape(text) text.gsub(InlineLinkRx) do body, suffix = $4.nil? ? [$3 + $6, "[]"] : [$3, ""] p = $1 and s = $2 and b = $4 if p == "link:" then "#{p}++#{s}#{body}++#{b}#{suffix}" elsif p == "<" "#{p}link:++#{s}#{body.sub(/>$/, '')}++#{b}#{suffix}>" else "#{p}link:++#{s}#{body}++#{b}#{suffix}" end end end |
#inlinelinkmacro(text) ⇒ Object
177 178 179 180 181 182 183 184 185 |
# File 'lib/metanorma/standoc/macros.rb', line 177 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}" end end.join end |
#pass_inline_split(text) ⇒ Object
137 138 139 140 141 |
# File 'lib/metanorma/standoc/macros.rb', line 137 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 |
#pass_status(status, text) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/metanorma/standoc/macros.rb', line 98 def pass_status(status, text) text == "++++" && !status[:delimln] and status[:pass] = !status[:pass] status[:midline_docattr] && !/^:[^ :]+: /.match?(text) and status[:midline_docattr] = false if (status[:is_delim] && /^(-+|\*+|=+|_+)$/.match?(text)) || (!status[:is_delim] && !status[:delimln] && /^-----*$|^\.\.\.\.\.*$/.match?(text)) status[:delimln] = text status[:pass] = true elsif status[:pass_delim] status[:delimln] = "" # end of paragraph for paragraph with [pass] elsif status[:delimln] && text == status[:delimln] status[:pass] = false status[:delimln] = nil elsif /^:[^ :]+: /.match?(text) && (status[:prev_line].empty? || status[:midline_docattr]) status[:pass] = true status[:midline_docattr] = true end status[:is_delim] = /^\[(source|listing|literal|pass)\b/.match?(text) status[:pass_delim] = /^\[(pass)\b/.match?(text) status[:prev_line] = text.strip status end |
#process(document, reader) ⇒ Object
88 89 90 91 92 93 94 95 96 |
# File 'lib/metanorma/standoc/macros.rb', line 88 def process(document, reader) p = init lines = reader.lines.map do |t| p = pass_status(p, t.rstrip) !p[:pass] && t.include?(":") and t = inlinelinkmacro(inlinelink(t)) t end ::Asciidoctor::PreprocessorReader.new document, lines end |