Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Recently me and some friends really got into "making everything compilable". More specifically, we need to do a lot of matlab calculations, and then we need to put the results into a tex document.

I've had some time left recently and decided to write a matlab script to output values and their uncertainty bounds to a file, in correct the correct form so they can be a called in LaTeX, with the correct number of significant digits and whatnot everything so no brains are needed. Let me show you an example:

1) I have a matlab script do.m that uses data form input files, processes it and calculates what I want, say values that are stored in a and b.

2) at the end of the script I call my savefortex script that saves variables a and b to a file, say out.txt, which will look like this:

 \def\a{123}
 \def\b{456}

3) I put \input{out.txt} in my LaTeX document.

4) I setup my makefile so that it knows do.m should be called to have the latest out.txt.

This is very handy when it comas down to a large number of variables that have to be inputted. Recently I stumbled into a problem though. I usually name my variables an their corresponding uncertainty bound as follows: a, s_a, b, s_b, etc. Yet this is not compatible with Tex. Try this at home

\def\s_a{10}
\def\s_b{20}
\s_a and \s_b.

It simply won't work. The same goes for a1, a2, etc. Yet something like:

\def\s_a{10}
\s_a

does work! It seems as if tex doesn't allow for multiple macro's that have an underscore to have the same text before the underscore, even if the text after the underscore is different (again, this is the same with numbers in the macro names). So whilst s_a and s_b are okay to use separately, if they are both defined tex cannot use either of them!

What would be a good solution to this? Any suggestions for a different naming scheme? Or perhaps there's another way to get data from a file (this would be nice, since input takes a lot of time when there are a lot of macro's defined)?

I would also like to be able to use siunitx, so while \SI{\a+-\b}{\metre} works, \SI{\a+-\s_a}{\metre} does not. I would love it if it did.

share|improve this question
2  
matlab has a latex command to output directly LaTex Content. It is in the symbolic toolbox. –  someonr Jan 4 '12 at 16:53
    
You can force latex to accept the _, by useing \catcode`_=11 before the new commands. But this is in general a bad idea, better use another naming sheme –  someonr Jan 4 '12 at 17:00
    
Short answer: don't put underscores (or anything else that isn't a letter) in a macro name. –  Seamus Jan 4 '12 at 17:02
    
@seamus, yeah thats what I doing now, but I was wondering if there was a more elegant solution (as in, my computer does what I want, not the other way around). –  romeovs Jan 4 '12 at 17:04
    
@someonr not quite what I need, I just save numbers, not mathematical symbolic expressions. –  romeovs Jan 4 '12 at 17:04

4 Answers 4

up vote 11 down vote accepted

There are two problems: the first is that after

\def\sa{10}
\def\sb{20}

the text \sa and \sb will render as

10and 20

because TeX ignores spaces after control words.

Second problem. A control sequence can consist either of

  1. only one non alphabetic character (control symbols); or
  2. a string of one or more alphabetic characters, that is [A-Za-z] (control words)

Spaces are not ignored after control symbols.

However definitions with \def allow for a fairly general syntax:

\def\cs<parameter text>{<replacement text>}

Here <parameter text> can be whatever sequence of tokens, including the argument indicators #1 to #9 to denote arguments. But if there are tokens different from the argument indicators, they must appear after \cs. So

\def\s_a{10}

is legal and defines a command \s which requires the two tokens _a to follow it. If you say after this

\def\s_b{20}

the command \s is redefined and usage of \s_a will trigger the error message

! Use of \s doesn't match its definition.

since \s is not followed by _b.

To solve both problems at once, use

\def\sa/{10}
\def\sb/{20}

and then \sa/ and \sb/ will render as

10 and 20

because the required / after the commands' names stops the space ignoring feature.

share|improve this answer
2  
Okay, just what I needed: a reason why it can't be done. –  romeovs Jan 4 '12 at 17:36

You can force latex to accept the _ by changing the catcode of the sign. In (La)Tex every sign has its catcode, so if we change the catcode of _ to the the normal catcode your command will work. But changing the catcode may lead to unexpected error. I recommend you to use another naming scheme.

\documentclass[12pt]{article}

\catcode`_=11
\def\s_a{10}
\def\s_b{20}

