diff options
author | Karl Berry <karl@freefriends.org> | 2024-04-26 21:26:55 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-04-26 21:26:55 +0000 |
commit | 252c4cb5c16dbe3af63150b6873a3e490ea995dc (patch) | |
tree | cd5ad41f824b831f6c4cb5f18b034545d6d60ccd /Master/texmf-dist/tex/latex | |
parent | cbd26dd674bcd61197d27c3dbf1722da270f78e0 (diff) |
jsonparse (26apr24)
git-svn-id: svn://tug.org/texlive/trunk@71088 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty | 229 |
1 files changed, 150 insertions, 79 deletions
diff --git a/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty b/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty index 447c70ae1b9..404e769ba74 100644 --- a/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty +++ b/Master/texmf-dist/tex/latex/jsonparse/jsonparse.sty @@ -10,7 +10,7 @@ % % This work has the LPPL maintenance status `maintained'. % -\ProvidesExplPackage {jsonparse} {2024-04-24} {0.8.0} +\ProvidesExplPackage {jsonparse} {2024-04-26} {0.8.2} {JSON Parse} \bool_new:N \l__jsonparse_debug_mode_bool @@ -41,11 +41,26 @@ Could ~ not ~ find ~ file ~ #1. } +\msg_new:nnn { jsonparse } { file-exists } { + \msg_error_text:n { jsonparse } \iow_newline: + File ~ #1 ~ already ~ existing. +} + \msg_new:nnn { jsonparse } { escape-in-key } { \msg_error_text:n { jsonparse } \iow_newline: Invalid ~ escape ~ sequence ~ #1 ~ in ~ key. } +\msg_new:nnn { jsonparse } { saving-external } { + \msg_info_text:n { jsonparse } \iow_newline: + Saving ~ external ~ file: ~ #1. +} + +\msg_new:nnn { jsonparse } { loading-external } { + \msg_info_text:n { jsonparse } \iow_newline: + Loading ~ from ~ external ~ file: ~ #1. +} + % === \str_new:N \l__jsonparse_child_sep_str @@ -106,20 +121,22 @@ \cs_generate_variant:Nn \tl_range:nnn { nne , nen } \cs_generate_variant:Nn \tl_range:Nnn { Nne , Nen } \cs_generate_variant:Nn \tl_remove_once:Nn { NV } +\cs_generate_variant:Nn \tl_replace_once:Nnn { Non } \cs_generate_variant:Nn \tl_rescan:nn { no , ne } \cs_generate_variant:Nn \tl_set:Nn { Ne } \cs_generate_variant:Nn \tl_trim_spaces:n { e } \cs_generate_variant:Nn \str_case_e:nn { en } -\cs_generate_variant:Nn \str_casefold:n { e } -\cs_generate_variant:Nn \str_head_ignore_spaces:n { e } +\cs_generate_variant:Nn \str_casefold:n { o } +\cs_generate_variant:Nn \str_head_ignore_spaces:n { o } \cs_generate_variant:Nn \prop_gput:Nnn { Nee } \cs_generate_variant:Nn \prop_item:Nn { Ne , ce } \cs_generate_variant:Nn \prop_put:Nnn { Nen , Nee } -\cs_generate_variant:Nn \msg_error:nnnn { nnee } +\cs_generate_variant:Nn \iow_now:Nn { Ne } +\cs_generate_variant:Nn \msg_error:nnnn { nnoo } \cs_generate_variant:Nn \msg_log:nnn { nne } \prg_generate_conditional_variant:Nnn \tl_if_eq:nn { en } { T } -\prg_generate_conditional_variant:Nnn \tl_if_head_eq_charcode:nN { eN } { T , TF } +\prg_generate_conditional_variant:Nnn \tl_if_head_eq_charcode:nN { oN } { T , TF } \prg_generate_conditional_variant:Nnn \tl_if_in:nn { nV } { F } \prg_generate_conditional_variant:Nnn \str_if_eq:nn { en , eV } { T , TF } @@ -141,8 +158,10 @@ \int_new:N \l__jsonparse_array_count_last_int \bool_new:N \l__jsonparse_prop_map_first_bool +\bool_new:N \l__jsonparse_load_external_bool \ior_new:N \l__jsonparse_json_ior +\iow_new:N \g__jsonparse_externalize_iow % === @@ -174,12 +193,12 @@ } \cs_new_protected:Npn \jsonparse_parse:n #1 { - \tl_set:Ne \l__jsonparse_input_tl { \tl_trim_spaces:n {#1} } - \cs_if_exist_use:cTF { __jsonparse_parse_ \str_head_ignore_spaces:e { \l__jsonparse_input_tl } :w } { + \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:Ne + \exp_last_unbraced:No \__jsonparse_parse_other:w \l__jsonparse_input_tl \q_stop } } @@ -187,30 +206,45 @@ % === \cs_new:cpn { __jsonparse_parse_ \c_left_brace_str :w } #1 \q_stop { - \exp_last_unbraced:Ne + \exp_last_unbraced:No \__jsonparse_parse_object_begin:w #1 \q_stop } \cs_new:cpn { __jsonparse_parse_ \c_right_brace_str :w } #1 \q_stop { - \exp_last_unbraced:Ne + \exp_last_unbraced:No \__jsonparse_parse_object_end:w #1 \q_stop } \cs_new:cpn { __jsonparse_parse_ [ :w } #1 \q_stop { - \exp_last_unbraced:Ne + \exp_last_unbraced:No \__jsonparse_parse_array_begin:w #1 \q_stop } \cs_new:cpn { __jsonparse_parse_ ] :w } #1 \q_stop { - \exp_last_unbraced:Ne + \exp_last_unbraced:No \__jsonparse_parse_array_end:w #1 \q_stop } \cs_new:cpn { __jsonparse_parse_ " :w } #1 \q_stop { - \exp_last_unbraced:Ne + \exp_last_unbraced:No \__jsonparse_parse_string_key:w #1 \q_stop } +\cs_new:Npn \__jsonparse_array_key_set: { + \str_if_eq:eVT { + \tl_range:Nen \l__jsonparse_prefix_tl { + \int_eval:n { + -1 * \tl_count:N \l__jsonparse_array_sep_left_str + } + } { -1 } + } \l__jsonparse_array_sep_left_str { + \int_incr:N \l__jsonparse_array_index_int + \tl_set:Ne \l__jsonparse_key_tl { + \l__jsonparse_prefix_tl \int_use:N \l__jsonparse_array_index_int \l__jsonparse_array_sep_right_str + } + } +} + \exp_last_unbraced:NNo \cs_new:Npn \__jsonparse_parse_object_begin:w \c_left_brace_str #1 \q_stop { \__jsonparse_array_key_set: \group_begin: @@ -305,26 +339,11 @@ \__jsonparse_parse_remainder: } -\cs_new:Npn \__jsonparse_array_key_set: { - \str_if_eq:eVT { - \tl_range:Nen \l__jsonparse_prefix_tl { - \int_eval:n { - -1 * \tl_count:N \l__jsonparse_array_sep_left_str - } - } { -1 } - } \l__jsonparse_array_sep_left_str { - \int_incr:N \l__jsonparse_array_index_int - \tl_set:Ne \l__jsonparse_key_tl { - \l__jsonparse_prefix_tl \int_use:N \l__jsonparse_array_index_int \l__jsonparse_array_sep_right_str - } - } -} - \cs_new:Npn \__jsonparse_parse_string_key:w " #1 " #2 \q_stop { \__jsonparse_array_key_set: \tl_set:Ne \l__jsonparse_remainder_tl { \tl_trim_spaces:n {#2} } % key or string? - \tl_if_head_eq_charcode:eNTF { \l__jsonparse_remainder_tl } : { + \tl_if_head_eq_charcode:oNTF { \l__jsonparse_remainder_tl } : { \tl_remove_once:NV \l__jsonparse_remainder_tl \c_colon_str \tl_set:Ne \l__jsonparse_key_tl { \l__jsonparse_prefix_tl #1 } } { @@ -347,17 +366,17 @@ \tl_set:Nn \l__jsonparse_remainder_tl {#1} \tl_set:Nn \l__jsonparse_temp_tl { #1 , } \tl_replace_once:Nnn \l__jsonparse_temp_tl { ] } { , } - \tl_replace_once:Nen \l__jsonparse_temp_tl { \c_right_brace_str } { , } - \exp_last_unbraced:Ne + \tl_replace_once:Non \l__jsonparse_temp_tl { \c_right_brace_str } { , } + \exp_last_unbraced:No \__jsonparse_parse_other_aux:w \l__jsonparse_temp_tl \q_stop } \cs_new:Npn \__jsonparse_parse_other_aux:w #1 , #2 \q_stop { \tl_set:Ne \l__jsonparse_temp_tl { \tl_trim_spaces:n {#1} } - \cs_if_exist_use:cF { __jsonparse_parse_ \str_casefold:e { \l__jsonparse_temp_tl } : } { + \cs_if_exist_use:cF { __jsonparse_parse_ \str_casefold:o { \l__jsonparse_temp_tl } : } { \fp_if_nan:nTF {#1} { % nan - \msg_error:nnee { jsonparse } { parsing-error } + \msg_error:nnoo { jsonparse } { parsing-error } { \l__jsonparse_key_tl } {#1} } { \tl_set:Nn \l__jsonparse_val_tl {#1} @@ -424,11 +443,11 @@ \cs_new:Npn \__jsonparse_parse_remainder: { \tl_set:Ne \l__jsonparse_remainder_tl { \tl_trim_spaces:e { \l__jsonparse_remainder_tl } } - \tl_if_head_eq_charcode:eNT { \l__jsonparse_remainder_tl } , { + \tl_if_head_eq_charcode:oNT { \l__jsonparse_remainder_tl } , { \tl_remove_once:Nn \l__jsonparse_remainder_tl { , } } \tl_if_empty:NF \l__jsonparse_remainder_tl { - \exp_args:Ne \jsonparse_parse:n { \l__jsonparse_remainder_tl } + \exp_args:No \jsonparse_parse:n { \l__jsonparse_remainder_tl } } } @@ -453,49 +472,102 @@ % === -\NewDocumentCommand { \JSONParse } { m +v } { - \tl_if_eq:enT { \tl_head:n {#2} } { \JSONParseValue } { - \msg_error:nn { jsonparse } { nested-non-expandable } +\NewDocumentCommand { \JSONParsePut } { m m +v } { + \prop_if_exist:NF #1 { + \prop_new:N #1 } - \prop_new:N #1 - \tl_gclear:N \g__jsonparse_json_tl - \group_begin: - \cs_set:Npn \" { \exp_not:N \" } - \cs_set:Npn \/ { \exp_not:N \/ } - \cs_set:Npn \\ { \exp_not:N \\ } - \cs_set:Npn \b { \exp_not:N \b } - \cs_set:Npn \f { \exp_not:N \f } - \cs_set:Npn \n { \exp_not:N \n } - \cs_set:Npn \r { \exp_not:N \r } - \cs_set:Npn \t { \exp_not:N \t } - \cs_set:Npn \u { \exp_not:N \u } - \cs_set:Npn \x [ ##1 ] [ ##2 ] { \prop_item:ce {##1} {##2} } - \tl_gset_rescan:Nne \g__jsonparse_json_tl { \cctab_select:N \c__jsonparse_json_escape_cctab } {#2} - \exp_args:NNe \jsonparse_parse_to_prop:Nn #1 { \g__jsonparse_json_tl } - \group_end: + \prop_gput:Nnn #1 { #2 } { #3 } } -\NewDocumentCommand { \JSONParseFromFile } { m m } { - \file_if_exist:nF {#2} { - \msg_error:nnn { jsonparse } { file-not-found } +\cs_new:Npn \__jsonparse_externalize:Nn #1#2 { + \file_if_exist:nTF {#2} { + \msg_error:nnn { jsonparse } { file-exists } + {#2} + } { + \iow_open:Nn \g__jsonparse_externalize_iow {#2} + \prop_map_inline:Nn #1 { + \iow_now:Nn \g__jsonparse_externalize_iow { + \JSONParsePut {#1} {##1} {##2} + } + } + \iow_close:N \g__jsonparse_externalize_iow + \msg_info:nnn { jsonparse } { saving-external } {#2} } - \prop_new:N #1 - \tl_gclear:N \g__jsonparse_json_tl - \group_begin: - \cs_set:Npn \" { \exp_not:N \" } - \cs_set:Npn \/ { \exp_not:N \/ } - \cs_set:Npn \\ { \exp_not:N \\ } - \cs_set:Npn \b { \exp_not:N \b } - \cs_set:Npn \f { \exp_not:N \f } - \cs_set:Npn \n { \exp_not:N \n } - \cs_set:Npn \r { \exp_not:N \r } - \cs_set:Npn \t { \exp_not:N \t } - \cs_set:Npn \u { \exp_not:N \u } - \cs_set:Npn \x [ ##1 ] [ ##2 ] { \prop_item:ce {##1} {##2} } - \file_get:nnN {#2} { \cctab_select:N \c__jsonparse_json_escape_cctab } \g__jsonparse_json_tl - \exp_args:NNe \jsonparse_parse_to_prop:Nn #1 { \g__jsonparse_json_tl } - \group_end: +} + +% === + +\NewDocumentCommand { \JSONParse } { o m +v } { + \bool_set_false:N \l__jsonparse_load_external_bool + \tl_if_novalue:nF {#1} { + \file_if_exist:nT { #1 .jsonparse } { + \bool_set_true:N \l__jsonparse_load_external_bool + } + } + \bool_if:NTF \l__jsonparse_load_external_bool { + \msg_info:nnn { jsonparse } { loading-external } + { #1 .jsonparse } + \file_input:n { #1 .jsonparse } + } { + \prop_new:N #2 + \tl_gclear:N \g__jsonparse_json_tl + \group_begin: + \cs_set:Npn \" { \exp_not:N \" } + \cs_set:Npn \/ { \exp_not:N \/ } + \cs_set:Npn \\ { \exp_not:N \\ } + \cs_set:Npn \b { \exp_not:N \b } + \cs_set:Npn \f { \exp_not:N \f } + \cs_set:Npn \n { \exp_not:N \n } + \cs_set:Npn \r { \exp_not:N \r } + \cs_set:Npn \t { \exp_not:N \t } + \cs_set:Npn \u { \exp_not:N \u } + \cs_set:Npn \x [ ##1 ] [ ##2 ] { \prop_item:ce {##1} {##2} } + \tl_gset_rescan:Nne \g__jsonparse_json_tl { \cctab_select:N \c__jsonparse_json_escape_cctab } {#3} + \exp_args:NNe \jsonparse_parse_to_prop:Nn #2 { \g__jsonparse_json_tl } + \group_end: + \tl_if_novalue:nF {#1} { + \__jsonparse_externalize:Nn #2 { #1 .jsonparse } + } + } +} + +\NewDocumentCommand { \JSONParseFromFile } { o m m } { + \file_if_exist:nF {#3} { + \msg_error:nnn { jsonparse } { file-not-found } + {#3} + } + \bool_set_false:N \l__jsonparse_load_external_bool + \tl_if_novalue:nF {#1} { + \file_if_exist:nT { #1 .jsonparse } { + \bool_set_true:N \l__jsonparse_load_external_bool + } + } + \bool_if:NTF \l__jsonparse_load_external_bool { + \msg_info:nnn { jsonparse } { loading-external } + { #1 .jsonparse } + \file_input:n { #1 .jsonparse } + } { + \prop_new:N #2 + \tl_gclear:N \g__jsonparse_json_tl + \group_begin: + \cs_set:Npn \" { \exp_not:N \" } + \cs_set:Npn \/ { \exp_not:N \/ } + \cs_set:Npn \\ { \exp_not:N \\ } + \cs_set:Npn \b { \exp_not:N \b } + \cs_set:Npn \f { \exp_not:N \f } + \cs_set:Npn \n { \exp_not:N \n } + \cs_set:Npn \r { \exp_not:N \r } + \cs_set:Npn \t { \exp_not:N \t } + \cs_set:Npn \u { \exp_not:N \u } + \cs_set:Npn \x [ ##1 ] [ ##2 ] { \prop_item:ce {##1} {##2} } + \file_get:nnN {#3} { \cctab_select:N \c__jsonparse_json_escape_cctab } \g__jsonparse_json_tl + \exp_args:NNe \jsonparse_parse_to_prop:Nn #2 { \g__jsonparse_json_tl } + \group_end: + \tl_if_novalue:nF {#1} { + \__jsonparse_externalize:Nn #2 { #1 .jsonparse } + } + } } \NewExpandableDocumentCommand { \JSONParseExpandableValue } { m m } { @@ -517,9 +589,8 @@ \cs_set:Npn \t { \l__jsonparse_horizontal_tab_str } \cs_set:Npn \u { \char" } \tl_set:Ne \l__jsonparse_temp_tl {#1} - \tl_analysis_log:N \l__jsonparse_temp_tl - \cs_set:Npn \" { \__jsonparse_tex_quote } - \cs_set:Npn \\ { \__jsonparse_tex_backslash } + \cs_set_eq:NN \" \__jsonparse_tex_quote + \cs_set_eq:NN \\ \__jsonparse_tex_backslash \tl_rescan:no { } { \l__jsonparse_temp_tl } \group_end: } @@ -528,7 +599,7 @@ \bool_if:NTF #1 { \prop_item:Ne #2 {#3} } { - \__jsonparse_rescan:n { \prop_item:Ne #2 {#3} } + \exp_args:Ne \__jsonparse_rescan:n { \prop_item:Ne #2 {#3} } } } @@ -608,11 +679,11 @@ } {#4} { \int_incr:N \l__jsonparse_array_index_int \tl_set:Ne \JSONParseArrayIndex { \__jsonparse_get_array_index:w ##1 \q_stop } - \tl_set:Ne \JSONParseArrayKey {##1} + \tl_set:Nn \JSONParseArrayKey {##1} \bool_if:NTF #1 { \tl_set:Nn \JSONParseArrayValue { \prop_item:Nn #2 {##1} } } { - \tl_set:Nn \JSONParseArrayValue { \__jsonparse_rescan:n { \prop_item:Nn #2 {##1} } } + \tl_set:Nn \JSONParseArrayValue { \exp_args:Ne \__jsonparse_rescan:n { \prop_item:Nn #2 {##1} } } } \use:c {#5} } |