texlive[73549] Master/texmf-dist: jsonparse (21jan25)
commits+karl at tug.org
commits+karl at tug.org
Tue Jan 21 21:46:19 CET 2025
Revision: 73549
https://tug.org/svn/texlive?view=revision&revision=73549
Author: karl
Date: 2025-01-21 21:46:18 +0100 (Tue, 21 Jan 2025)
Log Message:
-----------
jsonparse (21jan25)
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-21 20:46:10 UTC (rev 73548)
+++ trunk/Master/texmf-dist/doc/latex/jsonparse/README.md 2025-01-21 20:46:18 UTC (rev 73549)
@@ -1,4 +1,4 @@
-
+

@@ -44,6 +44,8 @@
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.
+
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-21 20:46:10 UTC (rev 73548)
+++ trunk/Master/texmf-dist/doc/latex/jsonparse/jsonparse-doc.tex 2025-01-21 20:46:18 UTC (rev 73549)
@@ -11,8 +11,8 @@
% This work has the LPPL maintenance status `maintained'.
%
\documentclass[a4paper]{article}
-\def\jsonparsefileversion{1.0.0}
-\def\jsonparsefiledate{20 January 2025}
+\def\jsonparsefileversion{1.0.1}
+\def\jsonparsefiledate{21 January 2025}
\usepackage[T1]{fontenc}
\usepackage{Alegreya}
@@ -69,17 +69,19 @@
\NewDocumentCommand{\printchanges}{ }{
\section{Changes}
\begin{description}
- \int_step_inline:nn { \l_jsonparse_doc_change_int } {
- \item[
+ \setlength\itemsep{0pt}
+ \int_step_inline:nn { \l_jsonparse_doc_change_int } {
+ \item[
+ \prop_item:cn { l_jsonparse_doc_change_
+ \int_to_roman:n { ##1 } _prop } { version } ~
+ \normalfont{ (
+ \prop_item:cn { l_jsonparse_doc_change_
+ \int_to_roman:n { ##1 } _prop } { date }
+ ) }
+ ]
\prop_item:cn { l_jsonparse_doc_change_
- \int_to_roman:n { ##1 } _prop } { version }
- ] (
- \prop_item:cn { l_jsonparse_doc_change_
- \int_to_roman:n { ##1 } _prop } { date }
- ) \\
- \prop_item:cn { l_jsonparse_doc_change_
- \int_to_roman:n { ##1 } _prop } { changes }
- }
+ \int_to_roman:n { ##1 } _prop } { changes }
+ }
\end{description}
}
@@ -210,9 +212,10 @@
\changes{v0.9.7}{2024/11/05}{Streamlining of code, ensuring backward compatibility.}
\changes{v0.9.8}{2024/11/19}{Bug fixes; adding possibility to store value in token list.}
\changes{v0.9.10}{2024/12/10}{Enhanced backward compatibility; switching to linked property lists.}
-\changes{v0.9.11}{2025/01/15}{Bug fixes; adding additional command to loop over arrays.}
+\changes{v0.9.11}{2025/01/15}{Bug fixes; adding additional command to loop through arrays.}
\changes{v0.9.12}{2025/01/17}{Bug fixes; adding commands to access items in arrays.}
\changes{v1.0.0}{2025/01/20}{Streamlining of code, unification of command structure.}
+\changes{v1.0.1}{2025/01/21}{Fixes in documentation. Added user command for filtering.}
\begin{document}
\vspace*{-1cm}
@@ -258,7 +261,7 @@
\begin{macrodef}
|\x|{<token variable name>}{<key>}
\end{macrodef}
-Using the control sequence \macro{\x}, it is possible to nest JSON strings into each other. The control sequence takes two arguments delimited by curly braces. The first argument represents the name of the token variable that holds the parsed JSON data where the inserted JSON string should be taken from. The second argument sets the key that should be selected. The following example shows a simple use case:
+Using the control sequence \macro{\x}, it is possible to nest JSON strings into each other. Used inside the \macro{\JSONParse} command, the control sequence takes two arguments delimited by curly braces. The first argument represents the name of the token variable that holds the parsed JSON data where the inserted JSON string should be taken from. The second argument sets the key that should be selected. The following example shows a simple use case:
\begin{codeexamplecolumns}
\JSONParse{\myJSONdataA}{
@@ -272,7 +275,7 @@
\JSONParseValue{\myJSONdataB}{d.b}
\end{codeexamplecolumns}
-Note that the control sequence \macro{\x} is replaced by the value exactly. Therefore, if the value happens to be a string, the control sequence \macro{\x} should be placed between quotation marks (\macro{"}) in order for the resulting string to be valid JSON. The control sequence \macro{\x} is only available inside the \macro{\JSONParse} command, but not inside the \macro{\JSONParseFromFile} command.
+Note that the control sequence \macro{\x} is replaced by the value exactly. Therefore, if the value happens to be a string, the control sequence \macro{\x} should be placed between quotation marks (\macro{"}) in order for the resulting string to be valid JSON. The control sequence \macro{\x} is only available inside the \macro{\JSONParse} command, but not inside the \macro{\JSONParseFromFile} command.
\begin{macrodef}
|escape|={all}
@@ -289,7 +292,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{\JSONParseArrayItem}, \macro{\JSONParseArrayValues} as well as to the command \macro{\JSONParseArrayValuesMap}.
+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}.
\begin{macrodef}
|rescan|
@@ -297,7 +300,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{\JSONParseArrayItem}, \macro{\JSONParseArrayValues} as well as to the command \macro{\JSONParseArrayValuesMap}.
+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}.
\section{Main user commands}
@@ -326,7 +329,7 @@
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. When the option \macro{rescan} is used, the token list is rescanned before it is typeset (which means that all category codes that may have been changed before are set to the default values). This is the default behaviour. If rescanning is not desired, pass the option \macro{rescan=false} to the command.
-When a key is associated with an object or array, the whole object or array is output as JSON string. The special key \macro{.} (or the string defined using the key \macro{child sep}) returns the whole JSON object as string where all characters (except for spaces and tabs) have category code 12 (``other'').
+When a key is associated with an object or array, the whole object or array is output as JSON string. The special key \macro{.} (or the string defined using the key \macro{child sep}) returns the whole JSON object (or the whole JSON array if the JSON daza only cosists of one array) as string where all characters (except for spaces and tabs) have category code 12 (``other'').
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.
@@ -335,16 +338,16 @@
\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.
-For example, if the JSON string \macro{{ "key" : "value" }} has been parsed into the token variable \macro{\myJSONdata}, the command \macro{\JSONParseExpandableValue{\myJSONdata}{key}} will expand to the exact same token list as \macro{\detokenize{value}} with all characters having category code 12 (``other'').
+For example, if the JSON string \macro{{ "key" : "value" }} has been parsed into the token variable \macro{\myJSONdata}, the command \macro{\JSONParseExpandableValue{\myJSONdata}{key}} will have the same meaning as \macro{\detokenize{value}} and expand to a token list with all characters having category code 12 (``other'').
\begin{macrodef}
|\JSONParseSetValue|{<token variable>}{<token variable>}{<key>}
\end{macrodef}
-The command \macro{\JSONParseValueSet} can be used to a select a value from the token variable that stores the parsed JSON data via a key and store this value globally in another token variable.
+The command \macro{\JSONParseSetValue} can be used to a select a value from the token variable that stores the parsed JSON data via a key and store this value globally in another token variable.
The first argument denotes the token variable where the value should be stored into. If this token variable has not yet been defined, it will be created by this command. The second argument represents the token variable (property list) that has been created using the commands \macro{\JSONParse} or \macro{\JSONParseFromFile} and that stores the parsed JSON data. The third argument takes the key to select the relevant value.
-The token list returned by this command is a string variable where all characters have category code 12 (``other''), except for spaces and (horizontal) tabs that have category code 10 (``space'').
+The token list returned by this command is a string variable where all characters have category code 12 (``other''), except for spaces and (horizontal) tabs that have category code 10 (``space'').
\begin{macrodef}
|\JSONParseSetRescanValue|{<token variable>}{<token variable>}{<key>}
@@ -373,6 +376,11 @@
The command \macro{\JSONParseSetKeys} is used to get all top-level keys of a JSON object as JSON array and parse this array into a token variable (a property list). 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. The first argument takes the token variable to hold the JSON array containing the top-level keys of the selected object. The token variable to store the keys as array is created if it does not exist.
\begin{macrodef}
+|\JSONParseFilter|{<token variable>}{<token variable>}{<key>}
+\end{macrodef}
+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>}
\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.
@@ -589,7 +597,7 @@
\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 set using \macro{\JSONParseSet}. They can also be set locally as option to the commands \macro{\JSONParseValue}, \macro{\JSONParseArrayItem}, \macro{\JSONParseArrayValues} as well as to the command \macro{\JSONParseArrayValuesMap}.
+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}.
\begin{macrodef}
|check num|
@@ -612,9 +620,14 @@
The command \macro{\jsonparse_parse_to_prop:Nn} creates the token variable given as the first arguments as property list and, after having called \macro{\jsonparse_parse:n} using the second argument, sets this newly created property list equal to \macro{\g_jsonparse_entries_prop}. If escaping is activated, this command will pre-process the input according to the selected escaping mode before forwarding it to \macro{\jsonparse_parse:n}. See more on escaping above in section \ref{sec:escaping}.
\begin{macrodef}
+|\jsonparse_parse_keys:NN| <token variable> <string variable>
+\end{macrodef}
+The command \macro{\jsonparse_parse_keys:NN} processes the token variable given as the first arguments as property list and selects all top-level keys which are then stored in the string variable as JSON array. The pseudo key \macro{.} (or the string defined using the key \macro{child sep}) to select the complete JSON data is ignored. If the JSON data is an array, the indices (wrapped into the separators defined by \macro{separator/array left} and \macro{separator/array right}) of the items are used as keys.
+
+\begin{macrodef}
|\jsonparse_filter:Nn| <token variable> {<key>}
\end{macrodef}
-The command \macro{\jsonparse_parse_to_prop:Nn} processes the token variable given as the first arguments as property list and filters it according to the key given as second argument. Filtering means that for every entry in the property list, the key of this entry is compared against the key given to the command. If the key in the property list starts with the given key, the matching part is removed from the key in the property list. If the keys do not match, the entry is completely removed from the property list.
+The command \macro{\jsonparse_filter:Nn} processes the token variable given as the first arguments as property list and filters it according to the key given as second argument. Filtering means that for every entry in the property list, the key of this entry is compared against the key given to the command. If the key in the property list starts with the given key, the matching part is removed from the key in the property list. If the keys do not match, the entry is completely removed from the property list. If the second argument matches the pseudo key \macro{.} (or the string defined using the key \macro{child sep}) excactly, the complete property list except for this key is returned.
\begin{macrodef}
|\jsonparse_array_count:NN| <token variable> <integer variable>
Modified: trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty 2025-01-21 20:46:10 UTC (rev 73548)
+++ trunk/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty 2025-01-21 20:46:18 UTC (rev 73549)
@@ -10,7 +10,7 @@
%
% This work has the LPPL maintenance status `maintained'.
%
-\ProvidesExplPackage {jsonparse} {2025-01-20} {1.0.0}
+\ProvidesExplPackage {jsonparse} {2025-01-21} {1.0.1}
{A handy way to parse, store and access JSON data from files or strings in LaTeX documents}
\msg_new:nnn { jsonparse } { old-kernel } {
@@ -556,6 +556,17 @@
% ===
+\cs_new_protected:Npn \jsonparse_parse:n #1 {
+ \tl_set:Ne \l__jsonparse_input_tl { \tl_trim_spaces:e {#1} }
+ \cs_if_exist_use:cTF { __jsonparse_parse_ \str_head_ignore_spaces:o { \l__jsonparse_input_tl } :w } {
+ \l__jsonparse_input_tl \q_stop
+ } {
+ % other
+ \exp_last_unbraced:No
+ \__jsonparse_parse_other:w \l__jsonparse_input_tl \q_stop
+ }
+}
+
\cs_new_protected:Npn \jsonparse_parse_to_prop:Nn #1#2 {
\bool_if:NT \l__jsonparse_debug_mode_bool {
\msg_log:nne { jsonparse } { debug-info } {
@@ -573,17 +584,6 @@
}
}
-\cs_new_protected:Npn \jsonparse_parse:n #1 {
- \tl_set:Ne \l__jsonparse_input_tl { \tl_trim_spaces:e {#1} }
- \cs_if_exist_use:cTF { __jsonparse_parse_ \str_head_ignore_spaces:o { \l__jsonparse_input_tl } :w } {
- \l__jsonparse_input_tl \q_stop
- } {
- % other
- \exp_last_unbraced:No
- \__jsonparse_parse_other:w \l__jsonparse_input_tl \q_stop
- }
-}
-
% ===
\cs_new:cpn { __jsonparse_parse_ \c_left_brace_str :w } #1 \q_stop {
@@ -870,13 +870,35 @@
}
}
+\cs_new:Npn \__jsonparse_warning_undefined_prop:N #1 {
+ \prop_if_exist:NF #1 {
+ \msg_error:nnn { jsonparse } { prop-undefined }
+ {#1}
+ }
+}
+
\cs_new_protected:Npn \jsonparse_filter:Nn #1#2 {
\prop_clear:N \l__jsonparse_temp_prop
\str_set:Nn \l__jsonparse_filter_key_str {#2}
- \prop_map_function:NN #1 \__jsonparse_filter:nn
+ \str_if_eq:NNTF \l__jsonparse_filter_key_str \l__jsonparse_child_sep_str {
+ \prop_set_eq:NN \l__jsonparse_temp_prop #1
+ \prop_remove:Ne \l__jsonparse_temp_prop { \l__jsonparse_child_sep_str }
+ } {
+ \prop_map_function:NN #1 \__jsonparse_filter:nn
+ }
\prop_set_eq:NN #1 \l__jsonparse_temp_prop
}
+\NewDocumentCommand { \JSONParseFilter } { m m m } {
+ \__jsonparse_warning_undefined_prop:N #2
+ \group_begin:
+ \tl_set_eq:NN \l__jsonparse_temp_tl #2
+ \jsonparse_filter:Nn \l__jsonparse_temp_tl {#3}
+ \exp_last_unbraced:Nf
+ \group_end:
+ \tl_set:NV #1 \l__jsonparse_temp_tl
+}
+
% ===
\NewDocumentCommand { \JSONParsePut } { m m +v } {
@@ -1067,13 +1089,6 @@
}
\cs_generate_variant:Nn \__jsonparse_gset_rescan:Nn { Ne }
-\cs_new:Npn \__jsonparse_warning_undefined_prop:N #1 {
- \prop_if_exist:NF #1 {
- \msg_error:nnn { jsonparse } { prop-undefined }
- {#1}
- }
-}
-
\NewDocumentCommand { \JSONParseValue } { O{} m m } {
\__jsonparse_warning_undefined_prop:N #2
\group_begin:
@@ -1107,14 +1122,7 @@
\__jsonparse_gset_rescan:Ne #1 { \prop_item:Ne #2 {#3} }
}
-\cs_new:Npn \__jsonparse_parse_keys:NN #1#2 {
- \tl_set:Nn \l__jsonparse_keys_array_tl { [ }
- \prop_map_function:NN #1 \__jsonparse_parse_keys_aux:nn
- \tl_put_right:Nn \l__jsonparse_keys_array_tl { ] }
- \tl_set_eq:NN #2 \l__jsonparse_keys_array_tl
-}
-
-\cs_new:Npn \__jsonparse_parse_keys_aux:nn #1#2 {
+\cs_new:Npn \__jsonparse_parse_keys:nn #1#2 {
\tl_if_in:nVF {#1} \l__jsonparse_child_sep_str {
\bool_if:NTF \l__jsonparse_prop_map_first_bool {
\bool_set_false:N \l__jsonparse_prop_map_first_bool
@@ -1125,6 +1133,13 @@
}
}
+\cs_new_protected:Npn \jsonparse_parse_keys:NN #1#2 {
+ \tl_set:Nn \l__jsonparse_keys_array_tl { [ }
+ \prop_map_function:NN #1 \__jsonparse_parse_keys:nn
+ \tl_put_right:Nn \l__jsonparse_keys_array_tl { ] }
+ \tl_set_eq:NN #2 \l__jsonparse_keys_array_tl
+}
+
\NewDocumentCommand { \JSONParseKeys } { m m } {
\__jsonparse_warning_undefined_prop:N #1
\group_begin:
@@ -1131,7 +1146,7 @@
\tl_set_eq:NN \l__jsonparse_temp_tl #1
\jsonparse_filter:Nn \l__jsonparse_temp_tl {#2}
\bool_set_true:N \l__jsonparse_prop_map_first_bool
- \__jsonparse_parse_keys:NN \l__jsonparse_temp_tl \l__jsonparse_keys_tl
+ \jsonparse_parse_keys:NN \l__jsonparse_temp_tl \l__jsonparse_keys_tl
\tl_use:N \l__jsonparse_keys_tl
\group_end:
}
@@ -1145,7 +1160,7 @@
\tl_set_eq:NN \l__jsonparse_temp_tl #2
\jsonparse_filter:Nn \l__jsonparse_temp_tl {#3}
\bool_set_true:N \l__jsonparse_prop_map_first_bool
- \__jsonparse_parse_keys:NN \l__jsonparse_temp_tl \l__jsonparse_keys_tl
+ \jsonparse_parse_keys:NN \l__jsonparse_temp_tl \l__jsonparse_keys_tl
\exp_last_unbraced:Nf
\group_end:
\exp_args:NNe \jsonparse_parse_to_prop:Nn #1 { \l__jsonparse_keys_tl }
More information about the tex-live-commits
mailing list.