Loading [MathJax]/jax/output/HTML-CSS/jax.js
Ask Your Question
0

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

asked 5 years ago

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

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
2

answered 5 years ago

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 21km2 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.

Preview: (hide)
link

Comments

Thankyou so much. This works perfectly

sononicola gravatar imagesononicola ( 5 years ago )

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: 5 years ago

Seen: 646 times

Last updated: Feb 07 '20