From 6e55a89494c01ad9be6b90212dc79344b402979e Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Mon, 5 May 2025 23:57:27 +0100 Subject: [PATCH] doc: ensure code blocks are safely fenced (#1218) Markdown uses ``` to start and end fenced code blocks. However code blocks can themselves contain ``` sequences. To deal with this, markdown allows code block fences to be of arbitrary length; any sequence of fence-chars that is shorter than the opening fence will not terminate the code block. We can scan through the code block text to find the longest sequence of `-chars to ensure the opening/closing fences are longer than the longest in the code block. Link: https://github.com/danth/stylix/pull/1218 Reviewed-by: awwpotato Co-authored-by: NAHO <90870942+trueNAHO@users.noreply.github.com> Reviewed-by: NAHO <90870942+trueNAHO@users.noreply.github.com> --- docs/default.nix | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/default.nix b/docs/default.nix index 95fa49b7..d0171356 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -290,6 +290,26 @@ let index = builtins.foldl' insertPlatform { } (builtins.attrNames platforms); + /** + Extracts the longest markdown code fence from a string. + + - `str`: the string to be checked + - returns: the longest sequence of "`" characters + */ + longestFence = longestFence' ""; + + longestFence' = + prev: str: + let + groups = builtins.match "[^`]*(`+)(.*)" str; + current = builtins.elemAt groups 0; + remainingStr = builtins.elemAt groups 1; + prevLen = builtins.stringLength prev; + currLen = builtins.stringLength current; + longest = lib.max currLen prevLen; + in + if groups == null then prev else longestFence' longest remainingStr; + # Renders a value, which should have been created with either lib.literalMD # or lib.literalExpression. renderValue = @@ -297,10 +317,15 @@ let if lib.isType "literalMD" value then value.text else if lib.isType "literalExpression" value then + let + # If the text contains ``` characters, our code-fence must be longer + # than the longest "```"-substring in the text. + fence = longestFence value.text; + in '' - ```nix + ${fence}```nix ${value.text} - ``` + ${fence}``` '' else builtins.throw "unexpected value type: ${builtins.typeOf value}";