From f3ec6022fec01db7eb274fbe8df3612b5b76ceb8 Mon Sep 17 00:00:00 2001 From: Bauke Date: Wed, 24 Jan 2024 13:33:55 +0100 Subject: [PATCH] Add the merge_dictionaries utility function. --- utilities/merge-dictionaries.typ | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 utilities/merge-dictionaries.typ diff --git a/utilities/merge-dictionaries.typ b/utilities/merge-dictionaries.typ new file mode 100644 index 0000000..f7a8fdf --- /dev/null +++ b/utilities/merge-dictionaries.typ @@ -0,0 +1,35 @@ +/// Merge dictionaries together by recursively going through each key. Any +/// non-dictionary keys will be overwritten by whichever value comes last. +#let merge_dictionaries( + /// When two array are found for the same key, merge them together. + merge_arrays: true, + ..args, +) = { + let output = (:) + + for arg in args.pos() { + assert.eq(type(arg), dictionary, message: "Can't merge non-dictionary types.") + + for (key, value) in arg { + if key not in output { + output.insert(key, value) + continue + } + + let value_type = type(value) + let existing_type = type(output.at(key)) + + if value_type == dictionary and existing_type == dictionary { + output.at(key) = merge_dictionaries(output.at(key), value) + } else if merge_arrays and value_type == array and existing_type == array { + for item in value { + output.at(key).push(item) + } + } else { + output.at(key) = value + } + } + } + + return output +}