120

This question led to a new package: matlab-prettifier

Does anybody have a quick and easy way to typeset some relatively long MATLAB code in the appendix? I looked up a few methods, and the mcode package emerged as a possibility, but it seems to be unmaintained...

I have a ton of equations in my code, so I'd prefer a solution that avoids having to use $ to denote equations.

Also, if possible, if there's a way to keep all of MATLAB's "natural" coding colors (e.g. green for comments), that would be great...

Any idea?

jub0bs
  • 58,916
suzu
  • 1,927
  • 2
    I used mcode for my thesis and it worked fine. Depending on what version of MATLAB you are using, it also has built-in tools for exporting the code with LaTeX markup already embedded. Look up "publish" in the MATLAB help browser. – craigim May 01 '13 at 16:00

4 Answers4

95

Here is the template I use for matlab code:

\documentclass{article}

\usepackage{listings}
\usepackage{color} %red, green, blue, yellow, cyan, magenta, black, white
\definecolor{mygreen}{RGB}{28,172,0} % color values Red, Green, Blue
\definecolor{mylilas}{RGB}{170,55,241}


\begin{document}


\lstset{language=Matlab,%
    %basicstyle=\color{red},
    breaklines=true,%
    morekeywords={matlab2tikz},
    keywordstyle=\color{blue},%
    morekeywords=[2]{1}, keywordstyle=[2]{\color{black}},
    identifierstyle=\color{black},%
    stringstyle=\color{mylilas},
    commentstyle=\color{mygreen},%
    showstringspaces=false,%without this there will be a symbol in the places where there is a space
    numbers=left,%
    numberstyle={\tiny \color{black}},% size of the numbers
    numbersep=9pt, % this defines how far the numbers are from the text
    emph=[1]{for,end,break},emphstyle=[1]\color{red}, %some words to emphasise
    %emph=[2]{word1,word2}, emphstyle=[2]{style},    
}


\section*{Matlab Code}

\lstinputlisting{myfun.m}


\end{document}

