# This file is part of NIT ( http://www.nitlanguage.org ). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Extends the wiki with an external highlighter (or any processor) for code blocks module markdown_highlight import wiki_links redef class WikiConfig # External highlighter command called to process block code. # # * key: `wiki.highlighter` # * default: empty string, that means no external highlighter # * example: `highlight --fragment -S "$1" --inline-css --enclose-pre` # # The external highlighter is a shell command invoked with `sh -c`. # The meta information of the fence is passed as `$1`. # *Important*: `$1` is given as is, thus is tainted. You SHOULD protect it with quotes in the command. # # By default, the highlighter is only called on fenced block code with a meta information. # See `wiki.highlighter.default` to force the invocation of the highlighter on any code block. # # The output of the command will be inserted as is in the generated document. # Therefore it is expected that the command returns a valid, complete and balanced HTML fragment. # If the highlighter returns nothing (empty output), the internal rendering is used as a fall-back # (as if the option was not set). # # Advanced usages can invoke a custom shell script instead of a standard command to # check the argument, filter it, dispatch to various advanced commands, implement ad-hoc behaviors, etc. var highlighter: String is lazy do return value_or_default("wiki.highlighter", "") end # Default meta (i.e. language) to use to call the external highlighter. # # * key: `wiki.highlighter.default` # * default: empty string, that means no default meta information. # * example: `nit` # # When set, this configuration forces the external highlighter (see `wiki.highlighter`) # to be called also on basic code block (with the indentation) and plain fenced code # blocks (without meta information). # # The value is used as the `$1` argument of the configured highlighter command. # # Note: has no effect if `wiki.highlighter` is not set. var highlighter_default: String is lazy do return value_or_default("wiki.highlighter.default", "") end end redef class NitiwikiDecorator # Extends special cases for meta in fences redef fun add_code(v, block) do var highlighter = wiki.config.highlighter # No highlighter, then defaults if highlighter.is_empty then super return end var code = block.raw_content var meta = block.meta or else wiki.config.highlighter_default # No meta nor forced meta, then defaults if meta.is_empty then super return end # Execute the command wiki.message("Executing `{highlighter}` `{meta}` (in {context.src_path.as(not null)})", 2) var proc = new ProcessDuplex("sh", "-c", highlighter, "", meta.to_s) var res = proc.write_and_read(code) if proc.status != 0 then wiki.message("Warning: `{highlighter}` `{meta}` returned {proc.status} (in {context.src_path.as(not null)})", 0) end # Check the result if res.is_empty then # No result, then defaults wiki.message(" `{highlighter}` produced nothing, process internally instead (in {context.src_path.as(not null)})", 2) super return end v.add(res) end end