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 <awwpotato@voidq.com>
Co-authored-by: NAHO <90870942+trueNAHO@users.noreply.github.com>
Reviewed-by: NAHO <90870942+trueNAHO@users.noreply.github.com>
This commit is contained in:
Matt Sturgeon 2025-05-05 23:57:27 +01:00 committed by GitHub
parent 45aa0e8492
commit 6e55a89494
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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}";