Inspired by a question yesterday, I thought I'd try my hand at a LaTeX3 solution which would show how to convert base 10 numbers into any other base of the user's choice.
Yesterday I wrote a nice simple version that worked. But today, I decided I wanted to separate the building of the steps from the process of outputting and formatting those steps. I also thought it would be interesting to explore the possibilities of creating the effect of an array within an array using sequences and token lists.
But now, I'm getting an error.
\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{xparse}
\pagestyle{empty}
\ExplSyntaxOn
%% setting and getting the base
\int_new:N \g__new_base_int
\NewDocumentCommand{\setbase}{ m }{
\int_gset:Nn \g__new_base_int { #1 }
}
\NewDocumentCommand{\getbase}{}{
\int_use:N \g__new_base_int
}
%% setting and getting the number to be converted
\int_new:N \g__number_to_convert_int
\NewDocumentCommand{\setnumber}{ m }{
\int_gset:Nn \g__number_to_convert_int {#1}
}
\NewDocumentCommand{\getnumber}{ }{
\int_use:N \g__number_to_convert_int
}
%%---internal function to build each step in the conversion process
%%---and the parameters to be used for this function
\int_new:N \l__quotient_int
\int_new:N \l__tmp_new_quotient_int
\int_new:N \l__remainder_int
\seq_new:N \g__steps_of_conversion
\cs_new:Nn \__build_steps_of_conversion: {
\int_set_eq:NN \l__quotient_int \g__number_to_convert_int
\int_do_while:nn { \l__quotient_int >= \g__new_base_int }
{
\int_set:Nn \l__remainder_int { \int_mod:nn { \l__quotient_int } { \g__new_base_int } }
\int_set:Nn \l__tmp_new_quotient_int { \int_div_truncate:nn { \l__quotient_int } {\g__new_base_int }}
\exp_args:NNx \seq_gput_right:Nn \g__steps_of_conversion
{
{\int_use:N \g__new_base_int }
{\int_use:N \l__quotient_int }
{\int_use:N \l__remainder_int }
{\int_use:N \l__tmp_new_quotient_int}
}
\int_set_eq:NN \l__quotient_int \l__tmp_new_quotient_int
}
}
%%---internal function to construct the display of the conversion process
\bool_new:N \l__first_item_on_line_bool
\cs_new:Nn \__show_steps_of_conversion: {
\__build_steps_of_conversion:
\seq_map_inline:Nn \g__steps_of_conversion
{
\bool_set_true:N \l__first_item_on_line_bool
\tl_map_inline:nn { ##1 } {
\bool_if:NF \l__first_item_on_line_bool { & }
###1
\bool_set_false:N \l__first_item_on_line_bool
}
\\
}
}
%%---user interface to displaying the conversion
\NewDocumentCommand{\showstepsofconversion}{ o }{
\[
\begin{array}{crc|r}
\text{Base} & & \text{R} & \text{Q} \\\hline
\__show_steps_of_conversion:
\end{array}
\]
}
%% accessing and using LaTeX3's internal base conversion
\NewDocumentCommand{\converttobase}{m}{
\int_to_base:nn {#1} \g__new_base_int
}
%%
\ExplSyntaxOff
\setlength{\parindent}{0pt}
\setbase{21}
\setnumber{2680010}
\begin{document}
The base is \getbase. \getnumber{} becomes $\converttobase{\getnumber}_{\getbase}$.
\showstepsofconversion
\end{document}
The problem seems to be ###1. Oddly, the output is as I desire. The suggested correction to ##1 is clearly not correct and when I rewrite my code to ##1 I get the wrong value.
#must be doubled, so I guess you need####1. – egreg Feb 02 '13 at 16:30expl3code should always be set up in a defined namespace. So here you might have\showbaseconv_...as the function prefix, and therefore\l_showbaseconv_...for a local variable, etc. – Joseph Wright Feb 02 '13 at 16:33#. – Joseph Wright Feb 02 '13 at 16:33#1TeX substitutes the first argument; when it contains##it substitutes#. (This is not the complete truth, but a good approximation.) – egreg Feb 02 '13 at 16:34###1 not parsing correctly– A.Ellett Feb 02 '13 at 16:38#already eg http://tex.stackexchange.com/questions/71632/why-do-paramaters-of-renewcommand-need-to-double-up-the-within-a-foreach/ – David Carlisle Feb 02 '13 at 16:42expl3concepts guide. The bottom line is TeX does not have a namespace system (and even if it did you'd still need to manage the module names). The formalised approach inexpl3is pretty much the same as good practice for LaTeX2e packages, where many packages use\foo@...in names. If you want more on this, probably best to ask on in chat or on LaTeX-L as it's likely to be a discussion. – Joseph Wright Feb 02 '13 at 16:49