# siunitx comand \SI{number}{units} with sagetex

I'm trying to create something more like the command \SI{number}{units} of siunitx package but I have some trouble. Reading the PythonTex documentation this problem doesn't exist.

Starting with the answer /#49745

\begin{sagesilent}
def SIsage(number,units=0):
if units==0:
if number in ZZ or number.parent()==QQ:
return r"\SI{"+ str(number) + "}"
else:
return r"\SI{"+ str(float(number)) + "}"
else:
if number in ZZ or number.parent()==QQ:
return r"\SI{"+ str(number) + "}" +"{"+ units + "}"
else:
return r"\SI{"+ str(float(number)) + "}" +"{"+ units + "}"
\end{sagesilent}
\sagestr{SIsage(2442,"\kilo\metre\squared")}
\sagestr{SIsage(2442)}


and it works except when using \newton witch it become "ewton" problably cause to \n

After this I want to create a new custom LaTeX command that replace \SI{}{} but I have some trouble with non-default arguments. I didn't understand how them work. I want be able to use both of \SI{number}{units} that \SI{number} without units. Probably the best choise is to create two different commands(?)

\newcommand{\SIsage_units}[1]{,"#1"}
\newcommand{\SIsage_number}[1]{\sagestr{SIsage(#1}}
\newcommand{\SISAGE}[2]{\SIsage_number{#2}\SIsage_units{#1})} #doesn't work


The command I want:

\SISAGE{21}{\kilo\metre\squared}
\SISAGE{26}{}


So my problems are:

1. how to avoid \n
2. how to set an unic custom command \SISAGE

Thanks everybody

edit retag close merge delete

Sort by » oldest newest most voted

Hello, @sononicola! Let me answer your questions one by one:

1. How to avoid \n: When you write

\sagestr{SIsage(2442,"\kilo\metre\squared")}


Sage considers the \k, \m, \s, and every character with a backslash as a escaped character for formatting. In particular, \n means new line, and that is why \newton shows only ewton following a blank line. I imagine you are getting a warning message like

<input>:1: DeprecationWarning: invalid escape sequence \k
<input>:1: DeprecationWarning: invalid escape sequence \k
<input>:1: DeprecationWarning: invalid escape sequence \k
<ipython-input-3-de7d74516408>:1: DeprecationWarning: invalid escape sequence \k
SIsage(Integer(2442),"\kilo\metre\squared")
'\\SI{2442}{\\kilo\\metre\\squared}'


If you are using Sage-9.0 or superior.

In order to avoid this behavior, you can escape the escape character. For example, \sagestr{SIsage(2442,"\\kilo\\metre\\squared")}, and also \\newton. However, there is a more elegant solution: you can use raw strings, which are strings that Python (and Sage) write AS THEY ARE, without formatting them. You just have to write an r before the string. For example, \sagestr{SIsage(2442,r"\kilo\metre\squared")} or r"\newton".

2. How to set an unique custom command \SISAGE You can define the following LaTeX command:

\newcommand\sisage[2]{\sagestr{SIsage(#1, r"#2")}}


This should work like this:

\sisage{21}{\kilo\meter\squared}
\sisage{26}{}


should return $21\,\text{km}^2$ and $26$, respectively.

That should solve your problems. However, let me give you one additional advise. Your definition of SIsage can be more efficient. In particular, you can eliminate the external if-then-else:

\begin{sagesilent}
def SIsage(number,units=""):
if number in ZZ or number.parent()==QQ:
return r"\SI{"+ str(number) + "}" +"{"+ units + "}"
else:
return r"\SI{"+ str(float(number)) + "}" +"{"+ units + "}"
\end{sagesilent}


Another quite interesting thing you can do is define \sisage to take the units argument as optional argument. This is going to be a little technical, and you should ignore it if you're not that experienced with LaTeX. I am putting this here for anyone who has a similar problem.

One alternative is to write in the preamble of your document (before \begin{document}):

\newcommand\sisage[2][]{\sagestr{SIsage(#2, r"#1")}}


This will allow you to write something like:

\sisage[\kilo\meter\squared]{21}
\sisage{26}


That is, the units argument is now optional, but it should be specified as first argument.

The second alternative is to write in your preamble:

\makeatletter
\def\sisage#1{%
\@ifnextchar[{\@sisage{#1}}{\@sisage{#1}[]}%
}
\def\@sisage#1[#2]{%
\sagestr{SIsage(#1, r"#2")}%
}
\makeatother


This will allow you to write something like:

\sisage{21}[\kilo\meter\squared]
\sisage{26}


That is, the units argument is also optional, but it can now be specified as the second argument.

I hope this helps! Feel free to write me a comment if you have some additional question.

more

Thankyou so much. This works perfectly

( 2020-02-09 01:12:11 -0600 )edit