From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- .../matlab-prettifier/matlab-prettifier.dtx | 2635 ++++++++++++++++++++ 1 file changed, 2635 insertions(+) create mode 100644 macros/latex/contrib/matlab-prettifier/matlab-prettifier.dtx (limited to 'macros/latex/contrib/matlab-prettifier/matlab-prettifier.dtx') diff --git a/macros/latex/contrib/matlab-prettifier/matlab-prettifier.dtx b/macros/latex/contrib/matlab-prettifier/matlab-prettifier.dtx new file mode 100644 index 0000000000..cb8145299b --- /dev/null +++ b/macros/latex/contrib/matlab-prettifier/matlab-prettifier.dtx @@ -0,0 +1,2635 @@ +% \iffalse meta-comment +% +% Copyright (C) 2014 by Julien Cretel +% +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% \fi +% +% \iffalse +%\NeedsTeXFormat{LaTeX2e}[2011/06/27] +%\ProvidesPackage{matlab-prettifier} +% [2014/06/19 v0.3 A package for prettyprinting Matlab source code] +% +%<*driver> +\documentclass[a4paper]{ltxdoc} +\EnableCrossrefs +\CodelineIndex +\RecordChanges + +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{xcolor} +\usepackage{lstdoc} +\usepackage[framed,numbered]{matlab-prettifier} +\usepackage{hyperref} +\usepackage{cleveref} + +\lstset +{ + style = Matlab-editor, + basicstyle = \normalsize\mlttfamily, + upquote = true, + mlunquotedstringdelim = {/*}{*/}, + mlmoresharedvars = {myglobalvar}, +} +\lstdefinestyle{nonbnoframe} +{ + frame = none, + numbers = none, +} +\lstMakeShortInline" +\newcommand\ph\mlplaceholder +\newcommand*{\pkg}[1]{\textsf{#1}} +\newcommand*{\opt}[1]{\texttt{#1}} +\newcommand\lstpkg{\pkg{listings}} +\newcommand*{\lststy}[1]{\texttt{#1}} +\newcommand*{\lstlng}[1]{\texttt{#1}} +\newcommand\matlab{\textsc{Matlab}} +\newcommand\octave{\textsc{Octave}} +\newcommand\matlabver{\matlab~(R2013a)} +\newcommand\mathworks{MathWorks} +\newcommand*\trademark[1]{#1\textsuperscript{\textregistered}} +\newcommand\mlpkg{\pkg{matlab-prettifier}} +\newcommand\mllng{\texttt{Matlab-pretty}} +\newcommand*{\mlsty}[1]{\texttt{#1}} +\newcommand\overrideEnd{\lstinline[mloverride]|end|} +\newcommand\overrideEnumeration{\lstinline[mloverride]|enumeration|} +\newcommand\overrideMethods{\lstinline[mloverride]|methods|} +\newcommand\overrideProperties{\lstinline[mloverride]|properties|} +\newcommand\overrideEvents{\lstinline[mloverride]|events|} +\newcommand\itemp{\item[\(+\)]} +\newcommand\itemm{\item[\(-\)]} + +\makeindex + +\begin{document} + \DocInput{matlab-prettifier.dtx} +\end{document} +% +% \fi +% +% \CheckSum{671} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \changes{v0.1}{2014/04/24}{Initial release.} +% \changes{v0.2}{2014/04/25}{ +% Refactor code extensively; +% rewrite automatic scaling of inline code; +% implement mlscaleinline key; +% implement mlonlyheader. +% } +% \changes{v0.3}{2014/06/19}{ +% Change default font from Bera Mono to Computer Modern typewriter +% (for compatibility reasons); +% fix bug (end keyword now gets reset by a semicolon); +% rename placeholder user macro; +% mention support for a subset of Octave's syntax. +% } +% +% \GetFileInfo{matlab-prettifier.sty} +% +% ^^A see http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex%2F3540 +% \begingroup +% \def\x{\#,\$,\%,\^,\_,\~,\&,\{,\},\/}%^^A +% \makeatletter +% \@onelevel@sanitize\x +% \expandafter\endgroup\expandafter\DoNotIndex\expandafter{\x} +% +% \begingroup +% \makeatletter +% \lccode`9=32\relax +% \lowercase{%^^A +% \edef\x{\noexpand\DoNotIndex{\@backslashchar9}}%^^A +% }%^^A +% \expandafter\endgroup\x +% +% \DoNotIndex{\@empty,\@ifpackagewith,\@lst,\@namedef,\@ne,\@tempa} +% \DoNotIndex{\advance} +% \DoNotIndex{\baselineskip,\begingroup,\bfseries,\bgroup} +% \DoNotIndex{\ClosingEndKW@mlpr@false,\ClosingEndKW@mlpr@true,^^A +% \color,\colorlet,\csname,\CurrentOption} +% \DoNotIndex{\DeclareOption,\def,\definecolor,\dimexpr,^^A +% \DroppingOutput@mlpr@false,\DroppingOutput@mlpr@true} +% \DoNotIndex{\edef,\egroup,\else,\endcsname,\endgroup,\expandafter} +% \DoNotIndex{\f@baselineskip,\f@shape,\f@size,\fi,\font,\fontsize,^^A +% \fontchardp,\fontcharht,\fontfamily,\framed@mlpr@true,\fvm@Scale} +% \DoNotIndex{\gdef,\global} +% \DoNotIndex{\ifnum,\ifx,^^A +% \InClassdef@mlpr@false,\InClassdef@mlpr@true,^^A +% \InSecTitle@mlpr@false,\InSecTitle@mlpr@true,^^A +% \InStr@mlpr@false,\InStr@mlpr@true,^^A +% \itdefault,\itshape} +% \DoNotIndex{\let,\lst@basicstyle,\lst@BeginDropOutput,\lst@AddToHook,^^A +% \lst@CalcLostSpaceAndOutput,\lst@DefSaveDef,\lst@DelimKey,^^A +% \lst@EnterMode,\lst@ifdisplaystyle,\lst@ifLmode,\lst@ifwhitespace,^^A +% \lst@InstallKeywords,\lst@Key,\lst@language,\lst@LeaveMode,^^A +% \lst@lineno,\lst@linewidth,\lst@Lmodetrue,\lst@mode,\lst@modetrue,^^A +% \lst@NormedDef,\lst@Pmode,\lst@DeleteKeywords,\lst@InstallFamily@,^^A +% \lst@MakeKeywords,\lst@MakeMoreKeywords,\lst@UseFamily,^^A +% \lstdefinelanguage,\lstdefinestyle,\lstKV@SetIf} +% \DoNotIndex{\m@ne,\makebox} +% \DoNotIndex{\newcommand,\newcount,\newif,\newlength,\newtoks,\normalsize,^^A +% \numbered@mlpr@true,\noexpand} +% \DoNotIndex{\OptionNotUsed} +% \DoNotIndex{\PackageError,\PackageWarning,\ProcessOptions} +% \DoNotIndex{\raisebox,\relax,\renewcommand,\RequirePackage,\rule,\rmfamily} +% \DoNotIndex{\selectfont,\setlength,\sldefault,\textlangle,\textrangle,^^A +% \ttfamily} +% \DoNotIndex{\the} +% \DoNotIndex{\upshape} +% \DoNotIndex{\VisCharOccured@mlpr@true,\VisCharOccured@mlpr@false} +% +% \title^^A +% {^^A +% The \mlpkg{} package^^A +% \thanks^^A +% {^^A +% This document corresponds to \mlpkg~\fileversion, +% dated~\filedate.^^A +% }^^A +% } +% \author{Julien Cretel\\ \texttt{jubobs.matlab.prettifier at gmail.com}} +% \date{\filedate} +% \thispagestyle{empty} +% \maketitle +% +% \begin{abstract} +% Built on top of the \lstpkg{} package, the \mlpkg{} package allows you to +% effortlessly prettyprint \matlab{} source code in documents typeset with +% \LaTeX{} \& friends. Three predefined styles, one of which closely mimics +% that of the \matlab{} editor, are available and can be invoked by +% \lstpkg{} macros and environments in conjunction with (most) options +% provided by the \lstpkg{} package. The appearance of your \matlab{} +% listings can be further tweaked via a key-value interface extending that +% of \lstpkg{}'. Partial support for Octave syntax is provided. +% \end{abstract} +% +% \tableofcontents\newpage +% +% +% \part{Introduction} +% +% \section{Why this package?} +% +% \trademark{\matlab} is a high-level language and interactive environment for +% numerical computation, visualization, and programming.^^A +% \footnote{Source: \url{http://www.mathworks.co.uk/products/matlab/}} +% Despite being proprietary and occasionally frustrating, \matlab{} remains a +% great tool for prototyping matrix-oriented, number-crunching programs. +% As such, it enjoys widespread popularity, especially in academia, +% where, in particular, it is often used for teaching numerical methods. +% +% Users of both \matlab{} and \LaTeX{} (and friends) often need to typeset +% \matlab{} listings in \LaTeX{} documents, usually with some syntax +% highlighting, for improved code readability; +% the relatively large number of relevant questions posted on +% \href{http://tex.stackexchange.com/search?q=matlab+code+is%3Aquestion}^^A +% {tex.stackexchange.com} attests to that need. +% +% Recent versions of \matlab{} provide a built-in function, called "publish", +% that can generate \LaTeX{} code for typesetting \matlab{} listings, but +% that function uses a |verbatim| environment, which doesn't allow for any +% fancy formatting. +% Several \LaTeX{} packages^^A +% ---vanilla \lstpkg{}, \pkg{mcode}, and \pkg{minted}, among others---^^A +% allow for automatic syntax highlighting of \matlab{} listings in \LaTeX{} +% documents. +% However, none of those packages do a great job at replicating the very +% specific syntax-highlighting style performed on the fly by the \matlab{} +% editor.^^A +% \footnote{see ... for a comparison.} +% +% The lack of tools for faithfully mimicking the style of the \matlab{} +% editor is unfortunate, especially from an educational standpoint, for the +% following reason. +% Most newcomers to \matlab{} read and write code in the \matlab{} editor +% and are, therefore, continually exposed to its highlighting style. +% Visual cues^^A +% ---such as those provided by syntax highlighting---^^A +% play an important role for recognising patterns, +% and students of a programming language are more likely to quickly and +% effectively learn and recognize its syntax if they see it highlighted in a +% consistent manner, whether it be in a text editor or in some course material +% (lab handout, assignment paper, etc.). +% +% The \mlpkg{} package is intended to fill that gap. +% Built on top of the feature-rich \lstpkg{} package, \mlpkg{} allows you to +% beautifully and effortlessly typeset \matlab{} listings, as it configures +% \lstpkg{} ``behind the scenes'' to replicate, as closely as possible, the +% syntax-highlighting style of the \matlab{} editor. +% +% What about code written in \octave{} (a free alternative to \matlab{})? +% Because \octave{}'s syntax and \matlab{}'s syntax +% \href{http://wiki.octave.org/FAQ#How_is_Octave_different_from_Matlab.3F} +% {overlap a lot}, +% \mlpkg{} correctly highlights \octave{} listings that strictly adhere to +% the subset of syntax that lies in this overlap. +% More support for \octave{} is expected to ship with a future release. +% +% Furthermore, \mlpkg{} comes with a few additional features that should make +% your life easier. Read on! +% +% +% \section{Review of alternatives to \mlpkg{}} +% +% Here is a review of the different alternatives^^A +% ---other than the \mlpkg{} package and \matlab{}'s "publish" function---^^A +% available for typesetting \matlab{} listings in \LaTeX{} documents. +% +% \paragraph{\lstpkg{}' \lstlng{Matlab} language} +%^^A +% \begin{itemize} +% \itemp A starting point! +% \itemp \lstpkg{}' rich features are available. +% \itemp Settings for \matlab{} listings are bundled into a \lstpkg{} +% language, which can be invoked \emph{locally}. +% \itemm Some \matlab{} keywords (e.g.\ "parfor") are not listed. +% \itemm Built-in \matlab{} function names (e.g.\ "sum") get highlighted +% like \matlab{} keywords do, which is very distracting. +% \itemm Highlighting of keywords is not context-aware; +% in particular, the |end| keyword gets typeset in the same style, +% regardless of the context (closing keyword or last-element keyword) +% in which it occurs. +% \itemm No highlighting of block comments +% \itemm No highlighting of line-continuation token and associated comment +% \itemm Section titles are not highlighted in a style distinct from that of +% comments. +% \itemm No highlighting of unquoted strings +% \end{itemize} +% +% \paragraph{\pkg{mcode}} +%^^A +% \begin{itemize} +% \itemp An honest attempt at improving \lstpkg{}' \lstlng{Matlab} language +% \itemp Package options for quickly effecting global changes to the look +% of \matlab{} listings +% \itemp Block comments are highlighted as such. +% \itemp A line-continuation token activates comment style\ldots +% \itemm \ldots but also gets highlighted in comment style. +% \itemm Settings for \matlab{} listings are defined \emph{globally} +% (using |\lstset|) rather than locally, +% which means those settings can easily be overwritten/lost. +% \itemm The \overrideEnumeration{} keyword is not listed. +% \itemm Highlighting of the last-element keyword is handled by a series of +% literate replacements; +% this approach works well only in a limited number of cases in which +% that keyword occurs. +% \itemm Highlighting of the four context-sensitive class-definition +% keywords is not context-aware; +% in particular, |properties| gets typeset in the same style, +% regardless of the context (function or class-definition keyword) +% in which it occurs. +% \itemm Undesirable literate replacements +% ("<=" by~\(\leq\), "delta" by~\(\Delta\)) are forced upon the users, +% and cannot be easily prevented without breaking other literate +% replacements put in place for highlighting the last-element keyword. +% \itemm Section titles are not highlighted in a style distinct from that of +% comments. +% \itemm No highlighting of unquoted strings +% \itemm The implementation of \pkg{mcode} lacks ``namespacing'', +% which increases the risk of conflict with other packages. +% \itemm \pkg{mcode} is currently not available on +% \href{http://ftp.heanet.ie/pub/CTAN/tex/support/ctanify/ctanify.pdf} +% {CTAN}. +% \end{itemize} +% +% \paragraph{Pygments-based packages +% (\pkg{minted}, \pkg{verbments}, \pkg{pythontex})} +%^^A +% \begin{itemize} +% \itemp Python! +% \itemp Pygments! +% \itemp Slick look +% \itemp Block comments are highlighted as such. +% \itemp A line-continuation token activates comment style\ldots +% \itemm \ldots but also gets highlighted in comment style. +% \itemm \lstpkg{}' features are not available. +% \itemm Highlighting of keywords is not context-aware; +% in particular, the last-element keyword gets highlighted like the +% closing keyword does, which is very distracting. +% \itemm \matlab{}'s transpose operator (".'") and "}'" are incorrectly +% interpreted as starting a string literal. +% \itemm No highlighting of unquoted strings +% \itemm Escape to \LaTeX{} is only allowed in comments. +% \itemm Slow compared to \lstpkg{} +% \itemm Requires |-shell-escape| +% \end{itemize} +% +% +% \section{Syntactic elements automatically highlighted by \mlpkg{}} +% +% The \mlpkg{} package defines a \pkg{listings} language called +% \mllng{}, which is designed to keep track of the context behind the scenes +% and, therefore, facilitates context-sensitive highlighting of various +% elements of \matlab{} syntax. +% That language is used as a basis for three \lstpkg{} styles, +% one of which, called \mlsty{Matlab-editor}, is showcased below. +% +% \paragraph{Context-insensitive keywords} +% "while", "for", "break", etc. +% +% \paragraph{Context-sensitive keywords} +% "end", +% \overrideEvents{}, +% \overrideProperties{}, +% etc. +% +% \paragraph{Quoted strings} +% \mbox{} +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[numbers=none] +'The sleeper must awaken.' +\end{lstlisting} +% \iffalse +% +% \fi +% +% \paragraph{To-end-of-line and block comments} +% \mbox{} +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[numbers=none] +% Now let's assign the value of pi to variable a +a = pi +%{ + Now that a holds the value of pi, + here is what we're going to do... + blah blah blah +%} +\end{lstlisting} +% \iffalse +% +% \fi +% +% \paragraph{Line-continuation token (and associated to-end-of-line comment)} +% \mbox{} +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[numbers=none] +A = [ 1, 2, 3,... (second row defined on next line) + 4, 5, 6]; +\end{lstlisting} +% \iffalse +% +% \fi +% +% \paragraph{Section titles} +% \mbox{} +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[numbers=none] +%% Variable initialization +\end{lstlisting} +% \iffalse +% +% \fi +% +% \paragraph{System commands} +% \mbox{} +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[numbers=none] +! gzip sample.m +\end{lstlisting} +% \iffalse +% +% \fi +% +% +% \section{Styles provided by \mlpkg{}} +% +% The package defines three \lstpkg{} \emph{styles} for \matlab{} code: +% \mlsty{Matlab-editor}, \mlsty{Matlab-bw}, and +% \mlsty{Matlab-Pyglike}. +% Those styles differ in terms of color scheme but, for convenience, +% all three activate automatic line breaking; +% for more defails about automatic line breaking, see subsection~4.10 in +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}. +% +% Here is a comparison of the three styles defined by \mlpkg{}. +% +% \paragraph{\mlsty{Matlab-editor}} +% This style mimics the default style of the \matlab{} editor. +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[style=Matlab-editor,basicstyle=\mlttfamily] +%% Sample Matlab code +!mv test.txt test2.txt +A = [1, 2, 3;... foo + 4, 5, 6]; +s = 'abcd'; +for k = 1:4 + disp(s(k)) % bar +end +%{ +create row vector x, then reverse it +%} +x = linspace(0,1,101); +y = x(end:-1:1); +\end{lstlisting} +% \iffalse +% +% \fi +% +% \paragraph{\mlsty{Matlab-bw}} +% This style is mainly for black \& white printing. +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[style=Matlab-bw,basicstyle=\mlttfamily] +%% Sample Matlab code +!mv test.txt test2.txt +A = [1, 2, 3;... foo + 4, 5, 6]; +s = 'abcd'; +for k = 1:4 + disp(s(k)) % bar +end +%{ +create row vector x, then reverse it +%} +x = linspace(0,1,101); +y = x(end:-1:1); +\end{lstlisting} +% \iffalse +% +% \fi +% +% \paragraph{\mlsty{Matlab-Pyglike}} +% The \pkg{minted}, \pkg{verbments}, and \pkg{pythontex} packages all use +% \href{http://pygments.org}{Pygments} lexers for syntax highlighting of +% listings. +% This \mlpkg{} style closely mimics the default style associated with +% Pygments' `MatlabLexer'. +% \iffalse +%<*example> +% \fi +\begin{lstlisting}[style=Matlab-Pyglike,basicstyle=\mlttfamily] +%% Sample Matlab code +!mv test.txt test2.txt +A = [1, 2, 3;... foo + 4, 5, 6]; +s = 'abcd'; +for k = 1:4 + disp(s(k)) % bar +end +%{ +create row vector x, then reverse it +%} +x = linspace(0,1,101); +y = x(end:-1:1); +\end{lstlisting} +% \iffalse +% +% \fi +% +% +% \section{Other features} +% +% Additional features include +% +% \begin{itemize} +% \item a key-value interface extending that of the \lstpkg{} package, +% \item manual highlighting of variables with shared scope +% (e.g.\ "myglobalvar"), +% \item manual highlighting of unquoted strings +% (e.g.\ ``on'' in ``"hold /*on*/"''), +% \item a macro for easily typesetting placeholders +% (e.g.\ \ph{initial-value}), +% \item automatic scaling of inline code according to its surroundings, +% \item an option to only print the header of a \matlab{} function. +% \end{itemize} +% +% +% \part{User's guide} +% +% \section{Installation} +% +% \subsection{Package dependencies} +% +% \mlpkg{} requires relatively up-to-date versions of packages \pkg{textcomp}, +% \pkg{xcolor}, and \lstpkg{}, all three of which ship with popular \TeX{} +% distributions. It loads those three packages without any options. +% +% +% \subsection{Installing \mlpkg{}} +% +% Since the package has been officially released on +% \href{http://www.ctan.org/pkg/matlab-prettifier}{CTAN}, +% you should be able to install it directly through your package manager. +% +% However, if you need to install \mlpkg{} manually, you should run +%^^A +% \begin{verbatim} +% latex matlab-prettifier.ins\end{verbatim} +%^^A +% and copy the file called |matlab-prettifier.sty| to a path +% where \LaTeX{} (or your preferred typesetting engine) can find it. +% To generate the documentation, run +%^^A +% \begin{verbatim} +% pdflatex matlab-prettifier.dtx +% makeindex -s gglo.ist -o matlab-prettifier.gls matlab-prettifier.glo +% makeindex -s gind.ist -o matlab-prettifier.ind matlab-prettifier.idx +% pdflatex matlab-prettifier.dtx +% pdflatex matlab-prettifier.dtx\end{verbatim} +%^^A +% +% +% \section{Getting started} +% +% As stated above, the \mlpkg{} package is built on top of the \lstpkg{} +% package. +% If you already are a seasoned \lstpkg{} user, you should feel right at home. +% If you're not, be aware that this user's guide makes use of some \lstpkg{} +% functionalities (such as key-value options) without describing their usage. +% For more details on those functionalities, you should consult the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}. +% +% +% \subsection{Loading \texorpdfstring{\mlpkg{}}{matlab-prettifier}} +% +% Simply write +%^^A +% \begin{verbatim} +% \usepackage{matlab-prettifier}\end{verbatim} +%^^A +% somewhere in your preamble. +% +% You may want to load the \lstpkg{} and +% \pkg{xcolor} packages with some options; in that case, make sure those +% options are passed to those two packages \emph{before} loading the \mlpkg{} +% package. +% +% The \mlpkg{} package currently offers four options. +% The first two are inspired from the \pkg{mcode} package. +% The last two are simply \lstpkg{} options that \mlpkg{} passes to \lstpkg{} +% behind the scenes; +% I chose to define those two options as \mlpkg{} options to save you +% the hassle of loading them with \lstpkg{} separately, +% should you wish to use them. +%^^A +% \begin{description} +% \item[\opt{framed}]\leavevmode +% +% Draws (by default) a dark gray frame around each listing that uses +% one of the three styles defined by \mlpkg{}. +% +% \item[\opt{numbered}]\leavevmode +% +% Prints (by default) line numbers in light gray to the left of each +% listing that uses one of the three styles defined by \mlpkg{}. +% +% \item[\opt{draft}]\leavevmode +% +% This is simply \lstpkg{}' \opt{draft} option. +% For more details, see subsection~2.2 of the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}. +% +% \item[\opt{final}]\leavevmode +% +% This is simply \lstpkg{}' \opt{final} option. +% For more details, see subsection~2.2 of the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}. +% \end{description} +% +% +% \subsection{Displayed listings} +% +% To typeset a \matlab{} listing embedded in your |tex| file, simply enclose +% it in an |lstlisting| environment, and load some style in the environment's +% optional argument, using \lstpkg{}' \keyname{style} key. +%^^A +% \begin{verbatim} +% \begin{lstlisting}[style=Matlab-editor] +% ... +% \end{lstlisting}\end{verbatim} +% +% +% \subsection{Standalone listings} +% +% In practice, though, keeping your \matlab{} listings in external files^^A +% ---rather than embedding them in a |tex|~file---^^A +% is preferable, for maintainability reasons. +% To typeset a \matlab{} listing residing in an m-file, simply invoke the +% |\lstinputlisting| macro; load some style in the environment's +% optional argument, and specify the path to the m-file in question in the +% mandatory argument. +%^^A +% \begin{verbatim} +% \lstinputlisting[style=Matlab-editor]{sample.m}\end{verbatim} +%^^A +% +% +% \subsection{Inline listings} +% +% You may want to typeset fragments of \matlab{} code within the main text of +% your document. For instance, you may want to typeset the "break" keyword in +% a sentence, in order to explain its usage. +% The |\lstinline| macro can be used for typesetting such inline code. +%^^A +% \begin{verbatim} +% \lstinline[style=Matlab-style]!break!\end{verbatim} +%^^A +% Well, that's quite a mouthful for such a simple \matlab{} keyword! +% Writing |\lstinline| for each instance of inline \matlab{} code in your +% document can rapidly become tedious. +% Fortunately, \lstpkg{} allows its users to define a character as a shorthand +% for inline code via the |\lstMakeShortInline| macro. +% For instance, you could define the double-quote character~(|"|) as a +% shorthand for inline \matlab{} code with +%^^A +% \begin{verbatim} +% \lstMakeShortInline[style=Matlab-editor]"\end{verbatim} +%^^A +% and you would then be able to typeset this "break" keyword simply by writing +%^^A +% \begin{verbatim} +% "break"\end{verbatim} +%^^A +% in your |tex| file (but outside displayed listings, of course). +% +% You should choose a character that does not otherwise occur in your +% |tex| file, especially in the inline \matlab{} code itself, +% or you run the risk of confusing \TeX{}. +% I find that, in general, the double-quote character~(|"|) offers a good +% compromise. +% If necessary, you can undefine a character as a shorthand for inline code, +% via \lstpkg{}' |\lstDeleteShortInline| macro. +% For more details, see subsection~4.17 in the \lstpkg{} manual. +% +% +% \subsection{Placeholders} +% +% Code-snippet placeholders, such as \ph{initial-value}, are particularly +% useful for educational purposes, e.g.\ to describe the syntax of a +% programming language to students. +% The following macro allows you to typeset such placeholders, both +% inside and outside listings: +%^^A +% \begin{syntax} +% +% \item[0.1] \rcmdname\mlplaceholder|{|\meta{placeholder content}|}| +% +% typesets a code-snippet placeholder. +% You can use this macro both inside and outside listings. +% When used inside listings, it must be invoked within an +% \emph{escape to \LaTeX{}}; see subsection~4.14 of the \lstpkg{} manual. +% +% \end{syntax} +% +% If you choose to define a single character for escaping to \LaTeX{} (via +% \lstpkg{}' \keyname{escapechar} key), I recommend you define +% either the double-quote character~(|"|) +% or the backtick character~(\texttt{\`{}}) +% as escape character, +% because neither is allowed in \matlab{} statements and expressions^^A +% ---although they may occur in \matlab{} string literals. +% Note that using~|"| both as shorthand for inline code and as an +% escape-to-\LaTeX{} character inside listings is perfectly allowed. +% +% The following example illustrates how placeholders may be used to describe +% the syntax of the \matlab{} while loop. +%^^A +% \begin{lstsample}{}{\lstset{style=nonbnoframe}} +% \begin{lstlisting}[ +% style=Matlab-editor, +% basicstyle=\mlttfamily, +% escapechar=`, +% ] +% while `\mlplaceholder{condition}` +% if `\mlplaceholder{something-bad-happens}` +% break +% else +% % do something useful +% end +% end +% \end{lstlisting} +% \end{lstsample} +% +% For convenience, you can of course define a custom macro with a shorter +% name for typesetting placeholders, e.g.~|\ph|: +%^^A +% \begin{verbatim} +% \newcommand\ph\mlplaceholder\end{verbatim} +% +% +% \section{Advanced customization} +% +% The \lstpkg{} package provides a large number of options accessible via a +% nifty key-value interface, which is described in its excellent +% \href{http://www.ctan.org/pkg/listings}{documentation}. +% The \mlpkg{} package extends \lstpkg{}' key-value interface interface by +% defining several additional keys that allow you to customize the style of +% your \matlab{} listings, should you wish to do so. +% All the keys provided by \mlpkg{} are prefixed by ``|ml|'', +% to help you distinguish them from native \lstpkg{} keys. +% +% +% \subsection{Keys from the \lstpkg{} that you should not use} +% +% The great majority of keys provided by \lstpkg{} can be used in conjunction +% with keys provided by \mlpkg{} without any detrimental side effects, +% but there are a few exceptions that you should keep in mind. +% +% Some \mlpkg{} keys rely on \lstpkg{} keys ``under the hood'', +% and using those \mlpkg{} and \lstpkg{} keys in conjunction is +% \emph{strongly discouraged}, +% because doing so has the potential to wreak havok on the syntax highlighting +% of \matlab{} listings. +% It would be like \emph{crossing the streams}: it would be \emph{bad}! +% +% For instance, if you want to change the way \matlab{} keywords are typeset, +% you should use the dedicated \mlpkg{} key called \rkeyname{mlkeywordstyle} +% and eschew the \lstpkg{} key called \keyname{keywordstyle}. +% More generally, if \lstpkg{} provides a key called \meta{something} and +% \mlpkg{} provides a key called |ml|\meta{something}, +% customization of your \matlab{} listings should be done with the latter, not +% the former. +% +% +% \subsection{Changing the font of Matlab listings} +% +% For compatibility reasons, the \mlpkg{} package uses the Computer Modern +% typewriter font by default. +% However, this font is far from ideal, +% because it doesn't come with a boldface version, +% and the \matlab{} editor does display some elements of \matlab{} syntax +% (section titles) in boldface. +% Therefore, I encourage you to switch to your preferred ``programmer font'' +% instead; how to do that depends on which typesetting engine you use. +% +% For |pdflatex| users, +% \mlpkg{} conveniently provides a macro for easily selecting the Bera Mono +% font---which is a popular monospaced font for listings, +% and the one I used for all listings in this manual. +%^^A +% \begin{syntax} +% +% \item[0.1] \rcmdname\mlttfamily +% +% selects the Bera Mono font (somewhat scaled down). +% +% \end{syntax} +%^^A +% To use Bera Mono in your \matlab{} listings, you must pass |\mltttfamily| to +% \lstpkg{}' \keyname{basicstyle} key (\emph{after} loading one of the three +% styles defined by \mlpkg{}) and also---this is important---^^A +% load the \pkg{fontenc} package with option \opt{T1}: +%^^A +% \begin{verbatim} +% \usepackage[T1]{fontenc}\end{verbatim} +%^^A +% +% +% \subsection{\mlpkg{}'s key-value interface} +% +% For each of the \mlpkg{} keys described below, +% the value assigned to it in the \mlsty{Matlab-editor} style is indicated +% on the right-hand side. +%^^A +% \begin{syntax} +% +% \item[0.1,\color{blue}] +% \rkeyname{mlkeywordstyle}|=|\meta{style} +% +% This key determines the style applied to \matlab{} keywords. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1,\color{black}] +% \rkeyname{mllastelementstyle}|=|\meta{style} +% +% The |end| keyword has different meanings depending on the context in +% which it occurs: +% it may be used to close a code block (e.g.\ a while loop), +% or it may stand for the last element of an array. +% In the first case, it gets highlighted in the same style as the other +% \matlab{} keywords, like so: "end". +% In the other case, it gets highlighted like ``normal text'', like so: +% \overrideEnd. +% This key determines the style of this keyword in cases where it means +% ``last element''. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1,false] +% \rkeyname{mloverride}|=|\meta{\alternative{true,false}} +% \syntaxor\rkeyname{mloverride} +% +% By default, in inline code, \mlpkg{} highlights the |end| keyword as +% the closing keyword (\emph{not} as the last-element keyword) +% and highlights the four class-definition identifiers as \matlab{} +% functions (\emph{not} as keywords), like so: +% "end", "events", "enumeration", "methods", and "properties". +% This key allows you to override the current context, so that those +% five context-sensitive keywords be typeset in the style of the +% alternative context, like so: +% \overrideEnd{}, +% \overrideEvents{}, +% \overrideEnumeration{}, +% \overrideMethods{}, +% \overrideProperties{}. +% +% \item[0.1,{\color[RGB]{160,32,240}}] +% \rkeyname{mlstringstyle}|=|\meta{style} +% +% This key determines the style applied to \matlab{} quoted and unquoted +% strings. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1,{\color[RGB]{34,139,34}}] +% \rkeyname{mlcommentstyle}|=|\meta{style} +% +% This key determines the style applied to \matlab{} to-end-of-line and +% block comments. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1,{\bfseries\color[RGB]{34,139,34}}] +% \rkeyname{mlsectiontitlestyle}|=|\meta{style} +% +% This key determines the style applied to \matlab{} section titles. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1,false] +% \rkeyname{mlshowsectionrules}|=|\meta{\alternative{true,false}} +% \syntaxor\rkeyname{mlshowsectionrules} +% +% This key determines whether an horizontal rule gets printed above each +% \matlab{} section title. +% +% \item[0.1,.05] +% \rkeyname{mlsectionrulethickness}|=|\meta{number} +% +% This key determines the thickness of the horizontal rule above each +% \matlab{} section title. +% The resulting thickness corresponds to the product of the value passed +% to this key and the length value of |\baselineskip|. +% +% \item[0.1,black!15] +% \rkeyname{mlsectionrulecolor}|=|\meta{color} +% +% This key determines the color of the horizontal rule shown above each +% \matlab{} section title. +% +% \item[0.1,{\color[RGB]{178,140,0}}] +% \rkeyname{mlsyscomstyle}|=|\meta{style} +% +% This key determines the style applied to \matlab{} system commands. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1] +% \rkeyname{mlsharedvars}|=|\meta{list of variables} +% \item[0.1] +% \rkeyname{mlmoresharedvars}|=|\meta{list of variables} +% \item[0.1] +% \rkeyname{mldeletesharedvars}|=|\meta{list of variables} +% \item[0.1,{\color[RGB]{0,163,163}}] +% \rkeyname{mlsharedvarstyle}|=|\meta{style} +% +% The first three of these four keys allow you to define, add, or remove +% (respectively) \matlab{} variables with shared scope. +% The last one determines the style applied to such variables; +% the last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.1] +% \rkeyname{mlunquotedstringdelim}|={|^^A +% \meta{opening delimiter}|}{|\meta{closing delimiter}|}| +% +% This key allows you to define delimiters +% (possibly composed of multiple characters) +% for highlighting unquoted strings; +% the delimiters themselves do not get printed in the output. +% Be aware that the special characters |{}#%\| must be escaped with a +% backslash (see item~5 in subsection~4.1 of the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}). +% Note that this key is only a tentative solution; +% automatic highlighting of unquoted strings is a planned feature for the +% next release of \mlpkg{}, which should make this key obsolete. +% +% \item[0.1,{\rmfamily\itshape\color[RGB]{209,0,86}}] +% \rkeyname{mlplaceholderstyle}|=|\meta{style} +% +% This key determines the style applied to placeholders in code snippets. +% The last token can be a one-parameter command, +% such as |\textbf| or |\underbar|. +% +% \item[0.2,true] +% \rkeyname{mlscaleinline}|=|\meta{\alternative{true,false}} +% \syntaxor\rkeyname{mlscaleinline} +% +% If this key is set, any font-size specification in the basic style is +% overriden, and inline \matlab{} code is scaled to it surroundings; +% in other words, the font size of inline \matlab{} code is made to match +% the local font size. +% +% \item[0.2,false] +% \rkeyname{mlonlyheader}|=|\meta{\alternative{true,false}} +% \syntaxor\rkeyname{mlonlyheader} +% +% If this key is set, output is dropped after the first block of +% contiguous line comments, which normally corresponds to the function's +% header, if any. +% +% \end{syntax} +% +% +% \section{Tips and tricks} +% +% Here is a list of recommendations^^A +% ---some more opinionated than others. +% \paragraph{Stick with the \mllng{} language.} +% Defining a \lstpkg{} language based on \mllng{} is discouraged, +% for the following reason: +% \mlpkg{} performs some necessary housekeeping tasks at the beginning and +% end of each listing, but only under the condition that the name of the +% language used by the listing be \mllng{}; +% therefore, \matlab{} listings are unlikely to get correctly highlighted if +% the language name differs from \mllng{}. +% +% \paragraph{Define your own style.} +% For maintainability reasons, if you're not completely satisfied with any of +% the predefined styles, you should define your own \lstpkg{} style. +% You can even base your custom style on one of the predefined styles and +% tweak it (see subsection~4.5 in the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}). +% +% \paragraph{Load the base language/style first; customize later.} +% If you want to customize the appearance of your \matlab{} listings, +% you should use \lstpkg{}' \keyname{language} key or \keyname{style} key +% before using any other (\lstpkg{} or \mlpkg{}) key, +% because loading a language or a style ``too late'' has the potential to +% wipe out most of the current settings. +% +% \paragraph{Define macros for recurring placeholders.} +% For maintainability reasons, you should define macros for oft-used +% placeholders, e.g. +%^^A +% \begin{verbatim} +% \newcommand\phcond{\mlplaceholder{condition}}\end{verbatim} +% +% \paragraph{For more highlights, use \lstpkg{}' \keyname{emph} key} +% If you want to highlight some identifiers in \matlab{} listings, use +% \lstpkg{}' \keyname{emph} key. Do \emph{not} use \lstpkg{}' +% \keyname{keywords} or \keyname{morekeywords} keys. +% +% \paragraph{Don't copy \& paste!} +% Do not encourage your readers to copy listings from their PDF viewer and +% then paste them in the \matlab{} editor. +% Unfortunately, it simply is \emph{not} a reliable way of distributing code, +% for at least three reasons: +%^^A +% \begin{itemize} +% \item copying listings than span multiple pages of a PDF document is +% tedious and error-prone; +% \item the results of copying content from a PDF for +% subsequent pasting vary widely from one PDF viewer to another; +% \item line breaks introduced by \lstpkg{} for typesetting a \matlab{} +% listing may translate to invalid \matlab{} syntax, if copied and pasted +% \emph{verbatim}. +% \end{itemize} +% +% \paragraph{Typesetting a vertically centered tilde} +% Unfortunately, not all fonts typeset the tilde character ("~") vertically +% centered---as it is in the \matlab{} editor. +% Be aware that, if you set a font for your \matlab{} listings +% (via \lstpkg{}' \keyname{basicstyle} key) that is different from \mlpkg{}'s +% default (a scaled-down version of Bera Mono), tilde characters occuring in +% your listings may get typeset vertically off-center. +% Because a good, font-independent workaround seems out of reach, +% I refer you to \url{http://tex.stackexchange.com/q/312/21891}, +% where you will find a list of ad-hoc solutions. +% +% \paragraph{Avoid literate replacements like the plague!} +% The \pkg{mcode} package predefines so-called ``literate replacements'' +% (see subsection~5.4 in the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation}), +% e.g.\ for printing~``\(\leq\)'' in place of each instance of~``"<="''. +% I deliberately chose not to define any such literate replacements in +% \mlpkg{} because I think that, rather than improving code readability, +% they have a potential to confuse and mislead your readers. +% In particular, newcomers to the programming language may not immediately +% realize that those symbols are not part of the language's syntax; +% they may ascribe literal meaning to them and attempt to reproduce them in +% their editor or IDE. +% How counterproductive! +% Of course, if you insist, you can still define your own literate +% replacements. +% +% +% \part{Miscellaneous} +% +% \section{To-do list} +% +% \paragraph{Automatic highlighting of unquoted strings} +% In the current version of \mlpkg{}, unquoted strings will only be +% highlighted as strings if you delimit them with custom delimiters +% (defined via the \rkeyname{mlunquotedstringdelim} key). +% However, I have plans to implement an automatic approach in a future +% release. +% Note that this feature will make the \rkeyname{mlunquotedstringdelim} key +% obsolete. +% +% \paragraph{Increased support for \octave{}'s syntax} +% Support for \octave{}'s idiosyncratic syntax---^^A +% e.g. |endif| and |endwhile| keywords---^^A +% will be added in a future release of \mlpkg{}. +% +% +% \section{Missing features and known issues} +% +% Although \mlpkg{} does a reasonably good job at replicating the syntax +% highlighting performed by the \matlab{} editor, some problems remain. +% Here is a list of known, currently unresolved problems. +% +% \paragraph{No automatic highlighting of variables with shared scope} +% Unfortunately, automatic highlighting of variables with shared scope +% would require multiple passes, which the \lstpkg{} package cannot do. +% However, I believe that the number of variables in your \matlab{} code +% should be small enough^^A +% ---otherwise, your \matlab{} code is probably not sound!---^^A +% that you can afford to highlight those variables manually, if you insist on +% highlighting them at all. +% +% \paragraph{No highlighting of unterminated strings} +% Because \lstpkg{} cannot look very far ahead, I haven't found an easy way of +% checking whether an opening string delimiter is missing a matching (closing) +% string delimiter on the same line. +% +% \paragraph{Illegal syntax tends to yield incorrect syntax highlighting} +% For example, the \matlab{} editor would highlight the |end| keyword in the +% listing below, not as closing keyword ("end"), but as last-element keyword +% (\overrideEnd{}). +%^^A +% \begin{lstsample}{}{\lstset{style=nonbnoframe}} +% \begin{lstlisting}[ +% style=Matlab-editor, +% basicstyle=\mlttfamily, +% numbers=none] +% if=end +% \end{lstlisting} +% \end{lstsample} +% +% \paragraph{Some section titles fail to be highlighted as such} +% In \matlab{}, a line containing only ``\texttt{\%\%}'' and blank +% characters is a section title. +% \mlpkg{} incorrectly highlights such a line in comment style. +%^^A +% \begin{lstsample}{}{\lstset{style=nonbnoframe}} +% \begin{lstlisting}[ +% style=Matlab-editor, +% numbers=none, +% basicstyle=\mlttfamily, +% numbers=none] +% %% This is a section title +% % and so is the next line +% %% +% % but it gets highlighted +% % like a comment. +% \end{lstlisting} +% \end{lstsample} +% +% \paragraph{\lstpkg{}' \keyname{keespaces} key messes up section-title rules} +% If both \lstpkg{}' \keyname{keepspaces} and \mlpkg{}'s +% \rkeyname{mlshowsectionrules} are set, section titles that start by some +% white space get pushed to the right. +%^^A +% \begin{lstsample}{}{\lstset{style=nonbnoframe}} +% \begin{lstlisting}[ +% style=Matlab-editor, +% basicstyle=\mlttfamily, +% numbers=none, +% keepspaces, +% mlshowsectionrules] +% %% the rule gets pushed to the right... +% \end{lstlisting} +% \end{lstsample} +% +% \paragraph{``Runaway'' block comments end prematurely (in some cases)} +% \matlab{} requires opening and closing delimiters of block comments to each +% be on a line on its own, without any visible character, but \mlpkg{} +% incorrectly considers block comments closed even in some cases where this +% rule is infringed. +% For example, in the listing below, the \matlab{} editor would typeset +% "a = 1" in comment style. +%^^A +% \begin{lstsample}{}{\lstset{style=nonbnoframe}} +% \begin{lstlisting}[ +% style=Matlab-editor, +% basicstyle=\mlttfamily, +% numbers=none] +% %{ +% "runaway" +% block +% comment %} +% a = 1 +% \end{lstlisting} +% \end{lstsample} +% +% +% \section{Bug reports and feature suggestions} +% +% The development version of \mlpkg{} is currently hosted on Bitbucket at +% \href{http://bitbucket.org/Jubobs/matlab-prettifier/} +% {Jubobs/matlab-prettifier}. +% If you find an issue in \mlpkg{} that this manual does not mention, +% if you would like to see a feature implemented in the package, +% or if you can think of ways in which the \mlpkg{} documentation could be +% improved, please open a ticket in the Bitbucket repository's issue tracker; +% alternatively, you can send me an email at +% \href{mailto:jubobs.matlab.prettifier@gmail.com} +% {jubobs.matlab.prettifier@gmail.com} +% +% +% \section{Acknowledgments} +% Thanks to the developers of the \lstpkg{} package, +% without which \mlpkg{} would never have existed. +% I'm also in debt to many +% \href{http://tex.stackexchange.com}{TeX.SX} users for their help, +% encouragements, and suggestions. +% Thanks in particular to David Carlisle, Marco Daniel, +% Enrico Gregorio (egreg), Harish Kumar, Heiko Oberdiek, and Robert Schlicht. +% Thanks also to the good people at \href{http://www.ctan.org}{CTAN} +% for hosting the package. +% +% +% \makeatletter +% \def\index@prologue{\part{Index}\markboth{Index}{Index}} +% \makeatother +% \StopEventually{^^A +% \clearpage^^A +% \PrintChanges^^A +% \setcounter{IndexColumns}{2}^^A +% \PrintIndex^^A +% } +% +% +% \part{Implementation} +% +% Be aware that, for ``namespacing'', the \mlpkg{} package uses, not a prefix, +% but the ``|mlpr|''~suffix (preceded by an |@| character) throughout. +% +% +% \section{Preliminary checks} +% +% \begin{macro}{\lstoptcheck@mlpr} +% Because the \lstpkg{} options \opt{noaspects}, \opt{0.21}, and +% \opt{savemem} are incompatible with \pkg{matlab-prettifier}, checking +% whether the \lstpkg{} package has been loaded with any of those options is +% a good idea; if so, we should issue an error. +% This macro checks whether \lstpkg{} was loaded with a given option +% and, if so, throws an error. +% \begin{macrocode} +\newcommand\lstoptcheck@mlpr[1] +{% + \@ifpackagewith{listings}{#1}% + { + \PackageError{matlab-prettifier}% + {incompatible listings' option #1}% + {% + Make sure the `listings' package + doesn't get loaded with option `#1'% + } + } + {} +} +% \end{macrocode} +% \end{macro} +% We now use this macro to make sure that none of the problematic \lstpkg{} +% options has been passed to \lstpkg{} during an earlier loading of that +% package. +% \begin{macrocode} +\lstoptcheck@mlpr{noaspects} +\lstoptcheck@mlpr{0.21} +\lstoptcheck@mlpr{savemem} +% \end{macrocode} +% +% +% \section{Package options} +% +% \paragraph{Framed listings} +% \begin{macro}{\ifframed@mlpr@} +% This option draws a frame around each listing by default. +% \begin{macrocode} +\newif\ifframed@mlpr@ +\DeclareOption{framed}{\framed@mlpr@true} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Numbered lines} +% \begin{macro}{\ifnumbered@mlpr@} +% This option prints line numbers to the left of each listing by default. +% \begin{macrocode} +\newif\ifnumbered@mlpr@ +\DeclareOption{numbered}{\numbered@mlpr@true} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Draft} +% This option is simply passed to \lstpkg{}. +% \begin{macrocode} +\DeclareOption{draft}{\PassOptionsToPackage{\CurrentOption}{listings}} +% \end{macrocode} +% +% \paragraph{Final} +% This option is simply passed to \lstpkg{}. +% \begin{macrocode} +\DeclareOption{final}{\PassOptionsToPackage{\CurrentOption}{listings}} +% \end{macrocode} +% +% \paragraph{Discard undefined options} +% We discard any other option passed to \mlpkg{} by the user +% and issue a warning. +% \begin{macrocode} +\DeclareOption*% +{% + \OptionNotUsed + \PackageWarning{matlab-prettifier}{Unknown `\CurrentOption' option} +} +% \end{macrocode} +% \paragraph{Process options} +% \begin{macrocode} +\ProcessOptions\relax +% \end{macrocode} +% +% +% \section{Required packages} +% +% The \mlpkg{} package require three packages without any package option: +% the \pkg{textcomp} package, in order to use \lstpkg{}' \keyname{upquote} +% key; +% the \pkg{xcolor} package, in order to color our \matlab{} code; +% and, of course, the \lstpkg{} package. +% \begin{macrocode} +\RequirePackage{textcomp}[2005/09/27] +\RequirePackage{xcolor}[2007/01/21] +\RequirePackage{listings}[2013/08/26] +% \end{macrocode} +% +% +% \section{Definition of the \texorpdfstring{\mllng}{Matlab-pretty} language} +% +% \paragraph{Language name} +% \begin{macro}{\language@mlpr} +% To avoid code duplication in this package file, we define a macro that +% expands to the name of our new language, \mllng{}. +% \begin{macrocode} +\newcommand\language@mlpr{Matlab-pretty} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\languageNormedDefd@mlpr} +% However, because \lstpkg{} ``normalizes'' language names internally, +% we will also need to define a macro that expands to the normalized name of +% the new language. +% \begin{macrocode} +\expandafter\lst@NormedDef\expandafter\languageNormedDefd@mlpr% + \expandafter{\language@mlpr} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Language definition} +% We can now define our new \lstpkg{} language, using some |\expandafter| +% trickery on |\lstdefinelanguage|. +% \begin{macrocode} +\expandafter\expandafter\expandafter\lstdefinelanguage\expandafter% +{\language@mlpr} +{% +% \end{macrocode} +% +% \paragraph{Case sensitivity} +% \matlab{} is a case-sensitive language. +% \begin{macrocode} + sensitive=true, +% \end{macrocode} +% +% \paragraph{Forbidden characters in identifiers} +% By default, \lstpkg{} allows ``\$'' and ``@'' to occur in identifiers, +% but those characters are not valid \matlab{} identifiers. +% \begin{macrocode} + alsoother={\$@}, +% \end{macrocode} +% +% \paragraph{Character-table adjustments} +% In order to keep track of the context, we need to modify the character +% table a bit. +% \begin{macrocode} + MoreSelectCharTable=\MoreSelectCharTable@mlpr, +% \end{macrocode} +% +% \paragraph{Keywords} +% +% The keywords defined below are based on the list returned by the +% \matlabver{} "iskeyword" function and the four class-definition keywords^^A +% ---which are omitted by the "iskeyword" function. +% Because different \matlab{} keywords affect the context in different ways, +% we use several classes of \pkg{listings} keywords to handle them. +% +% The following keywords open a block unrelated to class definition. +% \begin{macrocode} + morekeywords=[1]% + {% + for, + if, + otherwise, + parfor, + spmd, + switch, + try, + while, + }, + keywordstyle=[1]\processOpRegKW@mlpr, +% \end{macrocode} +% Most of the following keywords (nicknamed ``middle'' keywords herein) can +% only occur within a block opened by the keywords listed above^^A +% ---"function" and "return" are exceptions, but, as far as I can tell, +% seem to have the same effects on syntax highlighting as the others---^^A +% and are unrelated to class definition. +% \begin{macrocode} + morekeywords=[2]% + {% + break, + case, + catch, + continue, + else, + elseif, + function, + return, + }, + keywordstyle=[2]\processMidKW@mlpr, +% \end{macrocode} +% The following two keywords are ``standalone''; +% they don't open or close any block. +% \begin{macrocode} + morekeywords=[3]% + {% + global, + persistent, + }, + keywordstyle=[3]\processStdaKW@mlpr, +% \end{macrocode} +% The "classdef" keyword interacts with other keywords in a unique fashion; +% therefore, we dedicate a whole class of \lstpkg{} keywords to it. +% \begin{macrocode} + morekeywords=[4]{classdef}, + keywordstyle=[4]\processClassdefKW@mlpr, +% \end{macrocode} +% We dedicate a class of \lstpkg{} keywords to the four \matlab{} keywords +% that only occur within a class-definition block, +% namely \overrideEvents{}, \overrideEnumeration{}, \overrideMethods{}, +% and \overrideProperties{}. +% \begin{macrocode} + morekeywords=[5]% + {% + enumeration, + events, + methods, + properties, + }, + keywordstyle=[5]\processMidClassdefKW@mlpr, +% \end{macrocode} +% The |end| keyword has a very peculiar behavior and deserves its own keyword +% class. +% \begin{macrocode} + morekeywords=[6]{end}, + keywordstyle=[6]\processEndKW@mlpr, +% \end{macrocode} +% +% \paragraph{Strings} +% We simply use \lstpkg{}' built-in mechanism for highlighting \matlab{} +% quoted string\ldots with a twist; more details follow. +% \begin{macrocode} + morestring=[m]', + stringstyle=\processString@mlpr, +% \end{macrocode} +% +% \paragraph{Comments \& section titles} +% Delimiters for to-end-of-line and block comments are defined below. +% \begin{macrocode} + morecomment=[l]\%, + morecomment=[n]{\%\{\^^M}{\%\}\^^M}, + commentstyle=\commentStyle@mlpr, +% \end{macrocode} +% The line-continuation token ("..."), which starts a to-end-of-line comment, +% is treated separately. +% \begin{macrocode} + moredelim=**[il][\processDotDotDot@mlpr]{...}, +% \end{macrocode} +% Section titles, as special comments that get highlighted in a style +% different to that of regular comments, must also be treated separately. +% \begin{macrocode} + moredelim=[l][\processSectionTitle@mlpr]{\%\%\ }, +% \end{macrocode} +% +% \paragraph{System commands} +% System commands are handled in a straightforward manner by an |l|-type +% delimiter. +% \begin{macrocode} + moredelim=[l][\syscomStyle@mlpr]!, +% \end{macrocode} +% +% \paragraph{Required \lstpkg{} aspects} +% We now only need to specify the required \lstpkg{} ``aspects''. +% \begin{macrocode} +}[ + keywords, + strings, + comments, +] +% \end{macrocode} +% +% +% \section{State variables} +% We define a number of \TeX{} counters and switches that will be used as +% ``state variables'', to keep track of the context. +% +% \paragraph{Counters} +% \begin{macro}{\netBracketCount@mlpr} +% This counter is used to keep a net running count of opening and closing +% brackets---roughly speaking. +% When an opening bracket---be it round, square or curly---is encountered, +% the counter is incremented; +% conversely, when a closing bracket is encountered, the counter is +% decremented. +% I write ``roughly speaking'', because that counter gets reset on some +% occasions; more details follow. +% \begin{macrocode} +\newcount\netBracketCount@mlpr +% \end{macrocode} +% \end{macro} +% \begin{macro}{\blkLvl@mlpr} +% This counter counter is used to keep track of the block nesting level. +% \begin{macrocode} +\newcount\blkLvl@mlpr +% \end{macrocode} +% \end{macro} +% \begin{macro}{\blkLvlAtClassdef@mlpr} +% This counter is used to keep track of the block nesting level at which the +% last "classdef" keyword occured. +% \begin{macrocode} +\newcount\blkLvlAtClassdef@mlpr +% \end{macrocode} +% \end{macro} +% +% \paragraph{Switches} +% \begin{macro}{\ifClosingEndKW@mlpr@} +% This switch determines whether the |end| keyword acts as a closing keyword +% or as last-element keyword in the current context. +% \begin{macrocode} +\newif\ifClosingEndKW@mlpr@ \ClosingEndKW@mlpr@true +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifInClassdef@mlpr@} +% This switch determines whether we're within a class-definition block or not. +% \begin{macrocode} +\newif\ifInClassdef@mlpr@ \InClassdef@mlpr@false +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifInStr@mlpr@} +% This switch determines whether we're inside a string or not. +% \begin{macrocode} +\newif\ifInStr@mlpr@ \InStr@mlpr@false +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifVisCharOccured@mlpr@} +% This switch is used to keep track of whether visible characters have +% occured on the current line. +% \begin{macrocode} +\newif\ifVisCharOccured@mlpr@\VisCharOccured@mlpr@false +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifInSecTitle@mlpr@} +% This switch determines whether we're inside a section title or not. +% \begin{macrocode} +\newif\ifInSecTitle@mlpr@ \InSecTitle@mlpr@false +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifDroppingOutput@mlpr@} +% This switch determines whether we're passed the first contiguous block of +% line comments (function header). +% \begin{macrocode} +\newif\ifDroppingOutput@mlpr@\DroppingOutput@mlpr@false +% \end{macrocode} +% \end{macro} +% +% \paragraph{Helper macros for resetting state variables} +% The following macros are used to reset counters and switches. +% \begin{macro}{\resetEndKW@mlpr} +% This macro restores the |end| keyword as a closing keyword. +% \begin{macrocode} +\newcommand\resetEndKW@mlpr +{% + \global\ClosingEndKW@mlpr@true% + \global\netBracketCount@mlpr=0% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\resetClassdefKW@mlpr} +% This macro reinitializes state variables related to class definition. +% \begin{macrocode} +\newcommand\resetClassdefKW@mlpr +{% + \global\InClassdef@mlpr@false% + \global\blkLvl@mlpr=0% + \global\blkLvlAtClassdef@mlpr=0% +} +% \end{macrocode} +% \end{macro} +% +% +% \section{Processing of syntactic elements} +% +% (The overarching algorithm is not documented here; +% in a future release, perhaps.) +% +% \paragraph{Processing of brackets} +% An opening and or a closing brackets occuring in a \matlab{} listing affects +% the context; +% for instance, an |end| keyword is always interpreted as a closing keyword if +% it is immediately preceded by a closing bracket, no matter what comes +% before that. +% To keep track of the context, we must update our state variables every time +% a bracket is encountered. +% +% \begin{macro}{\MoreSelectCharTable@mlpr} +% This macro, which is passed to \lstpkg{}' \keyname{MoreSelectCharTable} key +% in the definition of \mllng{}, allows us to dictate what happens when a +% bracket or a semicolon is encountered. +% \begin{macrocode} +\newcommand\MoreSelectCharTable@mlpr +{% +% \end{macrocode} +% +% \begin{macro}{\roundBktOp@mlpr} +% We store the original definition of ``|(|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processOpenBracket@mlpr{`(}{\roundBktOp@mlpr}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\squareBktOp@mlpr} +% We store the original definition of ``|[|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processOpenBracket@mlpr{`[}{\squareBktOp@mlpr}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\curlyBktOp@mlpr} +% We store the original definition of ``|{|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processOpenBracket@mlpr{`\{}{\curlyBktOp@mlpr}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\roundBktCl@mlpr} +% We store the original definition of ``|)|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processCloseBracket@mlpr{`)}{\roundBktCl@mlpr}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\squareBktCl@mlpr} +% We store the original definition of ``|]|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processCloseBracket@mlpr{`]}{\squareBktCl@mlpr}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\curlyBktCl@mlpr} +% We store the original definition of ``|}|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processCloseBracket@mlpr{`\}}{\curlyBktCl@mlpr}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\semicolon@mlpr} +% We store the original definition of ``|;|'' from the default character +% table in a dedicated macro and modify the behavior of that character. +% \begin{macrocode} + \processSemicolon@mlpr{`;}{\semicolon@mlpr}% +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\processOpenBracket@mlpr} +% This macro is used to ``hook into'' opening-bracket characters and update +% state variables every time such a character is encountered in \lstpkg{}' +% ``processing mode''. +% \begin{macrocode} +\newcommand\processOpenBracket@mlpr[2] +{% + \lst@DefSaveDef{#1}#2% + {% + #2% + \ifnum\lst@mode=\lst@Pmode\relax% + \global\ClosingEndKW@mlpr@false% + \global\advance\netBracketCount@mlpr by \@ne% + \fi + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\processCloseBracket@mlpr} +% This macro is used to ``hook into'' closing-bracket characters and update +% state variables every time such a character is encountered in \lstpkg{}' +% ``processing mode''. +% \begin{macrocode} +\newcommand\processCloseBracket@mlpr[2] +{% + \lst@DefSaveDef{#1}#2% + {% + #2% + \ifnum\lst@mode=\lst@Pmode\relax% + \ifClosingEndKW@mlpr@% + \netBracketCount@mlpr=0% + \else + \global\advance\netBracketCount@mlpr by \m@ne% + \ifnum\netBracketCount@mlpr>0% + \else + \global\ClosingEndKW@mlpr@true% + \fi + \fi + \fi + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\processSemicolon@mlpr} +% This macro is used to ``hook into'' the semicolon character and update +% state variables every time such a character is encountered in \lstpkg{}' +% ``processing mode''. +% \begin{macrocode} +\newcommand\processSemicolon@mlpr[2] +{% + \lst@DefSaveDef{#1}#2% + {% + #2% + \ifnum\lst@mode=\lst@Pmode\relax% + \resetEndKW@mlpr% + \fi + }% +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Processing of keywords} +% The following macros are used for updating state variables every time a +% keyword is encountered in \lstpkg{} ``processing mode''. +% +% \begin{macro}{\processOpRegKW@mlpr} +% This macro updates state variables every time an opening keyword is +% processed, and applies keyword style. +% \begin{macrocode} +\newcommand\processOpRegKW@mlpr +{% + \resetEndKW@mlpr% + \global\advance\blkLvl@mlpr\@ne% + \keywordStyle@mlpr% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\processMidKW@mlpr} +% This macro updates state variables every time a ``middle'' keyword is +% processed, and applies keyword style. +% \begin{macrocode} +\newcommand\processMidKW@mlpr +{% + \resetEndKW@mlpr% + \keywordStyle@mlpr% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\processStdaKW@mlpr} +% As far as I can tell, ``standalone'' keywords and ``middle'' keywords +% affect the context in the same way; +% therefore, we simply reuse |\processMidKW@mlpr| here. +% \begin{macrocode} +\newcommand\processStdaKW@mlpr\processMidKW@mlpr +% \end{macrocode} +% \end{macro} +% \begin{macro}{\processClassdefKW@mlpr} +% This macro updates state variables every time the "classdef" keyword is +% processed, and applies keyword style. +% \begin{macrocode} +\newcommand\processClassdefKW@mlpr +{% + \resetEndKW@mlpr% + \global\InClassdef@mlpr@true% + \global\blkLvlAtClassdef@mlpr=\blkLvl@mlpr% + \global\advance\blkLvl@mlpr\@ne% + \keywordStyle@mlpr% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\processMidClassdefKW@mlpr} +% This macro updates state variables every time one of the four keywords +% that only occur within a class-definition block is processed, and applies +% the appropriate style. +% \begin{macrocode} +\newcommand\processMidClassdefKW@mlpr +{% + \ifOverridecontext@mlpr@% + \keywordStyle@mlpr% + \else + \ifInClassdef@mlpr@% + \resetEndKW@mlpr% + \global\advance\blkLvl@mlpr\@ne% + \keywordStyle@mlpr% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\processEndKW@mlpr} +% This macro updates state variables every time the |end| keyword is +% processed, and applies the appropriate style. +% \begin{macrocode} +\newcommand\processEndKW@mlpr +{% + \ifOverridecontext@mlpr@% + \lastElemStyle@mlpr% + \else + \ifClosingEndKW@mlpr@% + \ifnum\blkLvl@mlpr>0% + \global\advance\blkLvl@mlpr\m@ne% + \fi + \ifnum\blkLvl@mlpr=\blkLvlAtClassdef@mlpr% + \global\InClassdef@mlpr@false% + \fi + \keywordStyle@mlpr% + \else + \lastElemStyle@mlpr% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Processing of strings} +% \begin{macro}{\processString@mlpr} +% This macro records that a string has just started by setting the appropriate +% switch, and applies string style. +% \begin{macrocode} +\newcommand\processString@mlpr +{% + \global\InStr@mlpr@true% + \stringStyle@mlpr% +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Processing of line-continuation tokens} +% \begin{macro}{\processDotDotDot@mlpr} +% This macro typesets the line-continuation token in the style of our +% \matlab{} keywords, +% prohibits any mode changes on the rest of the current line, +% and applies comment style to the rest of the current line. +% \begin{macrocode} +\newcommand\processDotDotDot@mlpr +{% + \lst@CalcLostSpaceAndOutput% + {\keywordStyle@mlpr...}% + \lst@modetrue% + \lst@Lmodetrue% + \commentStyle@mlpr% +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Processing of section titles} +% First, we need to define a few length macros in order to draw the horizontal +% rule that \matlab{} shows (by default) above each section title. +% \begin{macro}{\emHeight@mlpr} +% We will use this length to store the height of the ``M'' character in the +% current font. +% \begin{macrocode} +\newlength\emHeight@mlpr +% \end{macrocode} +% \end{macro} +% \begin{macro}{\jayDepth@mlpr} +% We will use this length to store the depth of letter ``j'' in the current +% font. +% \begin{macrocode} +\newlength\jayDepth@mlpr +% \end{macrocode} +% \end{macro} +% \begin{macro}{\sectionRuleOffset@mlpr} +% We will use this length to store the result of our calculations for the +% vertical offset required. +% \begin{macrocode} +\newlength\sectionRuleOffset@mlpr +% \end{macrocode} +% \end{macro} +% Let's proceed\ldots +% \begin{macro}{\processSectionTitle@mlpr} +% This macro is invoked when a |%%| delimiter is encountered. +% \begin{macrocode} +\newcommand\processSectionTitle@mlpr +{% + \ifInSecTitle@mlpr@% + \sectionTitleStyle@mlpr% + \else +% \end{macrocode} +% If visible characters have already been encountered before the |%%| on the +% current line, this line is simply typeset as a to-end-of-line comment. +% \begin{macrocode} + \ifVisCharOccured@mlpr@% + \commentStyle@mlpr% +% \end{macrocode} +% Otherwise, a section title starts here; +% we update the relevant state variables and, if the +% \rkeyname{mlshowsectionrules} key has been set, we draw a horizontal rule. +% \begin{macrocode} + \else % a section title is starting here + \global\InSecTitle@mlpr@true% + \resetEndKW@mlpr% + \ifShowSectRules@mlpr@% + \drawSectionRule@mlpr% + \fi + \sectionTitleStyle@mlpr% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\drawSectionRule@mlpr} +% This helper macro is used for drawing a horizontal rule just above the +% current line. +% \begin{macrocode} +\newcommand\drawSectionRule@mlpr +{% +% \end{macrocode} +% We measure the height of the ``M'' character and the depth of the ``j'' +% character, which we then use to calculate the required vertical offset. +% \begin{macrocode} + \setlength\emHeight@mlpr{\fontcharht\font`M}% + \setlength\jayDepth@mlpr{\fontchardp\font`j}% + \setlength\sectionRuleOffset@mlpr% + {% + \dimexpr.5\emHeight@mlpr% + +.5\baselineskip% + -.5\jayDepth@mlpr\relax% + }% +% \end{macrocode} +% We now draw a rule as required (color and dimensions). +% \begin{macrocode} + \bgroup% + \color{\sectionRuleColor@mlpr}% + \makebox[0em][l]% + {% + \raisebox{\sectionRuleOffset@mlpr}[0pt][0pt]% + {\rule{\lst@linewidth}{\sectionRuleRT@mlpr\baselineskip}}% + }% + \egroup% +} +% \end{macrocode} +% \end{macro} +% +% \section{Hooking into \lstpkg{}' hooks} +% +% We apply some necessary patches in a number of \lstpkg{}' hooks; +% but first, we define a few helper macros. +% +% \paragraph{Helper macros related to hooks} +% \begin{macro}{\localFontSize@mlpr} +% This macro will be used to save the current font size. +% \begin{macrocode} +\newcommand\localFontSize@mlpr{} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\localBaselineskip@mlpr} +% This macro will be used to save the current value of |\baselineskip|. +% \begin{macrocode} +\newcommand\localBaselineskip@mlpr{} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\scaleInlineCode@mlpr} +% This helper macro is for setting the font size of inline code to the local +% font size (only if the \rkeyname{mlscaleinline} key is set). +% \begin{macrocode} +\newcommand\scaleInlineCode@mlpr +{% + \lst@ifdisplaystyle% + \else + \ifScaleInline@mlpr@% +% \end{macrocode} +% We save the values of the current font size and of |\baselineskip| into our +% dedicated macros\ldots +% \begin{macrocode} + \let\localFontSize@mlpr\f@size% + \let\localBaselineskip@mlpr\f@baselineskip% +% \end{macrocode} +% \ldots and we use the basic style but we update the font size. +% \begin{macrocode} + \expandafter\def\expandafter\lst@basicstyle\expandafter% + {% + \lst@basicstyle% + \fontsize{\localFontSize@mlpr}{\localBaselineskip@mlpr}% + \selectfont% + }% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\dropOutputAfterHeader@mlpr} +% This macro detects when the first block (if any) of contiguous of line +% comments (function header) ends and drops output thereafter. +% \begin{macrocode} +\newcommand\dropOutputAfterHeader@mlpr +{% + \ifonlyheader@mlpr@% + \ifnum\lst@lineno>1% + \lst@ifLmode% + \else +% \end{macrocode} +% At this stage, the header has definitely ended. +% If we've already begun dropping output, we don't do anything. +% \begin{macrocode} + \ifDroppingOutput@mlpr@% +% \end{macrocode} +% Otherwise, we begin dropping output now and we set the switch accordingly. +% \begin{macrocode} + \else + \lst@EnterMode\lst@Pmode{}% + \lst@BeginDropOutput\lst@Pmode% + \fi + \global\DroppingOutput@mlpr@true% +% \end{macrocode} +% \begin{macrocode} + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{InitVarsEOL}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% \begin{macro}{\addedToInitVarsEOL@mlpr} +% We add this macro (initially empty) to \lstpkg{}' +% \hookname{InitVarsEOL} hook. +% \begin{macrocode} +\newcommand\addedToInitVarsEOL@mlpr{} +\lst@AddToHook{InitVarsEOL}{\addedToInitVarsEOL@mlpr} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ddedToInitVarsEOL@mlpr} +% The |\addedToInitVarsEOL@mlpr| macro is let to this one under certain +% conditions (more details follow). +% \begin{macrocode} +\newcommand\@ddedToInitVarsEOL@mlpr +{% +% \end{macrocode} +% \lstpkg{}' built-in mechanism for handling \matlab{} string does not cover +% the illegal case in which an opening string delimiter is not followed by +% any matching (closing) string delimiter on the same line. +% More specifically, \lstpkg{} incorrectly highlights such a broken string +% literal as a bona-fide \matlab{} string. +% We improve the situation somewhat, by only highlighting as a string the line +% containing the unmatched opening delimiter, not the lines that follow it: +% \begin{macrocode} + \ifInStr@mlpr@% + \global\InStr@mlpr@false% + \lst@LeaveMode% + \fi +% \end{macrocode} +% Clearly, at the very beginning of a line, we're not (not yet, anyway) +% within a section title, and no visible character has yet occured on that +% line. +% \begin{macrocode} + \global\InSecTitle@mlpr@false% + \global\VisCharOccured@mlpr@false% +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{EndGroup}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% \begin{macro}{\addedToEndGroup@mlpr} +% We add this macro (initially empty) to \lstpkg{}' +% \hookname{EndGroup} hook. +% \begin{macrocode} +\newcommand\addedToEndGroup@mlpr{} +\lst@AddToHook{EndGroup}{\addedToEndGroup@mlpr} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ddedToEndGroup@mlpr} +% The |\addedToEndGroup@mlpr| macro is let to this one under certain +% conditions (more details follow). +% If we were in a string before when \hookname{EndGroup} hook was called, +% we're now exiting it; +% therefore, the relevant switch must be reset. +% \begin{macrocode} +\newcommand\@ddedToEndGroup@mlpr{\global\InStr@mlpr@false} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{PostOutput}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% \begin{macro}{\addedToPostOutput@mlpr} +% We add this macro (initially empty) to \lstpkg{}' +% \hookname{PostOutput} hook. +% \begin{macrocode} +\newcommand\addedToPostOutput@mlpr{} +\lst@AddToHook{PostOutput}{\addedToPostOutput@mlpr} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ddedToPostOutput@mlpr} +% The |\addedToPostOutput@mlpr| macro is let to this one under certain +% conditions (more details follow). +% If the last processed character was not white space +% (this check is necessary if \lstpkg{}' \keyname{keepspaces} key is set), +% we set the relevant switch. +% \begin{macrocode} +\newcommand\@ddedToPostOutput@mlpr +{% + \lst@ifwhitespace% + \else + \global\VisCharOccured@mlpr@true% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{Output}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% \begin{macro}{\addedToOutput@mlpr} +% We add this macro (initially empty) to \lstpkg{}' +% \hookname{Output} hook. +% \begin{macrocode} +\newcommand\addedToOutput@mlpr{} +\lst@AddToHook{Output}{\addedToOutput@mlpr} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ddedToOutput@mlpr} +% The |\addedToOutput@mlpr| macro is let to this one under certain +% conditions (more details follow). +% If the \rkeyname{mlonlyheader} is set, we begin dropping output as soon as +% we detect that the first contiguous block of line comments has been passed. +% \begin{macrocode} +\newcommand\@ddedToOutput@mlpr{\dropOutputAfterHeader@mlpr} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{OutputOther}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% \begin{macro}{\addedToOutputOther@mlpr} +% We add this macro (initially empty) to \lstpkg{}' +% \hookname{OutputOther} hook. +% \begin{macrocode} +\newcommand\addedToOutputOther@mlpr{} +\lst@AddToHook{OutputOther}{\addedToOutputOther@mlpr} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@ddedToOutputOther@mlpr} +% The |\addedToOutputOther@mlpr| macro is let to this one under certain +% conditions (more details follow). +% If the \rkeyname{mlonlyheader} is set, we begin dropping output as soon as +% we detect that the first contiguous block of line comments has been passed. +% \begin{macrocode} +\newcommand\@ddedToOutputOther@mlpr{\dropOutputAfterHeader@mlpr} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{PreInit}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% Because the |\lst@AddToHook| affects hooks globally +% (i.e.\ for all listings), +% we must apply our patches only when required, i.e.\ +% in listings that use \mllng{}, and not in others. +% The \hookname{PreInit}, which is called at the very beginning of each +% listing, is where we do that. +% \begin{macro}{\addedToPreInitHook@mlpr} +% In this macro, which we add to \lstpkg{}' \hookname{PreInit} hook, we check +% whether |\lst@language| and |\languageNormedDefd@mlpr| expand (once) to the +% same replacement text and only apply our patches under that condition. +% \begin{macrocode} +\newcommand\addedToPreInitHook@mlpr +{% + \ifx\lst@language\languageNormedDefd@mlpr% + \scaleInlineCode@mlpr% + \renewcommand\addedToInitVarsEOL@mlpr\@ddedToInitVarsEOL@mlpr% + \renewcommand\addedToEndGroup@mlpr\@ddedToEndGroup@mlpr% + \renewcommand\addedToPostOutput@mlpr\@ddedToPostOutput@mlpr% + \renewcommand\addedToOutput@mlpr\@ddedToOutput@mlpr% + \renewcommand\addedToOutputOther@mlpr\@ddedToOutputOther@mlpr% + \DroppingOutput@mlpr@false% +\fi +} +\lst@AddToHook{PreInit}{\addedToPreInitHook@mlpr} +% \end{macrocode} +% \end{macro} +% +% \paragraph{\hookname{DeInit}} +% (See the +% \href{http://www.ctan.org/pkg/listings}{\lstpkg{} documentation} +% for more details on this hook.) +% In the \hookname{DeInit} hook, which is called at the very end of each +% listing, we carry out some housekeeping tasks if the current listing uses +% \mllng{}. +% \begin{macro}{\addedToDeInitHook@mlpr} +% In this macro, which we add to \lstpkg{}' \hookname{DeInit} hook, we check +% whether |\lst@language| and |\languageNormedDefd@mlpr| expand (once) to the +% same replacement text and, under that condition, we reset all state +% variables. +% \begin{macrocode} +\newcommand\addedToDeInitHook@mlpr +{% + \ifx\lst@language\languageNormedDefd@mlpr% + \resetEndKW@mlpr% + \resetClassdefKW@mlpr% + \global\InStr@mlpr@false% + \global\VisCharOccured@mlpr@false% + \global\InSecTitle@mlpr@false% + \global\DroppingOutput@mlpr@false% + \fi +} +\lst@AddToHook{DeInit}{\addedToDeInitHook@mlpr} +% \end{macrocode} +% \end{macro} +% +% +% \section{Key-value interface} +% +% We extend \lstpkg{}' key-value interface by defining several additional +% keys, which we will use to define three \lstpkg{} styles, and which will +% allow the user to customize the style of their \matlab{} listings, +% should they which to do so. +% All \mlpkg{} keys are prefixed by~``|ml|'', so that the user can easily +% distinguish them from ``native'' \lstpkg{} keys. +% +% \paragraph{Keywords} +% \begin{lstkey}{mlkeywordstyle} +% \begin{macro}{\keywordStyle@mlpr} +% In the definition of \mllng{}, we used several classes of \lstpkg{} +% keywords to handle the different \matlab{} keywords; +% here is a style key to ``rule them all''. +% \begin{macrocode} +\newcommand\keywordStyle@mlpr{} +\lst@Key{mlkeywordstyle}\relax% + {\renewcommand\keywordStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \begin{lstkey}{mllastelementstyle} +% \begin{macro}{\lastElemStyle@mlpr} +% This key determines the style applied to the last-element keyword. +% \begin{macrocode} +\newcommand\lastElemStyle@mlpr{} +\lst@Key{mllastelementstyle}\relax% + {\renewcommand\lastElemStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \begin{lstkey}{mloverride} +% \begin{macro}{\ifOverridecontext@mlpr@} +% This key overrides the current context, so that context-sensitive +% keywords be typeset in the style associated with the alternative context. +% \begin{macrocode} +\lst@Key{mloverride}{false}[t]% + {\lstKV@SetIf{#1}\ifOverridecontext@mlpr@} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \paragraph{Strings} +% \begin{lstkey}{mlstringstyle} +% \begin{macro}{\stringStyle@mlpr} +% This key determines the style applied to \matlab{} (quoted and unquoted) +% strings. +% \begin{macrocode} +\newcommand\stringStyle@mlpr{} +\lst@Key{mlstringstyle}\relax% + {\renewcommand\stringStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \paragraph{Comments} +% \begin{lstkey}{mlcommentstyle} +% \begin{macro}{\commentStyle@mlpr} +% This key determines the style applied to \matlab{} +% (to-end-of-line and block) comments. +% \begin{macrocode} +\newcommand\commentStyle@mlpr{} +\lst@Key{mlcommentstyle}\relax% + {\renewcommand\commentStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \paragraph{Section titles} +% \begin{lstkey}{mlsectiontitlestyle} +% \begin{macro}{\sectionTitleStyle@mlpr} +% This key determines the style applied to \matlab{} section titles. +% \begin{macrocode} +\newcommand\sectionTitleStyle@mlpr{} +\lst@Key{mlsectiontitlestyle}\relax + {\renewcommand\sectionTitleStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \begin{lstkey}{mlshowsectionrules} +% \begin{macro}{\ifShowSectRules@mlpr@} +% This key determines whether an horizontal rule gets printed above each +% section title. +% \begin{macrocode} +\lst@Key{mlshowsectionrules}{false}[t]% + {\lstKV@SetIf{#1}\ifShowSectRules@mlpr@} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \begin{lstkey}{mlsectionrulethickness} +% \begin{macro}{\sectionRuleRT@mlpr} +% This key determines the relative thickness of the horizontal rule that +% gets printed above each section title. +% \begin{macrocode} +\newcommand\sectionRuleRT@mlpr{.05} +\lst@Key{mlsectionrulethickness}\relax% + {\renewcommand\sectionRuleRT@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \begin{lstkey}{mlsectionrulecolor} +% \begin{macro}{\sectionRuleColor@mlpr} +% This key determines the color of the horizontal rule that gets printed +% above each section title. +% \begin{macrocode} +\newcommand\sectionRuleColor@mlpr{black!15} +\lst@Key{mlsectionrulecolor}\relax% + {\renewcommand\sectionRuleColor@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \paragraph{System commands} +% \begin{lstkey}{mlsyscomstyle} +% \begin{macro}{\syscomStyle@mlpr} +% This key determines the style applied to system commands. +% \begin{macrocode} +\newcommand\syscomStyle@mlpr{} +\lst@Key{mlsyscomstyle}\relax% + {\renewcommand\syscomStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \paragraph{Variables with shared scope} +% For convenience, we create a brand new class of \lstpkg{} keywords for +% allowing the user to define \matlab{} variables with shared scope. +% +% \begin{macro}{\InstallKeywords@mlpr} +% This helper macro (which is based on \lstpkg{}' |\lst@InstallKeywords|), +% will let us defines four keys in one go, all prefixed by |ml|. +% \begin{macrocode} +\gdef\InstallKeywords@mlpr#1#2#3#4#5% +{% + \lst@Key{ml#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeKeywords}% + \lst@Key{mlmore#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeMoreKeywords}% + \lst@Key{mldelete#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@DeleteKeywords}% + \ifx\@empty#3\@empty\else + \lst@Key{#3}{#4}{\@namedef{lst@#3}{##1}}% + \fi + \expandafter\lst@InstallFamily@ + \csname\@lst @#2@data\expandafter\endcsname + \csname\@lst @#5\endcsname {#1}{#2}{#3} +} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{mlsharedvars} +% \begin{lstkey}{mlmoresharedvars} +% \begin{lstkey}{mldeletesharedvars} +% \begin{lstkey}{mlsharedvarstyle} +% We now use |\InstallKeywords@mlpr| to define the four keys in question: +% \rkeyname{mlsharedvars}, which can be used to define a list of \matlab{} +% variables with shared scope; +% \rkeyname{mlmoresharedvars}, which can be used to add elements to the +% current list of such variables; +% \rkeyname{mldeletesharedvars}, which can be used to remove elements +% from that list; +% and \rkeyname{mlsharedvarstyle}, which determines the style applied to +% variables with shared scope. +% \begin{macrocode} +\InstallKeywords@mlpr k{sharedvars}{mlsharedvarstyle}\relax% + {mlsharedvarstyle}{}ld +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \paragraph{Delimiters for unquoted strings} +% \begin{lstkey}{mlunquotedstringdelim} +% This key allows the user to define custom delimiters^^A +% ---which do not get printed in the output---^^A +% for unquoted strings. +% \begin{macrocode} +\lst@Key{mlunquotedstringdelim}\relax% + {\lst@DelimKey\relax{[is][\stringStyle@mlpr]{#1}}} +% \end{macrocode} +% \end{lstkey} +% +% \paragraph{Placeholders} +% \begin{lstkey}{mlplaceholderstyle} +% \begin{macro}{\phStyle@mlpr} +% This key determines the style applied to placeholder content; +% the color of placeholder delimiters is designed to match that of +% placeholder content. +% \begin{macrocode} +\newcommand\phStyle@mlpr{} +\lst@Key{mlplaceholderstyle}\relax% + {\renewcommand\phStyle@mlpr{#1}} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \mlpkg{} currently does not offer a nice interface for customizing +% code-snippet placeholder delimiters; in a future release, perhaps. +% +% \paragraph{Automatic scaling of inline code} +% \begin{lstkey}{mlscaleinline} +% \begin{macro}{\ifScaleInline@mlpr@} +% This key determines whether the font size of inline \matlab{} code should +% match the local font size. +% \begin{macrocode} +\lst@Key{mlscaleinline}{true}[t]% + {\lstKV@SetIf{#1}\ifScaleInline@mlpr@} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \paragraph{Printing only a function's signature and header} +% \begin{lstkey}{mlonlyheader} +% \begin{macro}{\ifonlyheader@mlpr@} +% This key determines whether output is dropped after the first block of +% contiguous line comments. +% \begin{macrocode} +\lst@Key{mlonlyheader}{false}[t]% + {\lstKV@SetIf{#1}\ifonlyheader@mlpr@} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% +% \section{Two user-level macros} +% +% \begin{macro}{\mlttfamily} +% This user-level macro can be used for selecting a scaled version of the +% Bera Mono font, a typewriter font family which, contrary to typewriter +% \TeX{} fonts, conveniently comes with a boldface version. +% \begin{macrocode} +\newcommand\mlttfamily +{% + \def\fvm@Scale{.85}% + \fontfamily{fvm}\selectfont% +} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Code-snippet placeholders} +% \begin{macro}{\mlplaceholder} +% This user-level macro can be used to typeset placeholders in code snippets. +% \begin{macrocode} +\newcommand\mlplaceholder[1] +{% + \bgroup% + \phStyle@mlpr% + \bgroup% + \phDelimStyle@mlpr% + \phOpDelim@mlpr% + \egroup% + #1\itcorr@mlpr% + \bgroup% + \phDelimStyle@mlpr% + \phClDelim@mlpr% + \egroup% + \egroup% +} +% \end{macrocode} +% \end{macro} +% +% +% \section{Other helper macros} +% +% \begin{macrocode} +\newcommand\phDelimStyle@mlpr{\rmfamily\upshape} +% \end{macrocode} +% \begin{macrocode} +\newcommand\phOpDelim@mlpr{\textlangle} +% \end{macrocode} +% \begin{macrocode} +\newcommand\phClDelim@mlpr{\textrangle} +% \end{macrocode} +% +% \begin{macro}{\itcorr@mlpr} +% This macro is used for applying italic correction in case the current font +% shape is either italic or slanted. +% \begin{macrocode} +\newcommand\itcorr@mlpr +{% +% \end{macrocode} +% We define a (long) macro that expands (once) to the current font shape, +% for comparison purposes. +% \begin{macrocode} + \expandafter\newcommand\expandafter\long@f@shape@mlpr% + \expandafter{\f@shape}% +% \end{macrocode} +% If the current font shape is either italic or slanted, we apply italic +% correction. +% \begin{macrocode} + \ifx\long@f@shape@mlpr\itdefault% + \/% + \else + \ifx\long@f@shape@mlpr\sldefault% + \/% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \section{\texorpdfstring{\mlpkg{}}{matlab-prettifier} styles} +% +% We now define three \lstpkg{} styles for \matlab{} listings. +% +% \paragraph{Base style} +% +% This style is used internally to define the three user-level styles. +% It's not meant to be used outside this package file. +% \begin{macro}{\toks@mlpr} +% We allocate a token list register in which we store settings that we'll use +% to define the style. +% \begin{macrocode} +\newtoks\toks@mlpr +\toks@mlpr=% +{ + language = \languageNormedDefd@mlpr, + basicstyle = \color{black}\ttfamily\normalsize, + breaklines = true, + showspaces = false, + showstringspaces = false, + upquote = true, + rulecolor = \color{black!67}, + numberstyle = \color{black!33}, + mlscaleinline = true, + mlonlyheader = false, +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\ifframed@mlpr@ + \toks@mlpr=\expandafter{\the\toks@mlpr frame=single,} +\fi +\ifnumbered@mlpr@ + \toks@mlpr=\expandafter{\the\toks@mlpr numbers=left,} +\fi +\begingroup\edef\@tempa{\endgroup + \noexpand\lstdefinestyle{MatlabBaseStyle@mlpr}{\the\toks@mlpr} +}\@tempa +% \end{macrocode} +% +% \paragraph{Standard style} +% Standard style of the \matlab{} editor. +% \begin{macro}{\mlbwphstyle}^^A FIXME: to be documented +% This user macro holds the placeholder style used in the +% \mlsty{Matlab-editor} style. +% \begin{macrocode} +\newcommand\mleditorphstyle{\color[RGB]{209,000,086}\rmfamily\itshape} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\lstdefinestyle{Matlab-editor} +{ + style = MatlabBaseStyle@mlpr, + mllastelementstyle = \color{black} , + mlkeywordstyle = \color[RGB]{000,000,255} , + mlcommentstyle = \color[RGB]{034,139,034} , + mlstringstyle = \color[RGB]{160,032,240} , + mlsyscomstyle = \color[RGB]{178,140,000} , + mlsectiontitlestyle = \commentStyle@mlpr \bfseries, + mlsharedvarstyle = \color[RGB]{000,163,163} , + mlplaceholderstyle = \mleditorphstyle, +} +% \end{macrocode} +% +% \paragraph{Black \& white style} +% Black \& white, printer-friendly style. +% \begin{macro}{\mlbwphstyle}^^A FIXME: to be documented +% This user macro holds the placeholder style used in the +% \mlsty{Matlab-bw} style. +% \begin{macrocode} +\newcommand\mlbwphstyle{\color[gray]{0}\rmfamily\itshape} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\lstdefinestyle{Matlab-bw} +{ + style = MatlabBaseStyle@mlpr, + mlkeywordstyle = \color[gray]{0} \bfseries , + mlcommentstyle = \color[gray]{.75} \itshape, + mlstringstyle = \color[gray]{.5} , + mlsyscomstyle = \color[gray]{.25} , + mlsectiontitlestyle = \color[gray]{.75}\bfseries\itshape, + mlsharedvarstyle = \color[gray]{0} , + mlplaceholderstyle = \mlbwphstyle, +} +% \end{macrocode} +% +% \paragraph{Style of Pygments' MatlabLexer} +% Style that closely mimics that of Pygments' `MatlabLexer'. +% \begin{macro}{\mlpyglikephstyle}^^A FIXME: to be documented +% This user macro holds the placeholder style used in the +% \mlsty{Matlab-Pyglike} style. +% \begin{macrocode} +\newcommand\mlpyglikephstyle{\color[RGB]{127,063,127}\rmfamily\itshape} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\lstdefinestyle{Matlab-Pyglike} +{ + style = MatlabBaseStyle@mlpr, + mllastelementstyle = \color[RGB]{127,000,000} , + mlkeywordstyle = \color[RGB]{000,127,000}\bfseries , + mlcommentstyle = \color[RGB]{063,127,127} \itshape, + mlstringstyle = \color[RGB]{186,034,034} , + mlsyscomstyle = \color[RGB]{000,127,000} , + mlsectiontitlestyle = \color[RGB]{063,127,127} \itshape, + mlsharedvarstyle = \color[RGB]{034,034,186} , + mlplaceholderstyle = \mlpyglikephstyle, +} +% \end{macrocode} +% +% \Finale +\endinput -- cgit v1.2.3