Pandoc - Support for a custom input latex environment - latex

I am using a single unified LaTeX doc to create problem sets and solutions:
\item What is one plus one?
\begin{soln}
The answer is "two".
\end{soln}
In LaTeX, I define this environment with (simplified):
\NewEnviron{soln}
{
\ifsolutions\expandafter
\BODY
\fi
}
That is, if \solutionsfalse has been defined in LaTeX, it prints:
1. What is one plus one?
and if \solutionstrue has been defined, it prints:
1. What is one plus one?
** The answer is two **
I'm trying to replicate this in pandoc to generate HTML or MD files from the latex input, but I've run against the wall. Pandoc doesn't honor any kind of /if /else /fi statement in LaTeX, I think. Pandoc doesn't honor the comment environment, which would also work with \excludecomment{soln}. So, I can't come up with a shim.tex file that would replicate the 'ignore stuff in the soln environment'.
The next way to go would, I guess, be to do something in luatex that pandoc can talk to, or to define the custom environment to pandoc with a filter? But the documentation for those systems is extremely heavyweight - there's no easy way in.
Can anyone suggest a solution to this?
Ideally, I want to run two different shell commands. Command A should omit all content in the soln environment. Command B, ideally, should turn all regular text blue, and show all content in the soln environment in black color.
(P.S. The xcolor package also seems unsupported in native pandoc, although there is a filter that doesn't work for me.)
Edit
Following comments by #tarleb and #mb21, I guess I have to try to work out how filters work. Again, the documentation here is terrible - it wants you to know everything before you can do anything.
I tried this:
return {
{
RawBlock = function(elem)
print(elem.text)
if starts_with('\\begin{soln}', elem.text) then
return pandoc.RawBlock(elem.format,"SOLN")
else
return elem
end
end,
}
}
and ran it with
pandoc --lua-filter ifdef.lua --mathjax -s hw01.tex -s -o hw01.html
But there is nothing on stdout from the print statement, and my document is unchanged, so the RawBlocks are apparently not processed by the lua filter unless the -f latex+raw_tex flag is passed. But passing those flags means that pandoc doesn't actually process the \include commands in the latex, so my filter wont' see the subdocuments.
Apparently, the answer is "No, pandoc cannot support new latex environment", because it would require modifying the parser. Although the -f latex+raw_tex can disable big parts of the parser, that just means the document is largely unparsed, which isn't what I want.
Please tell me if I'm wrong.

Related

Rmarkdown with pandoc templates, apply lua filter on intermediate .tex

I'm trying to use lua filters to capture images in my manuscript and list their caption in a special \section at the end of it.
I am working on a rmarkdown document that itself uses a .tex template.
I wasn't able to get anywhere, so I run a very simple filter:
function Header (head) print(pandoc.utils.stringify(head)) end
and noticed that just the headers in the markdown were recognized, not the ones in the ones in the template.
The only way I found to have lua filters recognize the elements in the template was to rerun the produced .tex file with pandoc:
pandoc -f latex -t latex -o test2.tex --lua-filter=my_filters.lua test.tex
but that removed all latex formatting and structure content outside the body, e.g., \documentclass, \usepackage and other custom commands. So it's a no go.
So the question is, is there a way to force lua filter to be applied after the integration of a latex template when knitting a rmarkdown document?
There might be a way, but it most likely won't do what you need.
When pandoc reads a document, it parses it and converts it into it's internal data structure. That internal structure can then be modified with a filter. LaTeX is a very expressive and complex document format, and any conversion from LaTeX into pandoc's internal format will result in a loss of (layout) information. That's good enough in most cases, but would be a problem in your case.
There are two possible ways to do this: one is to post-process the output, which is probably tedious and error-prone. The other is to find a way to generate the desired output, e.g. via a pandoc filter, without adding it to the template first.
I believe your other question is the right way to go.

Pandoc re-run latex filter on element after latex+raw_tex and lua filter

I've been writing a custom LaTeX reader Lua filter to convert a bunch of LaTeX source into Pandoc Markdown, which will be my new source for several documents.
I run the usual filter like the following.
pandoc file.tex \
-f latex+raw_tex \
-t markdown \
-o file.md \
--lua-filter myfilter.lua
This works great. I've been able to convert several custom LaTeX environments into Divs and the like.
However, when I have standard LaTeX nested inside the custom environment, the filter output leaves that as-is, unconverted. For example.
\begin{custom_environment}
\begin{itemize}
\item foo
\item bar
\end{itemize}
\end{custom_environment}
The custom environment is handled just fine by my filter, but the internal itemize or tabular or similar are, left unprocessed, as you would expect.
Is there some way to process the contents of the custom environment using the standard latex extension (i.e. filter)? I assume it would be a call from the Lua filter.
An idea I have for doing this that I'm trying to avoid is writing the contents to a temporary file and running another pandoc on that. It seems like such a ubiquitous situation that I'm hoping there's a better way. Thanks!
The best solution I found was pandoc.read:
https://pandoc.org/lua-filters.html#helper-functions
I used it as follows.
internal_div = pandoc.Div(
pandoc.read(
contents_of_custom_environment,
'latex'
).blocks,
'div_label'
)
Now internal_div contains the latex-processed contents of the custom environment. Note that contents_of_custom_environment is just a string.
I tried using walk_block and walk_inline, but couldn't get them to work quite like this. I would welcome an answer that did so.

How can I expand Sublime's language syntax understanding to incorporate custom syntax?

I know that sounds vague. Basically I just want Sublime to highlight custom syntax (color the text), just like it does with native syntax.
I am using Sublime to write LaTeX code. For those that don't know, LaTeX equations are typically enclosed by \[ \], e.g.
\[ E = m c^2 \]
Sublime understands that syntax and colors the enclosing code appropriately.
However, I use my custom defined command, \eq{ ... }, which wraps the \[ \] functionality (so I can globally change some settings by just redefining the \eq definition). e.g.
\eq{ E = m c^2 }
I don't know anything about Sublime under the hood beyond basic key bindings. I want to expand Sublime's understanding of syntax to incorporate my custom command without wasting a ton of time digging through tutorials and such.
Since you are mainly interested in the result and not in the reasoning, I will try to be as straight forward as I can.
The LaTeX syntax of Sublime Text will change in release 3119 and I would recommend to use that, if you want to change something.
Just download it from https://github.com/sublimehq/Packages and put the LaTeX folder into the folder, which opens when you select Preferences >> Browse Packages... in the Sublime Text menu.
Afterwards open the file LaTeX.sublime-syntax and search for ensuremath (LaTeX.sublime-syntax#L498). Duplicate that part (everything with a higher indent) and change the command to the command you wish, e.g. in your example this would be - match: '((\\)eq)(\{)'.
Aside the new syntax removes the highlighting of math environments as strings, because this has lead to several problems.
I made a small entry in the LaTeXTools wiki to explain, how you restore the highlight.

Physics bra-ket symbols in IPython

I am trying to have the ket symbol which is usually written in latex as \ket{\psi}. However, this doesn't work when written within the $$ ... $$. This also doesn't work when written using IPython.display.
$ latex
** \documentclass{article}\usepackage{amsmath}\begin{document}
... chatter chatter ...
* \show\ket
> \ket=undefined.
So your \ket macro is coming from some package or other which I don't know what it is. This doesn't explain why it doesn't work in $$ ... $$ -- you have to work at it to get things to not work in display math -- but it does explain why it doesn't work in IPython: whichever package this is isn't being loaded in IPython's canned TeX environment (or) IPython's emulation of TeX math input language does not include this macro.
Here's a reasonable definition in terms of primitive math symbols, which should work fine in display mode. I don't know if you can put this into IPython verbatim, but you should at least be able to write out the expansion longhand when needed (e.g. $$ \left| \psi \right\rangle $$)
\newcommand{\ket}[1]{\left|{#1}\right\rangle}
\newcommand{\bra}[1]{\left\langle{#1}\right|}
EDIT: define macros using LaTeX preferred interface, rather than primitive \def.
I was able to extend #zwol 's answer to create a \braket command as well for use in a Jupyter notebook:
$$\newcommand{\braket}[2]{\left\langle{#1}\middle|{#2}\right\rangle}$$
$$\braket{\Psi^*}{\Psi}$$
$$\braket{\frac{\Psi^*}{2}}{\Psi}$$
Gives:
IPython uses MathJax to render LaTeX in the notebook. MathJax is great but only supports a subset of LaTeX hence there are some limitations. See MathJax homepage for details.
A new command like proposed by #Zack will work fine though. Be aware that such custom commands will likely lead to some issues when converting to LaTeX (nbconvert).

Including doxygen's LaTeX output as an appendix to a larger document

I have a "project book" which uses LaTeX's \documentclass{report} ("report" is like a more compact version of \documentclass{book}). I would like to include into this book an appendix with the Doxygen-generated API documentation for the software in the project.
I have achieved this by setting Doxygen's config options LATEX_HEADER and LATEX_FOOTER to an empty file. This makes the resulting latex/refman.tex have top level commands like: \section{\-Namespace \-Index}, at which point I can wrap this with a top level document like:
\documentclass{report}
\usepackage{doxygen.sty}
% the "import" package helps to find Doxygen files in the latex/ subdirectory
\usepackage{import}
% [...] title page and the rest of the book
\appendix
\chapter{API reference (generated by Doxygen)
subimport{latex/}{refman.tex}
% [...] final stuff
\end{document}
This works reasonably well and I get doxygen.sty with this special doxygen invocation:
doxygen -w latex /dev/null /dev/null doxygen.sty
One problem is that this puts an "autogenerated" header on the entire document (not just on the doxygen appendix). I can get rid of this by editing doxygen.sty (I also rename it for my inclusion, actually) and commenting out the block that starts with % Setup fancy headings.
At this point I have something I can live with, but I would like to go one step further: the "doxygen" style modifies a lot of other aspects of the LaTeX document style, and I like it less.
So my question is (in two levels of excellence):
What would be a minimal set of LaTeX commands to put in a doxygen.sty file that would nicely render the doxygen appendix but not interfere with the rest of the LaTeX document?
Even better, has someone come up with a way of doing
\usepackage{doxygen_standalone}
% [... until you need doxygen]
\begin{doxygen}
% the stuff you need to insert your auto-generated doxygen API docs,
% for example the \subimport{latex/}{refman.tex} that I showed above
\end{doxygen}
This last approach is one I would consider very clean.
I'm hoping there is a really simple answer, such as "this already exists in doxygen.sty as an option, and you missed it!"
rename doxygen.sty to mydoxygen.sty, then modify it by inserting
\newenvironment{doxygen}{... most of doxygen.sty goes here ...}{}

Resources