texlive[73655] Master/texmf-dist: jsonparse (30jan25)

commits+karl at tug.org commits+karl at tug.org
Fri Jan 31 17:48:32 CET 2025


Revision: 73655
          https://tug.org/svn/texlive?view=revision&revision=73655
Author:   karl
Date:     2025-01-31 17:48:32 +0100 (Fri, 31 Jan 2025)
Log Message:
-----------
jsonparse (30jan25)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/jsonparse/README.md
    trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.pdf
    trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.tex
    trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty

Modified: trunk/Master/texmf-dist/doc/latex/jsonparse/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/jsonparse/README.md	2025-01-31 00:44:09 UTC (rev 73654)
+++ trunk/Master/texmf-dist/doc/latex/jsonparse/README.md	2025-01-31 16:48:32 UTC (rev 73655)
@@ -1,4 +1,4 @@
-![Version 1.0.3](https://img.shields.io/badge/version-1.0.3-blue)
+![Version 1.1.0](https://img.shields.io/badge/version-1.1.0-blue)
 
 ![Jason, the JSON parsing horse](https://github.com/jasperhabicht/jsonparse/assets/6378801/ddfddc70-bf5f-4121-ba45-4b9128875d85)
 
@@ -44,8 +44,12 @@
 
 We can store it in the token variable `\myJSONdata` using the command `\JSONParseFromFile{\myJSONdata}{example.json}`. Calling the command `\JSONParseValue{\myJSONdata}{contactPoint[0].telephone}` would then result in the output `+1 (555) 555-1234` (indices are zero-based per default). 
 
-The package also offers several commands for looping through arrays and accessing individual elements, for example to typeset them in tabular form.
+The package also offers several commands for looping through arrays and accessing individual elements, for example to typeset them in tabular form. 
 
+The package also provides a few helper commands such as to validate a JSON number or to convert Unicode surrogate pairs to the relevant Unicode codepoint.
+
+---
+
 This package including all files is subject to the LPPL 1.3c license. Copyright 2024–2025 Jasper Habicht (mail(at)jasperhabicht.de).
 
 Jason, the JSON parsing horse: Copyright 2024–2025 Hannah Klöber.

Modified: trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.tex	2025-01-31 00:44:09 UTC (rev 73654)
+++ trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.tex	2025-01-31 16:48:32 UTC (rev 73655)
@@ -11,8 +11,8 @@
 % This work has the LPPL maintenance status `maintained'.
 %
 \documentclass[a4paper]{article}
-\def\jsonparsefileversion{1.0.3}
-\def\jsonparsefiledate{26 January 2025}
+\def\jsonparsefileversion{1.1.0}
+\def\jsonparsefiledate{30 January 2025}
 
 \usepackage[T1]{fontenc}
 \usepackage{Alegreya}
@@ -37,7 +37,7 @@
 }
 \makeatother
 
-\tcbuselibrary{listings}
+\tcbuselibrary{skins,listings}
 \lstdefinestyle{jsonparsedocmacro}{
     basicstyle=\small\ttfamily,
     literate=*{<}{{{\color{black!50}\guilsinglleft}}}1
@@ -127,12 +127,22 @@
     title style hook/.style={}
 }
 
-\NewTCBListing{macrodef}{ }{
+\NewTCBListing{macrodef}{ s }{
     listing only,
     listing style={jsonparsedocmacro},
     grow to left by=2cm,
     boxrule=0pt,
-    after={\par\smallskip\noindent}
+    after={\par\smallskip\noindent},
+    enhanced,
+    overlay={
+      \IfBooleanT{#1}{
+        \fill[black!50, shift={([xshift={-10pt}, yshift={-10pt-0.5em}]frame.north east)}]
+          (90:3.75pt)
+          \foreach \i in {1,...,4} {
+            -- ({90+360/5*\i*2}:3.75pt)
+          } -- cycle;
+      }
+    }
 }
 
 \NewTCBListing{codeexample}{ }{
@@ -218,6 +228,7 @@
 \changes{v1.0.1}{2025/01/21}{Fixes in documentation. Added user command for filtering.}
 \changes{v1.0.2}{2025/01/23}{Support for Unicode surrogate pairs.}
 \changes{v1.0.3}{2025/01/26}{Test for valid JSON numbers expandable.}
+\changes{v1.1.0}{2025/01/30}{Unified names of user functions; renaming key for keywords.}
 
 \begin{document}
 \vspace*{-1cm}
@@ -233,13 +244,13 @@
 
 The \macro{jsonparse} package provides a handy way to read in JSON data from files or strings in LaTeX documents, parse the data and store it in a user-defined token variable. The package allows accessing the stored data via a JavaScript-flavored syntax.
 
-The package has been tested, but not exhaustively. The author is grateful for reporting any bugs via GitHub at \url{https://github.com/jasperhabicht/jsonparse/issues}. A site for asking questions about how to use the package and for suggestions for improvement is available at \url{https://github.com/jasperhabicht/jsonparse/discussions}.  
+The package has been tested, but not exhaustively. The author is grateful for reporting any bugs via GitHub at \url{https://github.com/jasperhabicht/jsonparse/issues}. A site for asking questions about how to use the package and for suggestions for improvement is available at \url{https://github.com/jasperhabicht/jsonparse/discussions}.
 
 \section{Loading the package}
 
 To install the package, copy the package file \macro{jsonparse.sty} into the working directory or into the \macro{texmf} directory. After the package has been installed, the \macro{jsonparse} package is loaded by calling \macro{\usepackage{jsonparse}} in the preamble of the document.
 
-The package does not load any dependencies.
+The package does not load any dependencies. It can be used with PDFLaTeX, LuaLaTeX or XeLaTeX.
 
 \begin{macrodef}
 |debug|
@@ -252,15 +263,17 @@
 
 In general, the package will read and store the JSON source and data as string, which means that all characters have category code 12 (``other''), except for spaces and (horizontal) tabs which have category code 10 (``space''). The \macro{\endlinechar} value is set to $-1$ which means that linefeeds and carriage returns are ignored by TeX. These settings are in line with the JSON specification of handling whitespace. Furthermore, if PDFLaTeX is used, the upper-half of the 8-bit range is set to ``active''. Additionally, JSON defines a small set of escape sequences and in order to be able to process these, the category code of the backslash is set to 0 (``escape'').
 
+During parsing, the package identifies JSON objects, arrays, strings, numbers, boolean values and null values from the JSON data. It stores all these values together with the relevant keys in a property list. Once the parsing process is done, every value can be retrieved from the property list by calling the relevant key. The package ignores whitespace in the JSON data. The JSON data should be an object or an array. In general, the package accepts any valid JSON data.
+
 \section{Escaping and special treatment of the input}\label{sec:escaping}
 
 JSON strings cannot contain the two characters \macro{"} and \macro{\}. These two characters need to be escaped with a preceding backslash (\macro{\}).  This package therefore redefines locally the TeX control symbols \macro{\"}, \macro{\/}, \macro{\\}, \macro{\b}, \macro{\f}, \macro{\n}, \macro{\r}, \macro{\t} and \macro{\u}. These control symbols are prevented from expanding during parsing. For example, \macro{\"} is first defined as \macro{\exp_not:N \"} and only when typeset, \macro{\"} is expanded to \macro{"}, which ensures that strings are parsed properly.
 
-Similarly, the control symbol \macro{\/} expands eventually to \macro{/} and \macro{\\} to \macro{\c_backslash_str} (i.\,e. a backslash with category code 12).
+Similarly, the control symbol \macro{\/} expands eventually to \macro{/} and \macro{\\} to \macro{\c_backslash_str} (i.\,e.\ a backslash with category code 12).
 
 The escape sequence \macro{\u} followed by a hex value consisting of four digits eventually expands to \macro{\codepoint_generate:nn} that creates the character represented by the relevant four hex digits with category code 12 (``other''). If two escape sequences \macro{\u} with four hex digits each follow each other and together represent a Unicode surrogate pair, this surrogate pair is converted into the relevant Unicode codepoint.
 
-The JSON escape sequences \macro{\b}, \macro{\f}, \macro{\n}, \macro{\r} and \macro{\t} eventually expand to token variables of which the contents can be set using the relevant \macro{replacement} key. See more on setting options below in section \ref{sec:options}.
+The JSON escape sequences \macro{\b}, \macro{\f}, \macro{\n}, \macro{\r} and \macro{\t} eventually expand to token variables of which the contents can be set using the relevant \macro{replace} key. See more on setting options below in section \ref{sec:options}.
 
 It is possible to insert TeX macros to the JSON source that will eventually be parsed when typesetting. Backslashes of TeX macros need to be escaped by another backslash. The TeX macros \macro{\"} and \macro{\\} must be escaped twice in the JSON source so that they become \macro{\\\"} and \macro{\\\\} respectively.
 
@@ -298,7 +311,7 @@
 
 The naming of the relevant characters follows their Unicode names. However, \macro{hash} exists as alias for \macro{number sign}, \macro{dollar} as alias for \macro{dollar sign}, \macro{percent} for \macro{percent sign}, \macro{circumflex} for \macro{circumflex accent} and \macro{underscore} for \macro{low line}.
 
-This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayValues} and \macro{\JSONParseArrayValuesMap}.
+This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayUse} and \macro{\JSONParseArrayMapFunction}.
 
 \begin{macrodef}
 |rescan|
@@ -306,7 +319,7 @@
 \end{macrodef}
 The key \macro{rescan} can be used to activate and deactivate rescanning of the output. This key is active per default. Rescanning converts all tokens to their default category codes and TeX control sequences are expanded before typesetting. Further, during the rescanning process, JSON escape sequences are replaced and characters that don't require escaping in JSON but in TeX are replaced by the relevant TeX escape sequences.
 
-This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayValues} and \macro{\JSONParseArrayValuesMap}.
+This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayUse} and \macro{\JSONParseArrayMapFunction}.
 
 \section{Main user commands}
 
@@ -339,7 +352,7 @@
 
 The command \macro{\JSONParseValue} is not expandable and can therefore not be used as argument of certain other arguments where expansion is needed. In such cases, the expandable command \macro{\JSONParseExpandableValue} should be used.
 
-\begin{macrodef}
+\begin{macrodef}*
 |\JSONParseExpandableValue|{<token variable>}{<key>}
 \end{macrodef}
 Whole objects or arrays can be output as JSON string for further use in other macros using the expandable command \macro{\JSONParseExpandableValue}. The value that is returned by this command is typically a string variable where all characters have category code 12 (``other''), except for spaces and (horizontal) tabs that have category code 10 (``space''). This should be kept in mind if string comparisons should be made. A comparison against a token list with the default category codes used by TeX won't work, since letters will have category code 11 (``letter''), but it is possible to use \macro{\detokenize} to set the category codes of the token list in such a way that the comparison works.
@@ -385,10 +398,20 @@
 The command \macro{\JSONParseFilter} is used to select a part (such as an object or an array) of a JSON object or JSON array and parse this into a token variable (a property list). The first argument denotes the token variable where the value should be stored into. The second argument of the command takes the token variable that holds the parsed JSON data. The third argument takes the key to select the relevant entry from the parsed JSON data using JavaScript syntax.
 
 \begin{macrodef}
-|\JSONParseArrayValues|[<options>]{<token variable>}{<key>}[<subkey>]{<string>}
+|\JSONParseArrayCount|{<token variable>}{<key>}
 \end{macrodef}
-The command \macro{\JSONParseArrayValues} is used to select all values from an array from a parsed JSON string or JSON file. The second argument takes the token variable that holds the parsed JSON data. The first argument takes the key to select the relevant entry from the parsed JSON data using JavaScript syntax. The third argument is optional and can be used to pass a subkey, i.\,e. a key that is used to select a value for every item. The last argument takes a string that is inserted between all values when they are typeset.
+The command \macro{\JSONParseArrayCount} takes as first argument a token variable holding a parsed JSON string or JSON file and as second argument a key to select an array in the JSON data. It returns an integer representing the number of items contained in the selected array.
 
+\begin{macrodef}
+|\JSONParseSetArrayCount|{<token variable>}{<token variable>}{<key>}
+\end{macrodef}
+The command \macro{\JSONParseSetArrayCount} takes as second argument a token variable holding a parsed JSON string or JSON file and as third argument a key to select an array in the JSON data. It stores the number of items contained in the selected array in the token variable given in the first argument of the command.
+
+\begin{macrodef}
+|\JSONParseArrayUse|[<options>]{<token variable>}{<key>}[<subkey>]{<string>}
+\end{macrodef}
+The command \macro{\JSONParseArrayUse} is used to select all values from an array from a parsed JSON string or JSON file. The second argument takes the token variable that holds the parsed JSON data. The first argument takes the key to select the relevant entry from the parsed JSON data using JavaScript syntax. The third argument is optional and can be used to pass a subkey, i.\,e.\ a key that is used to select a value for every item. The last argument takes a string that is inserted between all values when they are typeset.
+
 For example, let us assume the following JSON data structure is parsed into the token variable \macro{\myJSONdata}:
 
 \begin{codeexample}
@@ -407,15 +430,17 @@
 \end{codeexample}
 \JSONParse{\myJSONdata}{ { "array" : [ { "key_a" : "one" , "key_b" : "two" } , { "key_a" : "three" , "key_b" : "four" } ] } }
 
-Then, when using \macro{\JSONParseArrayValues{\myJSONdata}{array}[key_a]{, }}, `\JSONParseArrayValues{\myJSONdata}{array}[key_a]{, }' is typeset to the document.
+When using \macro{\JSONParseArrayUse{\myJSONdata}{array}[key_a]{, }}, `\JSONParseArrayUse{\myJSONdata}{array}[key_a]{, }' is then typeset to the document.
 
 The first optional argument can be used to pass options to the command, such as \macro{escape} or \macro{rescan}, that are then applied locally.
 
+For reasons of backward compatibility , the command \macro{\JSONParseArrayValues} is defined as alias of \macro{\JSONParseArrayUse}.
+
 \begin{macrodef}
-|\JSONParseArrayValuesMap|[<options>]{<token variable>}{<key>}[<subkey>]
-  {<command name>}[<before code>][<after code>]
+|\JSONParseArrayMapFunction|[<options>]{<token variable>}{<key>}[<subkey>]
+  {<command>}
 \end{macrodef}
-The command \macro{\JSONParseArrayValuesMap} takes the same first three arguments as the command \macro{\JSONParseArrayValues} and works in a similar way. However, instead of a string that is added between the array items, it takes a command name as fourth argument. This command can be defined beforehand and will be called for every array item. Inside its definition, the commands \macro{\JSONParseArrayIndex}, \macro{\JSONParseArrayKey} and \macro{\JSONParseArrayValue} can be used which are updated for each item and output the index, the key and the value of the current item respectively. Note that these commands are defined globally to make accessing them as easy as possible.
+The command \macro{\JSONParseArrayMapFunction} works in a similar way and takes the same first three arguments as the command \macro{\JSONParseArrayUse}. However, instead of a string that is added between the array items, it takes a command (a token list) as fourth argument. This command can be defined beforehand and will be called for every array item. Inside its definition, the commands \macro{\JSONParseArrayIndex}, \macro{\JSONParseArrayKey} and \macro{\JSONParseArrayValue} can be used which are updated for each item and output the index, the key and the value of the current item respectively. Note that these commands are defined globally to make accessing them as easy as possible.
 
 For example, let us assume the same JSON data structure as defined above parsed into the token variable \macro{\myJSONdata}. Then, the following can be done:
 
@@ -425,8 +450,8 @@
 }
 
 \begin{itemize}
-  \JSONParseArrayValuesMap{\myJSONdata}
-    {array}[key_a]{myJSONitem}
+  \JSONParseArrayMapFunction{\myJSONdata}
+    {array}[key_a]{\myJSONitem}
 \end{itemize}
 \end{codeexamplecolumns}
 
@@ -441,13 +466,18 @@
 }
 
 \begin{itemize}
-  \JSONParseArrayValuesMap{\myJSONdata}
-    {array}[key_a,key_b]{myJSONitem}
+  \JSONParseArrayMapFunction{\myJSONdata}
+    {array}[key_a,key_b]{\myJSONitem}
 \end{itemize}
 \end{codeexamplecolumns}
 
-The command additionally takes two optional arguments at sixth and seventh position. These arguments can be used to place code before and after the output that is generated by the command called for every array item, for example for typesetting tabular contents.
+\begin{macrodef}
+|code before|={<code>}
+|code after|={<code>}
+\end{macrodef}
 
+The \macro{\JSONParseArrayMapFunction} command also accepts the options \macro{code before} and \macro{code after}. These options can be used to place code before and after the output that is generated by the command called for every array item, for example for typesetting tabular contents.
+
 Typesetting the above example in a tabular way can be achieved as follows:
 
 \begin{codeexamplecolumns}
@@ -456,27 +486,24 @@
   \JSONParseArrayValueII \\
 }
 
-\JSONParseArrayValuesMap{\myJSONdata}
-  {array}[key_a,key_b]{myJSONitem}
-  [\begin{tabular}{ c c }
-    \textbf{key a} &
-    \textbf{key b} \\ \hline]
-  [\hline \end{tabular}]
+\JSONParseArrayMapFunction[
+    code before={
+      \begin{tabular}{ c c }
+        \textbf{key a} &
+        \textbf{key b} \\ \hline
+    },
+    code after={
+      \hline \end{tabular}
+    }
+  ]{\myJSONdata}
+  {array}[key_a,key_b]{\myJSONitem}
 \end{codeexamplecolumns}
 
 Finally, the first optional argument of the command can be used to pass options to the command, such as \macro{escape} or \macro{rescan}, that are then applied locally.
 
-\begin{macrodef}
-|\JSONParseArrayCount|{<token variable>}{<key>}
-\end{macrodef}
-The command \macro{\JSONParseArrayCount} takes as first argument a token variable holding a parsed JSON string or JSON file and as second argument a key to select an array in the JSON data. It returns an integer representing the number of items contained in the selected array.
+For reasons of backward compatibility, the command \macro{\JSONParseArrayValuesMap} is defined as alias of \macro{\JSONParseArrayMapFunction}.
 
 \begin{macrodef}
-|\JSONParseSetArrayCount|{<token variable>}{<token variable>}{<key>}
-\end{macrodef}
-The command \macro{\JSONParseSetArrayCount} takes as second argument a token variable holding a parsed JSON string or JSON file and as third argument a key to select an array in the JSON data. It stores the number of items contained in the selected array in the token variable given in the first argument of the command.
-
-\begin{macrodef}
 |\JSONParseArrayMapInline|{<token variable>}{<key>}{<inline function>}
 \end{macrodef}
 The command \macro{\JSONParseArrayMapInline} takes as first argument a token variable holding a parsed JSON string or JSON file and as second argument a key to select an array in the JSON data. The third parameter can contain any code where the index of the current item is represented by \macro{#1}.
@@ -517,9 +544,9 @@
 
 Note that the underscores in the names of the keys can be printed without changing to math mode in the above example because all JSON data is stored as string where all characters (except for spaces and tabs) have category code 12 (``other'').
 
-\subsection{Externalising parsed JSON data}\label{sec:externalizing}
+\subsection{Externalizing parsed JSON data}\label{sec:externalizing}
 
-Parsing large JSON files can take quite a while. In order to speed up follow-up compilation runs, this package provides a way to store parsed JSON data for future use. Once a file for externalization has been created, the package will try to load the data from this file instead of parsing the JSON data again.
+Parsing large and complex JSON files can take quite a while. In order to speed up follow-up compilation runs, this package provides a way to store parsed JSON data for future use. Once a file for externalization has been created, the package will try to load the data from this file instead of parsing the JSON data again.
 
 \begin{macrodef}
 |externalize|
@@ -557,40 +584,60 @@
 
 \subsection{Changing separators, output and other options}\label{sec:options}
 
-The package provides a set of keys can be set to change the separators used to select the relevant value in the JSON structure, the output that is generated from the JSON data as well as other things.
+The package provides a set of keys that can be set to change the separators used to select the relevant value in the JSON structure, the output that is generated from the JSON data as well as other things.
 
 \begin{macrodef}
 |\JSONParseSet|{<options>}
 \end{macrodef}
-The commands \macro{\JSONParseSet} can be used to specify options via key-value pairs (separated by commas). Keys that are presented here as a subkey (i.\,e. preceded by another key and a slash) can also be set using the syntax \macro{key={subkey}} and multiple subkeys belonging to one key can be combined using a comma as separator. Several user commands allow to pass keys directly which are then applied locally. The following keys are available:
+The command \macro{\JSONParseSet} can be used to specify options via key-value pairs (separated by commas). Keys that are presented here as a subkey (i.\,e.\ preceded by another key and a slash such as \macro{key/subkey}) can also be set using the syntax \macro{key={subkey}} and multiple subkeys belonging to one key can be combined using commas as separator. Several user commands allow to pass keys directly which are then applied locally. 
 
+Not every key takes effect in every situation. Some keys affect the parsing procedure and thus need to be set before parsing. Some keys affect the typeset result and some keys only affect the typeset result when used in combination with specific commands.
+
+\subsubsection{Keys affecting the parsing procedure}
+
+Information about the key \macro{externalize} as well as about the related keys \macro{externalize prefix} and \macro{externalize file name} can be found above in section \ref{sec:externalizing}.
+
 \begin{macrodef}
 separator/|child|={<string>}
 separator/|array left|={<string>}
 separator/|array right|={<string>}
 \end{macrodef}
-With the key \macro{separator/child}, the separator for child objects that is used in the syntax to select a specific value in the JSON data structure can be changed. Per default, the child separator is a dot (\macro{.}). Changing the separator can be useful if keys in the JSON structure already use these characters.
+With the key \macro{separator/child}, the separator for child objects that is used in the key to select a specific value in the JSON data structure can be changed. Per default, the child separator is a dot (\macro{.}). 
 
-With the keys \macro{separator/array left} and \macro{separator/array right}, the separators for arrays that are used in the syntax to select a specific value in the JSON data structure can be changed. Per default, the separators are square brackets (\macro{[} and \macro{]}). Changing the separators can be useful if keys in the JSON structure already use these characters. Changing these separators to curly braces (\macro{{}}) is not supported due to their grouping function in TeX.
+With the keys \macro{separator/array left} and \macro{separator/array right}, the separators for arrays that are used in the key to select a specific value in the JSON data structure can be changed. Per default, the separators are square brackets (\macro{[} and \macro{]}). Changing these separators to curly braces (\macro{{}}) is not supported due to their grouping function in TeX.
 
-These keys can be set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}.
+Changing the separators can be useful if keys in the JSON structure already use these characters. These settings take place already during parsing.
 
+These keys can be set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}. When set using \macro{\JSONParseSet}, these keys only take effect when set before parsing.
+
 \begin{macrodef}
 |zero-based|
 |zero-based|={<boolean>}
 \end{macrodef}
-If set (or explicitly set to \macro{true}), the key \macro{zero-based} sets the numbering of the index of array items to zero-based. If set to false, the indexing starts with one instead. Per default, the package uses zero-based indexing to resemble JavaScript notation.
+If the key \macro{zero-based} is set (or explicitly set to \macro{true}), the index of array items starts with zero. If set to false, the indexing starts with one instead. Per default, the package uses zero-based indexing to match JavaScript notation. This setting affects indexing already during parsing. 
 
+This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}. When set using \macro{\JSONParseSet}, this key only takes effect when set before parsing.
+
+\begin{macrodef}
+|check num|
+|check num|={<boolean>}
+\end{macrodef}
+If set to \macro{false}, the key \macro{check num} omits an internal check of numerical expressions against the JSON specification for numbers. Turning off this feature can increase the parsing speed if many numbers are to be parsed. Checks are carried out per default.
+
 This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}.
 
+\subsubsection{Keys affecting the typesetting}
+
+Information about the keys \macro{escape} and \macro{rescan} can be found above in section \ref{sec:escaping}. Information about the keys \macro{code before} and \macro{code after} can be found above in the description to the command \macro{\JSONParseArrayMapFunction}.
+
 \begin{macrodef}
-replace/|true|={<string>}
-replace/|false|={<string>}
-replace/|null|={<string>}
+keyword/|true|={<string>}
+keyword/|false|={<string>}
+keyword/|null|={<string>}
 \end{macrodef}
-With the keys \macro{replace/true}, \macro{replace/false} and \macro{replace/null}, the string that is typeset for true, false and null values can be changed. The default strings that are typeset are \macro{true}, \macro{false} and \macro{null} respectively. Only strings can be used as replacement. These replacements take place already during parsing.
+With the keys \macro{keyword/true}, \macro{keyword/false} and \macro{keyword/null}, the string that is typeset for true, false and null values can be changed. The default strings that are typeset are \macro{true}, \macro{false} and \macro{null} respectively. Only strings can be used as replacement. These replacements take place already during parsing.
 
-These keys can be set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}.
+These keys can be set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}. When set using \macro{\JSONParseSet}, these keys only take effect when set before parsing.
 
 \begin{macrodef}
 replace/|backspace|={<string>}
@@ -599,20 +646,14 @@
 replace/|carriage return|={<string>}
 replace/|horizontal tab|={<string>}
 \end{macrodef}
-These keys can be used to set the replacement text for the JSON escape sequences \macro{\b} (backspace), \macro{\f} (formfeed), \macro{\n} (linefeed), \macro{\r} (carriage return) and \macro{\t} (horizontal tab). The default replacement string is a space. Only strings can be used as replacement. These replacements take place only during typesetting.
+These keys can be used to set the replacement text for the JSON escape sequences \macro{\b} (backspace), \macro{\f} (formfeed), \macro{\n} (linefeed), \macro{\r} (carriage return) and \macro{\t} (horizontal tab). The default replacement string is a space in each case. Only strings can be used as replacement. These replacements take place only during typesetting.
 
-These keys can be set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayValues} and \macro{\JSONParseArrayValuesMap}.
+These keys can be set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayUse} and \macro{\JSONParseArrayMapFunction}.
 
-\begin{macrodef}
-|check num|
-|check num|={<boolean>}
-\end{macrodef}
-If set to \macro{false}, the key \macro{check num} omits an internal check of numerical expressions against the JSON specification for numbers. Turning off this feature can increase the parsing speed.
+\subsection{L3 commands}
 
-This key can be set using \macro{\JSONParseSet}. It can also be set locally as option to the commands \macro{\JSONParse} and \macro{\JSONParseFromFile}.
+The following commands are provided for defining user functions by package authors.
 
-\subsection{L3 commands}
-
 \begin{macrodef}
 |\jsonparse_parse:n| {<JSON string>}
 \end{macrodef}
@@ -638,17 +679,15 @@
 \end{macrodef}
 The command \macro{\jsonparse_array_count:NN} processes the token variable given as the first arguments as property list and, assuming that it is an array, counts its items and stores the result in the integer variable. If the token variable does not expand to a key that represents an array item, that is if the key does not start with the character defined by \macro{separator/array left}, the command will return an error. The command \macro{\JSONParseArrayCount} serves as a wrapper of this command.
 
-\begin{macrodef}
+\begin{macrodef}*
 |\jsonparse_if_num:nTF| {<string>} {<true code>} {<false code>}
 |\jsonparse_if_num:nT| {<string>} {<true code>}
 |\jsonparse_if_num:nF| {<string>} {<false code>}
 |\jsonparse_if_num_p:n| {<string>}
 \end{macrodef}
-The command \macro{\jsonparse_if_num:nTF} checks whether a string is a valid JSON number according the relevant specification. It executes the true code if the string is a valid JSON number and the false code if not. The variants \macro{\jsonparse_if_num:nT} and \macro{\jsonparse_if_num:nF} work accordingly. The command \macro{\jsonparse_if_num_p:n} returns a boolean true or false (i.\,e. \macro{\c_true_bool} or \macro{\c_false_bool}).
+The expandable conditional function \macro{\jsonparse_if_num:nTF} checks whether a string is a valid JSON number according the relevant specification. It executes the true code if the string is a valid JSON number and the false code if not. The variants that only provide an argument for the true or false case work accordingly. The command \macro{\jsonparse_if_num_p:n} returns a boolean true or false (i.\,e.\ \macro{\c_true_bool} or \macro{\c_false_bool}).
 
-This conditional function is fully expandable.
-
-\begin{macrodef}
+\begin{macrodef}*
 |\jsonparse_unicode_if_high_surrogate:nTF| {<codepoint>}
   {<true code>} {<false code>}
 |\jsonparse_unicode_if_high_surrogate:nT| {<codepoint>} {<true code>}
@@ -655,11 +694,11 @@
 |\jsonparse_unicode_if_high_surrogate:nF| {<codepoint>} {<false code>}
 |\jsonparse_unicode_if_high_surrogate_p:n| {<codepoint>}
 \end{macrodef}
-The command \macro{\jsonparse_unicode_if_high_surrogate:nTF} can be used to check whether a codepoint entered as argument (an integer that can be hexadecimal if preceded by \macro{"}) is in the range of \macro{"D800} and \macro{"DBFF} which means that it is the first part of a surrogate pair (a high surrogate). The variants that only provide an argument for the true or false case work accordingly. The command \macro{\jsonparse_unicode_if_high_surrogate_p:n} returns a boolean true or false (i.\,e. \macro{\c_true_bool} or \macro{\c_false_bool}).
+The expandable conditional function \macro{\jsonparse_unicode_if_high_surrogate:nTF} checks whether the codepoint entered as argument (an integer that can be hexadecimal if preceded by \macro{"}) is in the range of \macro{"D800} and \macro{"DBFF} which means that it is the first part of a surrogate pair (a high surrogate). The variants that only provide an argument for the true or false case work accordingly. The command \macro{\jsonparse_unicode_if_high_surrogate_p:n} returns a boolean true or false (i.\,e.\ \macro{\c_true_bool} or \macro{\c_false_bool}).
 
-This conditional function is fully expandable.
+The variants \macro{\jsonparse_unicode_if_high_surrogate:eTF} etc.\ are predefined for this conditional function.
 
-\begin{macrodef}
+\begin{macrodef}*
 |\jsonparse_unicode_if_low_surrogate:nTF| {<codepoint>}
   {<true code>} {<false code>}
 |\jsonparse_unicode_if_low_surrogate:nT| {<codepoint>} {<true code>}
@@ -666,16 +705,16 @@
 |\jsonparse_unicode_if_low_surrogate:nF| {<codepoint>} {<false code>}
 |\jsonparse_unicode_if_low_surrogate_p:n| {<codepoint>}
 \end{macrodef}
-The command \macro{\jsonparse_unicode_if_low_surrogate:nTF} can be used to check whether a codepoint entered as argument (an integer that can be hexadecimal if preceded by \macro{"}) is in the range of \macro{"DC00} and \macro{"DFFF} which means that it is the last part of a surrogate pair (a low surrogate). The variants that only provide an argument for the true or false case work accordingly. The command \macro{\jsonparse_unicode_if_low_surrogate_p:n} returns a boolean true or false (i.\,e. \macro{\c_true_bool} or \macro{\c_false_bool}).
+The expandable conditional function \macro{\jsonparse_unicode_if_low_surrogate:nTF} checks whether the codepoint entered as argument (an integer that can be hexadecimal if preceded by \macro{"}) is in the range of \macro{"DC00} and \macro{"DFFF} which means that it is the last part of a surrogate pair (a low surrogate). The variants that only provide an argument for the true or false case work accordingly. The command \macro{\jsonparse_unicode_if_low_surrogate_p:n} returns a boolean true or false (i.\,e.\ \macro{\c_true_bool} or \macro{\c_false_bool}).
 
-This conditional function is fully expandable.
+The variants \macro{\jsonparse_unicode_if_low_surrogate_p:eTF} etc.\ are predefined for this conditional function.
 
-\begin{macrodef}
-|\jsonparse_unicode_join_surrogate_pair:nn| {<codepoint>} {<codepoint>}
+\begin{macrodef}*
+|\jsonparse_unicode_convert_surrogate_pair:nn| {<codepoint>} {<codepoint>}
 \end{macrodef}
-The command \macro{\jsonparse_unicode_join_surrogate_pair:nn} coverts a surrogate pair to the relevant codepoint. It takes as first argument the codepoint of the low surrogate and as second argument the codepoint of the high surrogate. It does not check whether the codepoints actually belong to the relevant ranges of codepoints for high and low surrogates.
+The expandable command \macro{\jsonparse_unicode_convert_surrogate_pair:nn} converts a surrogate pair to the relevant Unicode codepoint. The returned value is an integer. It takes as first argument the codepoint of the low surrogate and as second argument the codepoint of the high surrogate. It does not check whether the codepoints actually belong to the relevant ranges of codepoints for high and low surrogates.
 
-This function is fully expandable.
+The variant \macro{\jsonparse_unicode_convert_surrogate_pair:ee} is predefined.
 
 % =====
 

Modified: trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty	2025-01-31 00:44:09 UTC (rev 73654)
+++ trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty	2025-01-31 16:48:32 UTC (rev 73655)
@@ -10,7 +10,7 @@
 %
 % This work has the LPPL maintenance status `maintained'.
 %
-\ProvidesExplPackage {jsonparse} {2025-01-26} {1.0.3}
+\ProvidesExplPackage {jsonparse} {2025-01-30} {1.1.0}
   {A handy way to parse, store and access JSON data from files or strings in LaTeX documents}
 
 \msg_new:nnn { jsonparse } { old-kernel } {
@@ -125,6 +125,9 @@
 \str_new:N \l__jsonparse_carriage_return_str
 \str_new:N \l__jsonparse_horizontal_tab_str
 
+\tl_new:N \l__jsonparse_map_before_tl
+\tl_new:N \l__jsonparse_map_after_tl
+
 \clist_new:N \l__jsonparse_unused_keys_clist
 
 \clist_const:Nn \c__jsonparse_escape_tex_chars_clist {
@@ -165,13 +168,13 @@
   check ~ num                 .bool_set:N = \l__jsonparse_check_num_bool ,
   check ~ num                 .default:n  = { true } ,
   check ~ num                 .initial:n  = { true } ,
-  replace                     .code:n     = { \keys_set:nn { jsonparse / parse / replace } {#1} } ,
-  replace / true              .str_set:N  = \l__jsonparse_true_str ,
-  replace / true              .initial:n  = { true } ,
-  replace / false             .str_set:N  = \l__jsonparse_false_str ,
-  replace / false             .initial:n  = { false } ,
-  replace / null              .str_set:N  = \l__jsonparse_null_str ,
-  replace / null              .initial:n  = { null }
+  keyword                     .code:n     = { \keys_set:nn { jsonparse / parse / keyword } {#1} } ,
+  keyword / true              .str_set:N  = \l__jsonparse_true_str ,
+  keyword / true              .initial:n  = { true } ,
+  keyword / false             .str_set:N  = \l__jsonparse_false_str ,
+  keyword / false             .initial:n  = { false } ,
+  keyword / null              .str_set:N  = \l__jsonparse_null_str ,
+  keyword / null              .initial:n  = { null }
 }
 
 \keys_define:nn { jsonparse / typeset } {
@@ -233,7 +236,9 @@
   rescan                      .bool_set:N = \l__jsonparse_rescan_bool ,
   rescan                      .default:n  = { true } ,
   rescan                      .initial:n  = { true } ,
-  rescan                      .groups:n   = { output }
+  rescan                      .groups:n   = { output } ,
+  code ~ before               .tl_set:N   = \l__jsonparse_map_before_tl ,
+  code ~ after                .tl_set:N   = \l__jsonparse_map_after_tl
 }
 
 \cs_new_protected:Npn \__jsonparse_warning_unused_keys: {
@@ -1054,6 +1059,7 @@
     \prg_return_false:
   }
 }
+\prg_generate_conditional_variant:Nnn \jsonparse_unicode_if_high_surrogate:n { e } { p , T , F , TF }
 
 \prg_new_conditional:Npnn \jsonparse_unicode_if_low_surrogate:n #1 { p , T , F , TF } {
   \int_compare:nNnTF {#1} > { "DBFF } {
@@ -1066,10 +1072,12 @@
     \prg_return_false:
   }
 }
+\prg_generate_conditional_variant:Nnn \jsonparse_unicode_if_low_surrogate:n { e } { p , T , F , TF }
 
 \cs_new:Npn \jsonparse_unicode_convert_surrogate_pair:nn #1#2 {
   \int_eval:n { ( #1 - "D800 ) * "0400 + ( #2 - "DC00 ) + "10000 }
 }
+\cs_generate_variant:Nn \jsonparse_unicode_convert_surrogate_pair:nn { ee }
 
 \cs_new:Npn \__jsonparse_unicode_char:NNNNN #1#2#3#4#5 {
   \__jsonparse_unicode_char_aux:nNNNN { } #1#2#3#4
@@ -1082,13 +1090,14 @@
 
 \cs_new:Npn \__jsonparse_unicode_char_aux:nNNNN #1#2#3#4#5 {
   \tl_if_empty:nTF {#1} {
-    \exp_args:Ne \jsonparse_unicode_if_high_surrogate:nF { " \str_uppercase:n {#2#3#4#5} } {
+    \jsonparse_unicode_if_high_surrogate:eF { " \str_uppercase:n {#2#3#4#5} } {
       \exp_args:Ne \codepoint_generate:nn { " \str_uppercase:n {#2#3#4#5} } { 12 }
     }
   } {
-    \exp_args:Ne \jsonparse_unicode_if_low_surrogate:nTF { " \str_uppercase:n {#2#3#4#5} } {
+    \jsonparse_unicode_if_low_surrogate:eTF { " \str_uppercase:n {#2#3#4#5} } {
       \codepoint_generate:nn {
-        \exp_args:Nne \jsonparse_unicode_convert_surrogate_pair:nn {#1} { " \str_uppercase:n {#2#3#4#5} }
+        \jsonparse_unicode_convert_surrogate_pair:ee
+          { \str_uppercase:n {#1} } { " \str_uppercase:n {#2#3#4#5} }
       } { 12 }
     } {
       \exp_args:Ne \codepoint_generate:nn { " \str_uppercase:n {#2#3#4#5} } { 12 }
@@ -1274,7 +1283,7 @@
   \tl_set:NV #1 \l__jsonparse_array_count_int
 }
 
-\cs_new_protected:Npn \__jsonparse_array_values:n #1 {
+\cs_new_protected:Npn \__jsonparse_array_use:n #1 {
   \bool_if:NTF \l__jsonparse_prop_map_first_bool {
     \bool_set_false:N \l__jsonparse_prop_map_first_bool
   } {
@@ -1313,7 +1322,7 @@
   }
 }
 
-\NewDocumentCommand { \JSONParseArrayValues } { O{} m m O{} m } {
+\NewDocumentCommand { \JSONParseArrayUse } { O{} m m O{} m } {
   \__jsonparse_warning_undefined_prop:N #2
   \group_begin:
     \keys_set_known:nn { jsonparse / typeset } {#1} \l__jsonparse_unused_keys_clist
@@ -1325,15 +1334,19 @@
     \tl_set:Nn \l__jsonparse_array_values_insert_tl {#5}
     \bool_set_true:N \l__jsonparse_prop_map_first_bool
     \int_step_function:nN { \l__jsonparse_array_count_int }
-      \__jsonparse_array_values:n
+      \__jsonparse_array_use:n
   \group_end:
 }
 
+% backward compatibility
+\cs_set_eq:NN \JSONParseArrayValues \JSONParseArrayUse
+% ===
+
 \tl_new:N \JSONParseArrayIndex
 \tl_new:N \JSONParseArrayKey
 \tl_new:N \JSONParseArrayValue
 
-\cs_new_protected:Npn \__jsonparse_array_values_map_keys:n #1 {
+\cs_new_protected:Npn \__jsonparse_array_map_function_keys:n #1 {
   \int_incr:N \l__jsonparse_array_keys_index_int
   \tl_set:Ne \l__jsonparse_array_keys_index_roman_tl {
     \int_to_Roman:n { \l__jsonparse_array_keys_index_int }
@@ -1370,7 +1383,9 @@
   }
 }
 
-\cs_new_protected:Npn \__jsonparse_array_values_map:n #1 {
+\cs_new:Npn \__jsonparse_array_map_function_cs: { }
+
+\cs_new_protected:Npn \__jsonparse_array_map_function:n #1 {
   \bool_if:NTF \l__jsonparse_zero_based_bool {
     \tl_gset:Nn \JSONParseArrayIndex { \int_eval:n { #1 - 1 } }
   } {
@@ -1404,14 +1419,14 @@
   } {
     \int_zero:N \l__jsonparse_array_keys_index_int
     \clist_map_function:NN \l__jsonparse_array_map_keys_clist
-      \__jsonparse_array_values_map_keys:n
+      \__jsonparse_array_map_function_keys:n
     \tl_gset_eq:NN \JSONParseArrayKey \JSONParseArrayKeyI
     \tl_gset_eq:NN \JSONParseArrayValue \JSONParseArrayValueI
   }
-  \use:c { \l__jsonparse_array_map_function_str }
+  \__jsonparse_array_map_function_cs:
 }
 
-\cs_set_protected:Npn \__jsonparse_array_map_generate_cs:n #1 {
+\cs_set_protected:Npn \__jsonparse_array_map_function_generate_cs:n #1 {
   \int_incr:N \l__jsonparse_array_keys_index_int
   \tl_set:Ne \l__jsonparse_array_keys_index_roman_tl {
     \int_to_Roman:n { \l__jsonparse_array_keys_index_int }
@@ -1424,11 +1439,11 @@
   }
 }
 
-\NewDocumentCommand { \JSONParseArrayValuesMap } { O{} m m O{} m O{} O{} } {
+\NewDocumentCommand { \JSONParseArrayMapFunction } { O{} m m O{} m } {
   \__jsonparse_warning_undefined_prop:N #2
-  \cs_if_exist:cF {#5} {
+  \cs_if_exist:NF #5 {
     \msg_error:nne { jsonparse } { cs-undefined }
-      { \c_backslash_str #5 }
+      {#5}
   }
   \group_begin:
     \keys_set_known:nn { jsonparse / typeset } {#1} \l__jsonparse_unused_keys_clist
@@ -1437,19 +1452,29 @@
     \jsonparse_filter:Nn \l__jsonparse_temp_tl {#3}
     \jsonparse_array_count:NN \l__jsonparse_temp_tl \l__jsonparse_array_count_int
     \clist_set:Nn \l__jsonparse_array_map_keys_clist {#4}
-    \str_set:Nn \l__jsonparse_array_map_function_str {#5}
+    \cs_set_eq:NN \__jsonparse_array_map_function_cs: #5
     \clist_if_empty:NF \l__jsonparse_array_map_keys_clist {
       \int_zero:N \l__jsonparse_array_keys_index_int
       \clist_map_function:NN \l__jsonparse_array_map_keys_clist
-        \__jsonparse_array_map_generate_cs:n
+        \__jsonparse_array_map_function_generate_cs:n
     }
-    #6
+    \l__jsonparse_map_before_tl
     \int_step_function:nN { \l__jsonparse_array_count_int }
-      \__jsonparse_array_values_map:n
-    #7
+      \__jsonparse_array_map_function:n
+    \l__jsonparse_map_after_tl
   \group_end:
 }
 
+% backward compatibility
+\cs_new:Npn \__jsonparse_array_map_function_cs_compat: { }
+
+\NewDocumentCommand { \JSONParseArrayValuesMap } { O{} m m O{} m O{} O{} } {
+  \cs_set_eq:Nc \__jsonparse_array_map_function_cs_compat: {#5}
+  \JSONParseArrayMapFunction [ #1 , code ~ before = {#6} , code ~ after = {#7} ]
+    {#2} {#3} [#4] { \__jsonparse_array_map_function_cs_compat: }
+}
+% ===
+
 \cs_new:Npn \__jsonparse_array_map_inline:n #1 { }
 
 \NewDocumentCommand { \JSONParseArrayMapInline } { m m +m } {



More information about the tex-live-commits mailing list.