Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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.