1

I know that \fp_new_variable:n ⟨identifier⟩ must consist entirely of Latin letters from [a-zA-Z]. In the \setvar command below, I want to replace any numbers or underscores in the parameter #1 before using it, for example, convert h_2 to hUnderscoreTwo, and then let \fp_set_variable uses it. However, \fp_set_variable:nn doesn't seem to expand #1. Is there any way to achieve this?

\documentclass[12pt]{article}
\ExplSyntaxOn
\seq_new:N \g__xcn_var_list_seq
\NewDocumentCommand{\setvar}{mm}
{
 \seq_if_in:NnF \g__xcn_var_list_seq {#1 }
 {
 \fp_new_variable:n {#1}
 \seq_gput_left:Nn \g__xcn_var_list_seq {#1}
 } 
 \fp_set_variable:nn {#1} {#2} 
}
\NewExpandableDocumentCommand{\usevar}{O{15}m}
{ 
 \fp_eval:n { round( #2 , #1 ) }
}
\ExplSyntaxOff
\begin{document}
\setvar{h}{600 * 2}
\usevar{h}
%\setvar{h_2}{600 * 2} \usevar{h_2}
\end{document}
asked 2 days ago
8
  • 1
    as always in expl3, given However, \fp_set_variable:nn doesn't seem to expand #1 you could use (or declare if necessary) an \fp_set_variable:en that does expand #1 Commented 2 days ago
  • 1
    you can use l3regex to do the replacement in combination with the variant @DavidCarlisle mentioned. or use \exp_args:N.... Commented 2 days ago
  • 1
    I don't think you should delete your question. but I think it would be better to start from one of the answers which does what you want and ask e.g. whether the syntax can be modified in whichever way you need. your question did not say why you didn't want to use the expandable answers, so it just seemed weird to be asking how to change my answer to do what the other answers already gave you. Commented 2 days ago
  • @cfr yes. You're right. Now I restore it if I could find it. Commented 2 days ago
  • 1
    @cfr yes, I have solved that. Commented yesterday

3 Answers 3

2

You can do it by associating to the "external" name a "purified" internal one. But this will be much slower, mind you.

\documentclass[12pt]{article}
\ExplSyntaxOn
\prop_new:N \g__xcn_var_list_prop
\tl_new:N \l__xcn_var_purified_tl
\NewDocumentCommand{\setvar}{mm}
 {
 \__xcn_var_purify:n {#1}
 \prop_if_in:NnF \g__xcn_var_list_prop {#1 }
 {
 \exp_args:NV \fp_new_variable:n \l__xcn_var_purified_tl
 \prop_gput:NnV \g__xcn_var_list_prop {#1} \l__xcn_var_purified_tl
 }
 \exp_args:NV \fp_set_variable:nn \l__xcn_var_purified_tl {#2} 
 }
\NewExpandableDocumentCommand{\usevar}{O{15}m}
 { 
 \fp_eval:n { round( \prop_item:Nn \g__xcn_var_list_prop {#2} , #1 ) }
 }
\cs_new_protected:Nn \__xcn_var_purify:n
 {
 \tl_set:Nn \l__xcn_var_purified_tl {#1}
 \exp_args:NNe \tl_replace_all:Nnn \l__xcn_var_purified_tl
 { \char_generate:nn { `_ } {8} } % underscore
 { underscore }
 \regex_replace_all:nnN { ([0-9]+) } { \c{int_to_roman:n} {1円} } \l__xcn_var_purified_tl
 \tl_set:Ne \l__xcn_var_purified_tl { \l__xcn_var_purified_tl }
 }
\ExplSyntaxOff
\begin{document}
\setvar{h}{600 * 2}
\usevar{h}
\setvar{h_2}{600 * 2} \usevar{h_2}
\setvar{h_2}{2*pi} \usevar{h_2}
\fpeval{\usevar{h_2}/2}
\end{document}

output

answered 2 days ago
3
  • Can the syntax be modified so that I can use variable directly? such as use \setvar{h_c}{600 * 2 + h_b} instead if \setvar{h_c}{600 * 2 + \usevar{h_b} } . Commented 2 days ago
  • @xcn NO, it’s not possible, because variables cannot have names containing nonletters. Commented 2 days ago
  • it’s possible if change your answer a little. Commented yesterday
4

In OpTeX, we can use \expr macro:

\mathinexpr
\def\_decdigits{15}
\def\setvar#1#2{\directlua{#1 = #2}}
\def\usevar#1{\nnum{\expr{#1}}}
\setvar{h}{600 * 2}
\usevar{h}
\setvar{h_2}{600 * 2} \usevar{h_2}
\setvar{h_2}{2*pi} \usevar{h_2}
\usevar{h_2/2}
\bye

The result is the same as in the egreg's answer.

answered 2 days ago
2
  • How to use Optex? I can't find Optex Compiler in Texworks editor. Commented yesterday
  • I don't know what Texworks editor is. If you are unable to find OpTeX in the editor menu then it is problem of this editor. TeXlive and MikTeX include OpTeX (you can use command line with optex command). Commented 21 hours ago
0

This modified answer allows to use understore in argument #2 of \setvar command.

\documentclass[12pt]{article}
\ExplSyntaxOn
\prop_new:N \g__xcn_var_list_prop
\tl_new:N \l__xcn_var_purified_tl
\tl_new:N \l__xcn_var_purifiedeq_tl
\NewDocumentCommand{\setvar}{mm}
 {
 \__xcn_var_purify:n {#1}
 \prop_if_in:NnF \g__xcn_var_list_prop {#1 }
 {
 \exp_args:NV \fp_new_variable:n \l__xcn_var_purified_tl
 \prop_gput:NnV \g__xcn_var_list_prop {#1} \l__xcn_var_purified_tl
 }
 \tl_set_eq:NN \l__xcn_var_purifiedeq_tl \l__xcn_var_purified_tl 
 \__xcn_var_purify:n {#2}
 \exp_args:NV \fp_set_variable:nn \l__xcn_var_purifiedeq_tl \l__xcn_var_purified_tl 
 }
\NewExpandableDocumentCommand{\usevar}{O{15}m}
 { 
 \fp_eval:n { round( \prop_item:Nn \g__xcn_var_list_prop {#2} , #1 ) }
 }
\cs_new_protected:Nn \__xcn_var_purify:n
 {
 \tl_set:Nn \l__xcn_var_purified_tl {#1}
 \exp_args:NNe \tl_replace_all:Nnn \l__xcn_var_purified_tl
 { \char_generate:nn { `_ } {8} } % underscore
 { U }
 %\regex_replace_all:nnN { ([0-9]+) } { \c{int_to_roman:n} {1円} } \l__xcn_var_purified_tl
 \tl_set:Ne \l__xcn_var_purified_tl { \l__xcn_var_purified_tl }
 }
\ExplSyntaxOff
\begin{document}
\setvar{h_a}{600 * 2}
\usevar{h_a}
\fpeval{\usevar{h_a}/2}
\setvar{h_b}{3.14+h_a}
\usevar{h_b}
\end{document}
answered yesterday

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.