使用 */ 和 /** 作为 markdown 包的代码块围栏

使用 */ 和 /** 作为 markdown 包的代码块围栏

我曾以接近文学编程的风格编写过一个程序。该程序源代码包含大量 Markdown 块,这些块位于像这样的块注释中。

/**
## Entities, state variables, and scales

The model consists of agents interacting on a hexagonal discrete global grid in
discrete time. One time step is supposed to model a season with a duration of
half a year.

 */    
type HalfYears = u32;    
/**
Whereever possible, resources are measured in kcal (in SI units: 1 kcal = 4.184 kJ)

 */    
type KCal = f32;
// Maybe KCal should be a finite f32? I bet there is a crate for that…

我希望将此\markdownInput源代码作为程序更大描述的一部分。我如何编写一些 Lua 代码来说服\usepackage{markdown}将其解析⎵*/为 Rust 代码块的起始围栏和 /**结束围栏?也就是说,当使用此文档大纲时

\documentclass{scrartcl}
\usepackage{markdown}
% some Lua magic
\begin{document}
\section{Model description}
\markdownInput{model/src/main.rs}
\end{document}

我希望出现类似底部的东西,目前它显然产生了顶部。

预览当前和预期的输出

答案1

我按照以下方式为这个特定项目扩展了 markdown 包(具体来说,就是markdown.dtx随后编译到包中的各个文件中)。

1 file changed, 41 insertions(+)
markdown.dtx | 41 +++++++++++++++++++++++++++++++++++++++++

modified   markdown.dtx
@@ -14079,6 +14079,41 @@ parsers.fencedline   = function(char)
                          return s:sub(i)
                        end
 end
+
+parsers.anticommenthead = function()
+  return               C(parsers.nonindentspace) / function(s) fenceindent = #s end
+                     * Cg(parsers.optionalspace * parsers.asterisk * parsers.slash, "fencelength")
+                     * parsers.optionalspace * C(parsers.infostring)
+                     * parsers.optionalspace * (parsers.newline + parsers.eof)
+end
+
+parsers.anticommenttail = function()
+  return             parsers.optionalspace * P("TEST")
+                     + parsers.slash * parsers.doubleasterisks
+                     * parsers.optionalspace * (parsers.newline + parsers.eof)
+                     + parsers.eof
+end
+
+parsers.anticommentline = 
+                     C(parsers.line - parsers.anticommenttail())
+                     / function(s)
+                         i = 1
+                         remaining = fenceindent
+                         while true do
+                           c = s:sub(i, i)
+                           if c == " " and remaining > 0 then
+                             remaining = remaining - 1
+                             i = i + 1
+                           elseif c == "\t" and remaining > 3 then
+                             remaining = remaining - 4
+                             i = i + 1
+                           else
+                             break
+                           end
+                         end
+                         return s:sub(i)
+                       end
+
 %    \end{macrocode}
 % \par
 % \begin{markdown}
@@ -14558,6 +14593,11 @@ parsers.LocalFilePath
                      * parsers.localfilepath
                      * parsers.optionaltitle

+parsers.AntiCommentFencedCode
+                     = parsers.anticommenthead()
+                     * Cs(parsers.anticommentline^0)
+                     * parsers.anticommenttail()
+
 parsers.TildeFencedCode
                      = parsers.fencehead(parsers.tilde)
                      * Cs(parsers.fencedline(parsers.tilde)^0)
@@ -15169,6 +15209,7 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
                            ) / expandtabs / writer.verbatim

   larsers.FencedCode   = (parsers.TildeFencedCode
+                         + parsers.AntiCommentFencedCode
                          + parsers.BacktickFencedCode)
                        / function(infostring, code)
                            return writer.fencedCode(writer.string(infostring),

这将添加*//**,块注释分隔符(按此顺序!这就是为什么它是反对我使用注释栅栏作为 Markdown 解析器的栅栏。这个实现不是很健壮,因为我不知道我弄乱的东西的内部结构,我希望这不会在以后困扰我。

相关内容