This produced the following output (I didn't put my matlab file here but it should be clear from the output):

enter image description here

Vivi
  • 26,953
  • 31
  • 77
  • 79
90

For typesetting Matlab code in LaTeX, consider using the matlab-prettifier package.

Piggybacking on the listings package, it doesn't require much configuration, and it keeps track of the context (behind the scenes) in order to highlight code as it appears in the Matlab editor. In this respect, it arguably does a much better job than the other available options (minted, listings, mcode, etc.) do.

Syntax highlighting currently performed by the matlab-prettifier package include:

  1. context-insensitive keywords (e.g. for, while, break),
  2. context-sensitive keywords (e.g. end, properties, events),
  3. (quoted) strings,
  4. one-line and block comments,
  5. line-continuation tokens (...),
  6. code-section titles.
  7. system commands.

Additional features include

  • three predefined styles: standard, black & white, and a MatlabLexer-like style for mimicking Pygments (minted) output,
  • seamless compatibility with listings' environments and macros,
  • manual highlighting of variables with shared scope,
  • manual highlighting of unquoted strings,
  • a macro for easily typesetting placeholders in code snippets,
  • automatic scaling of inline code according to its surroundings,
  • an option to only print the header of a Matlab function (see this).

matlab-prettifier is available on CTAN and in both TeX Live and MiKTeX. If you wish, you can grab the development version from the GitHub repository.

Some examples

For comparison, here are some code samples as typeset by matlab-prettifier and as they appear in the Matlab editor.

person.m (matlab-prettifier) person.m (Matlab editor)

sample.m (matlab-prettifier) sample.m (Matlab editor)

code snippet with placeholders (matlab-prettifier)

Code

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage{bigfoot} % to allow verbatim in footnote
\usepackage[numbered,framed]{matlab-prettifier}

\usepackage{filecontents}
\begin{filecontents*}{person.m}
classdef person
   properties %(here, properties is a keyword)
       mass=80;
       height=1.80;
   end
   methods
       function BMI = getBMI(height,weight)
           BMI = person.mass/person.mass^2;
       end
   end
end
\end{filecontents*}

\begin{filecontents*}{sample.m}
%% Code sections are highlighted.
% System command are supported...
!gzip sample.m
% ... as is line continuation.
A = [1, 2, 3,... % (mimicking the ouput is good)
     4, 5, 6]
fid = fopen('testFile.text', 'w')
for i=1:10
  fprintf(fid,'%6.2f \n', i);
end
x=1; %% this is just a comment, though
% Context-sensitive keywords get highlighted correctly...
p = properties(mydate); %(here, properties is a function)
x = linspace(0,1,101);
y = x(end:-1:1)
% ... even in nonsensical code.
]end()()(((end end)end ))))end (function end
%{
    block comments are supported
%} even
runaway block comments
are
\end{filecontents*}

\let\ph\mlplaceholder % shorter macro
\lstMakeShortInline"

\lstset{
  style              = Matlab-editor,
  basicstyle         = \mlttfamily,
  escapechar         = ",
  mlshowsectionrules = true,
}

\begin{document}

\lstlistoflistings

\lstinputlisting[caption = {Some class definition}]{person.m}

Before you use any "for"~loop, refresh your memory on Matlab blocks.%
\footnote{Any occurence of "for" must have a matching "end".} 

\lstinputlisting[caption = {Sample code from Matlab}]{sample.m}
\pagebreak

\begin{lstlisting}[caption = {For educational purposes}]
% example of while loop using placeholders
while "\ph{condition}"
  if "\ph{something-bad-happens}"
    break
  else
    % do something useful
  end
  % do more things
end
\end{lstlisting}

\end{document}
jub0bs
  • 58,916
  • 13
    Though I hate matlab truly, this is still quite cool output – percusse Feb 06 '14 at 00:07
  • Great! Thanks. I think you should upload it to Mathworks File Exchange. – osjerick Feb 07 '14 at 04:49
  • 4
    I myself find Matlab frustrating in many ways, but it's still a great tool for prototyping number-crunching stuff. What spurred me into writing matlab-prettifier is that none of the existing tools do a great job at replicating the syntax highlighting of the Matlab editor, and I think Matlab beginners learn more effectively if they're exposed to code that is highlighted in a consistent manner, whether is be in the Matlab editor or in a PDF. – jub0bs Feb 08 '14 at 03:24
  • Looks rather nice - the main differences between the matlab window and the output (I know matching colours was the request) look to be the font weight and line spacing - and the latter could be tightened to match. – Chris H Feb 10 '14 at 14:01
  • @ChrisH I used Courier in my listings, whereas Matlab uses its proprietary (I think) Monospaced font by default. However, because matlab-prettifier is compatible with XeLaTeX/LuaLaTeX, you can always set a different monospace font for your listings, one closer in appearance to Matlab's Monospaced, if you so wish. – jub0bs Feb 10 '14 at 14:29
  • @Jubobs, thankfully I don't have enough to do with matlab to worry about it! It's interesting to see though how much tighter the (admittedly designed for screen use) matlab default is, and it still looks nice and clear. – Chris H Feb 10 '14 at 15:17
  • @ChrisH If you want, you can always reduce the vertical space between lines by setting the lineskip key to some negative (length) value, e.g. -1pt. – jub0bs Feb 10 '14 at 19:43
  • @Jubobs I was thinking that, then got distracted choosing a monospaced font (and thanks for spotting my mistake). – Chris H Feb 11 '14 at 09:40
  • +1 really pretty code: so finally promise broken :) – texenthusiast Feb 16 '14 at 01:05
  • @texenthusiast Yes. Sorry, I had to break my promise because I changed the syntax... for the better! That should be the last edit, though. – jub0bs Feb 16 '14 at 09:15
  • Quick question. If I load the package, can I just issue \lstinputlistings{mycode.m} to achieve the desired results? I haven't looked at the documentation yet. – dustin Apr 27 '14 at 15:57
  • 2
    @dustin Basically, yes. Using it is no more complicated than loading a listings style. Try \lstset{style=Matlab-editor} in your preamble, and then \lstinputlisting{mycode.m}. Or, if you have listings in other programming language, use \lstinputlisting[style=Matlab-editor]{mycode.m}. – jub0bs Apr 27 '14 at 16:07
  • @Jubobs, please consider adding support to GNU Octave. It has extra keywords such as endif, endfor, etc; recognizes comments with # in addition to %, etc. – juliohm Apr 27 '14 at 18:17
  • 1
    @Jubobs +1 great package. looks like you've changed snippetPlaceholder to mlplaceholder, not sure if edit is appropriate here. (at least, snippetPlaceholder is undefined, but i don't know latex) – user3125280 Sep 16 '14 at 12:08
  • 1
    @user3125280 Thanks. Yes, good catch. The macro for placeholders is indeed called \mlplaceholder, now; I just forgot to change the name in this answer. Fixed. – jub0bs Sep 16 '14 at 12:23
  • You can keep improving this solution, by fixing the formatting when you call 'save', for instance: save inputs.mat mu Q – QFi Apr 19 '18 at 02:46
  • @Zizou23 I know. Unfortunately, I don't have a solution for this case. There is a relevant section in the package documentation (search for "unquoted strings"). – jub0bs Apr 19 '18 at 07:12
  • @jubobs thanks for this great package! Maybe you can add to the post the information how to change the name of the environment. E.g. from listing to Algorithm. I found it here https://tex.stackexchange.com/a/64845/34538 – bonanza Aug 15 '18 at 07:23
  • That's relevant to the listings package in general, not to matlab-prettifier (which uses listings under the hood) specifically. – jub0bs Aug 15 '18 at 09:26
38

The mcode package still supports Matlab code formatting, setting the default lstlisting environment (from listings) formatting to that of Matlab. It also provides \mcode{<code>} for inline Matlab code.

enter image description here

\documentclass{article}
% http://www.mathworks.com/matlabcentral/fileexchange/8015-m-code-latex-package
\usepackage[framed,numbered,autolinebreaks,useliterate]{mcode}
\begin{document}
\begin{lstlisting}
function y = myfun(aa, sigma, options)

  sigma

  y = aa .* pdf('logn', aa, -0.5*sigma^2, sigma)

  %y = 1/(sigma.*sqrt(2.*pi)) .* exp((-((log(aa)+0.5*sigma.^2)).^2) ./ (2.*sigma.^2));
\end{lstlisting}
\end{document}

Similar reference: Inline MATLAB code

Werner
  • 603,163
  • 4
    Not fair. Now that I see your answer I am not quite so proud of my code anymore :( – Vivi Nov 05 '12 at 08:43
  • The best way! Great package. – osjerick Nov 25 '13 at 17:39
  • 2
    Unfortunately, the mcode package suffers from several limitations, one of which is that it doesn't typeset the context-sensitive end keyword correctly all the time. I'm working on a package that allows for correct syntax highlighting of Matlab listings, and I'm hoping to submit it to CTAN in the near future. – jub0bs Dec 12 '13 at 00:29
  • 1
    @Jubobs It will be awesome! – osjerick Dec 13 '13 at 16:38
  • @Werner is there any way to remove the numbers that comes up to the left of the output? – Zeno San Sep 04 '22 at 13:36
  • 1
    @ZenoSan: Try without the numbered option for the package. – Werner Sep 05 '22 at 07:51
-3

Did you try

\begin{verbatim}    
Matlab code 
\end{verbatim}
Zarko
  • 296,517