diff --git a/CHANGES.md b/CHANGES.md index 8e061c7f..0164a489 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ## 3.5.1 +Fixes: + +- Correctly sort YAML map keys with mixed types. (#433, #441) + ## 3.5.0 (2024-04-29) Development: diff --git a/markdown.dtx b/markdown.dtx index bbbd06e8..dcc8e6af 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -32359,13 +32359,38 @@ M.extensions.jekyll_data = function(expect_jekyll_data) for k, _ in pairs(d) do table.insert(keys, k) end - table.sort(keys) +% \end{macrocode} +% \begin{markdown} +% +% For reproducibility, sort the keys. For mixed string-and-numeric keys, sort +% numeric keys before string keys. +% +% \end{markdown} +% \begin{macrocode} + table.sort(keys, function(first, second) + if type(first) ~= type(second) then + return type(first) < type(second) + else + return first < second + end + end) if not p then table.insert(buf, "\\markdownRendererJekyllDataBegin") end - if #d > 0 then + local is_sequence = false + if #d > 0 and #d == #keys then + for i=1, #d do + if d[i] == nil then + goto not_a_sequence + end + end + is_sequence = true + end + ::not_a_sequence:: + + if is_sequence then table.insert(buf, "\\markdownRendererJekyllDataSequenceBegin{") table.insert(buf, self.identifier(p or "null")) table.insert(buf, "}{") @@ -32420,7 +32445,7 @@ M.extensions.jekyll_data = function(expect_jekyll_data) end end - if #d > 0 then + if is_sequence then table.insert(buf, "\\markdownRendererJekyllDataSequenceEnd") else table.insert(buf, "\\markdownRendererJekyllDataMappingEnd") diff --git a/tests/testfiles/lunamark-markdown/jekyll-data-mixed-keys.test b/tests/testfiles/lunamark-markdown/jekyll-data-mixed-keys.test new file mode 100644 index 00000000..e782a6b3 --- /dev/null +++ b/tests/testfiles/lunamark-markdown/jekyll-data-mixed-keys.test @@ -0,0 +1,32 @@ +\markdownSetup{jekyllData=true} +<<< +This test ensures that the Lua `jekyllData` option correctly propagates +through the plain TeX interface and that mixed numeric and string keys +are correctly sorted. + +--- +1: foo +a: bar +--- +>>> +BEGIN document +codeSpan: jekyllData +softLineBreak +softLineBreak +interblockSeparator +jekyllDataBegin +BEGIN jekyllDataMappingBegin +- key: null +- length: 2 +END jekyllDataMappingBegin +BEGIN jekyllDataString +- key: 1 +- value: foo +END jekyllDataString +BEGIN jekyllDataString +- key: a +- value: bar +END jekyllDataString +jekyllDataMappingEnd +jekyllDataEnd +END document