\begin{document}
\s_a and \s_b
\end{document}

You may solve the spacing issue with xspace:

\documentclass[12pt]{article}
\usepackage{xspace}

\catcode`_=11
\def\s_a{10\xspace}
\def\s_b{20\xspace}

\begin{document}
\s_a and \s_b
\end{document}
share|improve this answer

My solution:

I've made my own solution, that isn't quite what I officially asked, though it qualifies as "another way to get data from a file".

I use this function to set a value:

\DeclareDocumentCommand{\Mset}{m m g}
{
    \IfNoValueTF{#3}{
        \pgfkeyssetvalue{/matlab/#1/val}{#2}
        \pgfkeyssetvalue{/matlab/#1/e}{}
    }{
        \pgfkeyssetvalue{/matlab/#1/val}{#2}
        \pgfkeyssetvalue{/matlab/#1/e}{e#3}
    }

}
% eg:
\Mset{a}{124}         % set value of 'a' to 124
\Mset{b}{124}{2}      % set value of 'a' to 124e2

I can get it's literal value by using:

\newcommand{\M}[1]
{
    \pgfkeysvalueof{/matlab/#1/val}\pgfkeysvalueof{/matlab/#1/e}
}
% eg:
\M{a}     % results in: 124
\M{b}     % results in: 124e2

Or it's value without it's exponent:

\newcommand{\Mval}[1]
{
    \pgfkeysvalueof{/matlab/#1/val}
}
% eg:
\Mval{a}     % results in: 124
\Mval{b}     % results in: 124

Then I defined my own SI command: \MSI.

\DeclareDocumentCommand{\Mparse}{m g m}{

    \IfNoValueTF{#2}{
        \SI{ \M{#1}}{#3}
    }{
        \SI{ \Mval{#1}+-\M{#2} }{#3}
    }
}

\DeclareDocumentCommand \MSI { >{ \SplitArgument{1}{+} } m m}
{
    \Mparse #1 {#2}
}

%eg:
\MSI{a}{m}     % same as: \SI{124}{m}
\MSI{b}{m}     % same as: \SI{124e2}{m}

This is a cool function:

\Mset{c}{100}{2}
\Mset{s_c}{12}{2}
\MSI{c+s_c}{m}       % same as: \SI{100+-12e2}{m}

I can actually call \MSI on the names of the values. This will only work properly if the exponent values for c and s_c are the same, since it just takes the exponent value of s_c. Since my matlab function outputs the values with corresponding exponents for c and s_c this doesn't matter for me. Yet I probably will implement some sort of warning anytime soon.

This requires the xparse package, as well as the pgfplots package.

Replace \Mparse definition by this one for some minimal error tracking:

\DeclareDocumentCommand{\Mparse}{m g m}{

    \IfNoValueTF{#2}{
        \SI{ \M{#1}}{#3}
    }{
        \comparestrict
        \IfStrEq{\Mexp{#1}}{\Mexp{#2}}{
            \SI{ \Mval{#1}+-\M{#2} }{#3}
        }{
            \text{\tt > > ERROR: not equal exponents in MSI < < }
                    \GenericError{(cont.)\space\space}{The exponents for the inputs here aren't the same, as should be for decent output.}{Check that the exponents are the same.}{Check tex.stackexchange.com question 40070}


        }

    }
}

This makes use of the the \Mexp command:

\newcommand{\Mexp}[1]
{
    \pgfkeysvalueof{/matlab/#1/e}
}

It also needs the xstring package to check if the strings in /matlab/#1/e are equal.

share|improve this answer

I have used labels in mymacros.tex:

\newlabel{@S_L(d)}{{\unit{-118}{\mega\pascal}}}

Then use references in tex file:

\ref{@S_L(d)}
share|improve this answer
    
Does this actually answer the OP's question? –  Werner Jan 5 '12 at 0:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.