Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
151 lines (135 sloc) 4.51 KB
\RequirePackage{expl3}
\ProvidesExplPackage
{jsonlite}{2016/12/24}{0.1}{Read JSON structure}
\RequirePackage{xparse}
\cs_set_nopar:Npn \exp_args:NNff { \::N \::f \::f \::: }
\cs_set_nopar:Npn \exp_args:NNfff { \::N \::f \::f \::f \::: }
\cs_set_nopar:Npn \exp_args:NNNff { \::N \::N \::f \::f \::: }
\cs_set_nopar:Npn \exp_args:NNffff { \::N \::f \::f \::f \::f \::: }
\cs_set_nopar:Npn \exp_args:NNNfff { \::N \::N \::f \::f \::f \::: }
\cs_set_nopar:Npn \exp_args:NNcfff { \::N \::c \::f \::f \::f \::: }
\cs_new:Npn \inside_name:Nnn #1#2#3 {
% #1 is a proplist
\tl_set:Nn \name { #2 }
\tl_set:Nf \car_input { \tl_head:n { #3 } }
\tl_set:Nf \cdr_input { \tl_tail:n { #3 } }
\tl_if_head_is_group:nTF { #3 }
{
\exp_args:NNff \inside_name:Nnn #1 {} { \car_input \relax \cdr_input }
}
{ \tl_if_head_eq_charcode:nNTF { #3 } { : }
{
\exp_args:NNfff \inside_val:Nnnn #1 {} { \name } \cdr_input
}
{
\tl_set:Nx \app_name { \name\car_input }
\exp_args:NNff \inside_name:Nnn #1 { \app_name } { \cdr_input }
}
}
}
\cs_new:Npn \inside_val:Nnnn #1#2#3#4 {
% #1 is a proplist
\tl_set:Nn \val { #2 }
\tl_set:Nn \name { #3 }
\tl_set:Nf \car_input { \tl_head:n { #4 } }
\tl_set:Nf \cdr_input { \tl_tail:n { #4 } }
\tl_if_head_is_group:nTF { #4 }
{
\exp_args:NNfff \inside_val:Nnnn #1 { \car_input } { \name } { \cdr_input }
}
{ \tl_if_head_eq_charcode:nNTF { #4 } { , }
{
\exp_args:NNff \add_key_val:Nnn #1 { \name } { \val }
\exp_args:NNff \inside_name:Nnn #1 {} { \cdr_input }
}
{ \tl_if_head_eq_charcode:nNTF { #4 } { [ }
{
\cs_if_exist:cTF { seq_\name }
{\cs_undefine:c { seq_\name }}
{}
\seq_new:c { seq_\name }
\exp_args:NNcfff \inside_array:Nnnnn #1 { seq_\name } {} { \name } { \cdr_input }
}
{ \tl_if_head_eq_charcode:nNTF { #4 } { " }
{
\exp_args:NNf \inside_string #1 { \name } #4
}
{ \tl_if_head_eq_meaning:nNTF { #4 } { \relax }
{
\exp_args:NNff \add_key_val:Nnn #1 { \name } { \val }
}
{
\tl_set:Nx \app_val { \val\car_input }
\exp_args:NNfff \inside_val:Nnnn #1 { \app_val } { \name } { \cdr_input }
}
}
}
}
}
}
% No double quotation within a string
\cs_new:Npn \inside_string #1#2"#3"#4\relax {
% #1 is a control sequence for a proplist
\tl_set:Nn \name { #2 }
\tl_set:Nn \jsonstr { \tl_to_str:n { #3 } }
\exp_args:NNNff \inside_val:Nnnn #1 \jsonstr { \name } { #4\relax }
}
% returns the seqence name as string, since proplist is able to hold only text
\cs_new:Npn \inside_array:Nnnnn #1#2#3#4#5 {
% #1 is a proplist
% #2 is a sequence
\tl_set:Nn \array_item { #3 }
\tl_set:Nn \name { #4 }
\tl_set:Nf \car_input { \tl_head:n { #5 } }
\tl_set:Nf \cdr_input { \tl_tail:n { #5 } }
\tl_if_head_is_group:nTF { #4 }
{
\exp_args:NNNfff \inside_array:Nnnnn #1 #2 { \car_input } { \name } { \cdr_input }
}
{ \tl_if_head_eq_charcode:nNTF { #5 } { ] }
{
\add_array_item:Nn #2 { \array_item }
\exp_args:NNfff \inside_val:Nnnn #1 { \cs_to_str:N #2 } { \name } { \cdr_input }
}
{ \tl_if_head_eq_charcode:nNTF { #5 } { , }
{
\add_array_item:Nn #2 { \array_item }
\exp_args:NNNfff \inside_array:Nnnnn #1 #2 {} { \name } { \cdr_input }
}
{
\exp_args:NNNfff \inside_array:Nnnnn #1 #2 { \array_item\car_input } { \name } { \cdr_input }
}
}
}
}
\cs_new:Npn \add_array_item:Nn #1#2 {
\exp_args:NNf \seq_put_right:Nn #1 { #2 }
}
\cs_new:Npn \add_key_val:Nnn #1#2#3 {
\exp_args:NNff \prop_put:Nnn #1 { #2 } { #3 }
}
\msg_new:nnn { jsonlite } { overwritten } { Proplist~\string#1~is~overwriten. }
\NewDocumentCommand{\readJson}{ m m }
{
\cs_if_exist:NTF #1
{
\cs_undefine:N #1
% \msg_warning:nnn { jsonlite } { overwritten } { #1 }
}
{ }
\prop_new:N #1
\tl_set:Nn \cdr_input { \tl_tail:n { #2 } }
\exp_args:NNff \inside_name:Nnn #1 {} { #2 }
}
\NewDocumentCommand{\readJsonValueById}{ m m m }
{
\cs_if_exist:NTF #1
{
\cs_undefine:N #1
% \msg_warning:nnn { jsonlite } { overwritten } { #1 }
}
{ }
\prop_get:NnN #2 { #3 } #1
}
\NewDocumentCommand{\showJsonValueById}{ m m }
{ \prop_item:Nn #1 { #2 } }