From 08f63e625440e08119e5bc530994963888e0c0e5 Mon Sep 17 00:00:00 2001 From: winniehell Date: Sun, 20 Oct 2024 18:18:04 +0200 Subject: [PATCH 1/5] Sort keys when encoding tables as JSON --- src/resources/pandoc/datadir/_json.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources/pandoc/datadir/_json.lua b/src/resources/pandoc/datadir/_json.lua index 06e9d57a6e3..736409b6470 100644 --- a/src/resources/pandoc/datadir/_json.lua +++ b/src/resources/pandoc/datadir/_json.lua @@ -101,7 +101,7 @@ local function encode_table(val, stack) return "[" .. table.concat(res, ",") .. "]" elseif types["string"] then -- Treat as object - for k, v in pairs(val) do + for k, v in _quarto.utils.table.sortedPairs(val) do table.insert(res, encode_string(k) .. ":" .. encode(v, stack)) end stack[val] = nil From 3462373ba829dbf3ef49ae66bbd16708d327d33c Mon Sep 17 00:00:00 2001 From: winniehell Date: Mon, 21 Oct 2024 20:08:17 +0200 Subject: [PATCH 2/5] Update json.lua from current (unreleased) master https://github.com/rxi/json.lua/blob/dbf4b2dd2eb7c23be2773c89eb059dadd6436f94/json.lua --- src/resources/pandoc/datadir/_json.lua | 78 ++++++++++++-------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/src/resources/pandoc/datadir/_json.lua b/src/resources/pandoc/datadir/_json.lua index 736409b6470..9da79cc52b3 100644 --- a/src/resources/pandoc/datadir/_json.lua +++ b/src/resources/pandoc/datadir/_json.lua @@ -4,8 +4,7 @@ -- Copyright (c) 2020 rxi -- https://github.com/rxi/json.lua -- --- 2023-02-08: Modified by RStudio, PBC to make encoding more robust under the --- following example: encode(decode("[null, 'test']")) +-- includes unreleased upstream changes: https://github.com/rxi/json.lua/blob/dbf4b2dd2eb7c23be2773c89eb059dadd6436f94/json.lua -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of -- this software and associated documentation files (the "Software"), to deal in @@ -26,7 +25,7 @@ -- SOFTWARE. -- -local json = { _version = "0.1.2" } +local json = { _version = "0.1.2-quarto" } ------------------------------------------------------------------------------- -- Encode @@ -59,9 +58,6 @@ local function encode_nil(val) return "null" end -local function encode_string(val) - return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' -end local function encode_table(val, stack) local res = {} @@ -72,45 +68,44 @@ local function encode_table(val, stack) stack[val] = true - local n = 0 - local types = {} - - for k in pairs(val) do - types[type(k)] = true - end - - if #types > 1 then - error("invalid table: mixed or invalid key types") - elseif types["number"] then - -- Treat as array - local max_key = 0 + if rawget(val, 1) ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 for k in pairs(val) do - if k > max_key then - max_key = k + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") end + n = n + 1 end - for i = 1, max_key do - if val[i] == nil then - table.insert(res, "null") - else - local v = encode(val[i], stack) - table.insert(res, v) - end + if n ~= #val then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) end stack[val] = nil return "[" .. table.concat(res, ",") .. "]" - elseif types["string"] then - -- Treat as object - for k, v in _quarto.utils.table.sortedPairs(val) do - table.insert(res, encode_string(k) .. ":" .. encode(v, stack)) + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) end stack[val] = nil return "{" .. table.concat(res, ",") .. "}" - else - return "[]" end end + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + local function encode_number(val) -- Check for NaN, -inf and inf if val ~= val or val <= -math.huge or val >= math.huge then @@ -139,7 +134,7 @@ encode = function(val, stack) end -local function jsonEncode(val) +function json.encode(val) return ( encode(val) ) end @@ -205,7 +200,7 @@ local function codepoint_to_utf8(n) return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) elseif n <= 0x10ffff then return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, - f(n % 4096 / 64) + 128, n % 64 + 128) + f(n % 4096 / 64) + 128, n % 64 + 128) end error( string.format("invalid unicode codepoint '%x'", n) ) end @@ -214,7 +209,7 @@ end local function parse_unicode_escape(s) local n1 = tonumber( s:sub(1, 4), 16 ) local n2 = tonumber( s:sub(7, 10), 16 ) - -- Surrogate pair? + -- Surrogate pair? if n2 then return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) else @@ -240,8 +235,8 @@ local function parse_string(str, i) local c = str:sub(j, j) if c == "u" then local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) - or str:match("^%x%x%x%x", j + 1) - or decode_error(str, j - 1, "invalid unicode escape in string") + or str:match("^%x%x%x%x", j + 1) + or decode_error(str, j - 1, "invalid unicode escape in string") res = res .. parse_unicode_escape(hex) j = j + #hex else @@ -380,7 +375,7 @@ parse = function(str, idx) end -local function jsonDecode(str) +function json.decode(str) if type(str) ~= "string" then error("expected argument of type string, got " .. type(str)) end @@ -393,7 +388,4 @@ local function jsonDecode(str) end -return { - encode = jsonEncode, - decode = jsonDecode -} \ No newline at end of file +return json \ No newline at end of file From 2e56476fb88c4c98d865c56a5ab5b3c381408be4 Mon Sep 17 00:00:00 2001 From: winniehell Date: Mon, 21 Oct 2024 20:09:43 +0200 Subject: [PATCH 3/5] Update json.lua from pending pull request https://github.com/rxi/json.lua/pull/51 --- src/resources/pandoc/datadir/_json.lua | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/resources/pandoc/datadir/_json.lua b/src/resources/pandoc/datadir/_json.lua index 9da79cc52b3..b36a4929588 100644 --- a/src/resources/pandoc/datadir/_json.lua +++ b/src/resources/pandoc/datadir/_json.lua @@ -5,6 +5,7 @@ -- https://github.com/rxi/json.lua -- -- includes unreleased upstream changes: https://github.com/rxi/json.lua/blob/dbf4b2dd2eb7c23be2773c89eb059dadd6436f94/json.lua +-- includes unmerged upstream pull request: https://github.com/rxi/json.lua/pull/51 -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of -- this software and associated documentation files (the "Software"), to deal in @@ -27,6 +28,21 @@ local json = { _version = "0.1.2-quarto" } +-- taken from https://www.lua.org/pil/19.3.html +function pairsByKeys (t, f) + local a = {} + for n in pairs(t) do table.insert(a, n) end + table.sort(a, f) + local i = 0 -- iterator variable + local iter = function () -- iterator function + i = i + 1 + if a[i] == nil then return nil + else return a[i], t[a[i]] + end + end + return iter +end + ------------------------------------------------------------------------------- -- Encode ------------------------------------------------------------------------------- @@ -89,7 +105,7 @@ local function encode_table(val, stack) else -- Treat as an object - for k, v in pairs(val) do + for k, v in pairsByKeys(val) do if type(k) ~= "string" then error("invalid table: mixed or invalid key types") end @@ -388,4 +404,4 @@ function json.decode(str) end -return json \ No newline at end of file +return json From 86ae7b394d2a0c8ca4e41ec243b1e28346fa3306 Mon Sep 17 00:00:00 2001 From: winniehell Date: Mon, 21 Oct 2024 21:13:50 +0200 Subject: [PATCH 4/5] Update json.lua from pending pull request https://github.com/rxi/json.lua/pull/52 --- src/resources/pandoc/datadir/_json.lua | 58 +++++++++++++++----------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/resources/pandoc/datadir/_json.lua b/src/resources/pandoc/datadir/_json.lua index b36a4929588..5b8143fc178 100644 --- a/src/resources/pandoc/datadir/_json.lua +++ b/src/resources/pandoc/datadir/_json.lua @@ -6,6 +6,7 @@ -- -- includes unreleased upstream changes: https://github.com/rxi/json.lua/blob/dbf4b2dd2eb7c23be2773c89eb059dadd6436f94/json.lua -- includes unmerged upstream pull request: https://github.com/rxi/json.lua/pull/51 +-- includes unmerged upstream pull request: https://github.com/rxi/json.lua/pull/52 -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of -- this software and associated documentation files (the "Software"), to deal in @@ -74,6 +75,9 @@ local function encode_nil(val) return "null" end +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end local function encode_table(val, stack) local res = {} @@ -84,44 +88,48 @@ local function encode_table(val, stack) stack[val] = true - if rawget(val, 1) ~= nil or next(val) == nil then - -- Treat as array -- check keys are valid and it is not sparse - local n = 0 + if next(val) == nil then + return '[]' + end + + local types = {} + + for k in pairs(val) do + types[type(k)] = true + end + + if #types > 1 then + error("invalid table: mixed or invalid key types") + elseif types["number"] then + -- Treat as array + local max_key = 0 for k in pairs(val) do - if type(k) ~= "number" then - error("invalid table: mixed or invalid key types") + if k > max_key then + max_key = k end - n = n + 1 - end - if n ~= #val then - error("invalid table: sparse array") end - -- Encode - for i, v in ipairs(val) do - table.insert(res, encode(v, stack)) + for i = 1, max_key do + if val[i] == nil then + table.insert(res, "null") + else + local v = encode(val[i], stack) + table.insert(res, v) + end end stack[val] = nil return "[" .. table.concat(res, ",") .. "]" - - else - -- Treat as an object + elseif types["string"] then + -- Treat as object for k, v in pairsByKeys(val) do - if type(k) ~= "string" then - error("invalid table: mixed or invalid key types") - end - table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + table.insert(res, encode_string(k) .. ":" .. encode(v, stack)) end stack[val] = nil return "{" .. table.concat(res, ",") .. "}" + else + error( string.format("invalid table: unsupported key type %s", types[1]) ) end end - -local function encode_string(val) - return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' -end - - local function encode_number(val) -- Check for NaN, -inf and inf if val ~= val or val <= -math.huge or val >= math.huge then From 2b90b33889646adb6ad9480bf4fab18403fc8e3d Mon Sep 17 00:00:00 2001 From: winniehell Date: Mon, 21 Oct 2024 22:27:54 +0200 Subject: [PATCH 5/5] Add changelog entries --- news/changelog-1.6.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/news/changelog-1.6.md b/news/changelog-1.6.md index 828da297522..328af0f5f1d 100644 --- a/news/changelog-1.6.md +++ b/news/changelog-1.6.md @@ -19,6 +19,7 @@ All changes included in 1.6: - ([#10858](https://github.com/quarto-dev/quarto-cli/issues/10858)): Don't crash in `gfm` when `content` of a `FloatRefTarget` is of type `Blocks`. - ([#10894](https://github.com/quarto-dev/quarto-cli/issues/10894)): Fix configuration of title and prefix in callouts for `html`, `revealjs`, `pdf`, and `typst`. - ([#10999](https://github.com/quarto-dev/quarto-cli/issues/10999)): New API entry point: `quarto.paths.rscript()` to resolve `Rscript` path in Lua filters and extensions consistently with Quarto itself. +- ([#11124](https://github.com/quarto-dev/quarto-cli/pull/11124)): Sort keys when encoding tables as JSON ## `dashboard` Format @@ -29,6 +30,7 @@ All changes included in 1.6: - Fix `kbd` element styling on dark themes. - ([#10761](https://github.com/quarto-dev/quarto-cli/issues/10761)): Add support for `licence: CC0` to automatically link to Creative Commons licence [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/). - ([#10817](https://github.com/quarto-dev/quarto-cli/issues/10817)): Ensure that user provided SCSS has precedent over quarto generated scss also for dark theme. +- ([#11124](https://github.com/quarto-dev/quarto-cli/pull/11124)): Use stable order of GLightbox options ## `revealjs` Format