Ask Your Question
0

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

asked 2020-02-07 07:26:49 +0100

sononicola gravatar image

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 flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2020-02-07 20:43:29 +0100

dsejas gravatar image

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.

edit flag offensive delete link more

Comments

Thankyou so much. This works perfectly

sononicola gravatar imagesononicola ( 2020-02-09 08:12:11 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2020-02-07 07:26:49 +0100

Seen: 591 times

Last updated: Feb 07 '20