How do I send the result of \pgfkeys to Lua? - lua

In the example below the macro "\pgfkeysprintvalue" is a variant of "\pgfkeysgetvalue" that sort of sends the value of a key to Lua, and prints it from Lua:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\pgfkeyssetvalue{/p}{PP}
\pgfkeysgetvalue{/p}{\luatmp}
\luatmp % prints a "PP" in the document
\def\pgfkeysprintvalue#1{
\pgfkeysgetvalue{#1}{\luatmp}
\directlua{print("#1: "..(token.get_meaning("luatmp") or ""))}
}
\pgfkeyssetvalue {/q}{QQ}
\pgfkeysprintvalue{/q} % prints "/q: ->QQ" on stdout
\end{document}
In this other example the first three "\pgfkeys"s have interesting side-effects but expand to nothing, and the "\pgfkeys{/c,/d,/e=DD}" expands to "(c)(d:)(c)(d:DD)":
\documentclass{article}
\usepackage{tikz}
\begin{document}
\pgfkeys{/c/.code=(c)}
\pgfkeys{/d/.code=(d:#1)}
\pgfkeys{/e/.style={/c,/d=#1}}
\pgfkeys{/c,/d,/e=DD}
\end{document}
The last "\pgfkeys" above "prints" the "(c)(d:)(c)(d:DD)" into the document, and it appears in the PDF.
How do I write a variant of \pgfkeys - let me call it \pgfkeysprint - that would store the expansion of its argument in a macro called \luatmp? I guess that it would be like this:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\def\pgfkeysprint#1{
<I don't know what to put here>{#1}{\luatmp}
\directlua{print("#1: "..(token.get_meaning("luatmp") or ""))}
}
\pgfkeys{/c/.code=(c)}
\pgfkeys{/d/.code=(d:#1)}
\pgfkeys{/e/.style={/c,/d=#1}}
\pgfkeysprint{/c,/d,/e=DD} % prints "/c,/d,/e=DD: -> (c)(d:)(c)(d:DD)" on stdout
\end{document}
I'm trying to write functions for inspecting PGF keys from a Lua REPL running inside LuaLaTeX, and the part corresponing to the "<I don't know what to put here>" above is the main piece that is still missing...
Obs: I tried to write my macro \pgfkeysprint by adapting the definition of \pgfkeysgetvalue in pgf/utilities/pgfkeys.code.tex, but I couldn't find the right way to use the "\expandafter"s...

Related

Highlighting inline code snippets with the latex listings package

In my latex document I am using the listings package extensively.
I have many short inline code snippets that I like to give a proper highlighting in the text, and I am using the \lstMakeShortInline construct. Now I am interested in highlighting (background coloring) at least some of those code inserts for clarity, and was trying the following:
\lstMakeShortInline[language=Python,basicstyle=\ttfamily, backgroundcolor=\color{lightgray}]!
hoping that usage like:
some text some text !read_csv()! some more text
Will result in read_csv() appearing on a light-gray background, but it does not seem to work. The \ttfamily format works well in this situation.
(Thanks to samcarter_is_at_topanswers.xyz)
Here is a minimal example:
\documentclass{book}
\usepackage{listings}
\usepackage{color}
\lstset{language=Python}
\begin{document}
\lstMakeShortInline[language=Python, keywordstyle={\bfseries \color{blue}}, backgroundcolor=\color{yellow}]!
Here is the keyword !for!, showing that the \textbf{keywordstyle} setting takes effect, but the \textbf{backgroundcolor} setting does not.
\textbf{backgroundcolor} fails to take effect also when applied to a non-keyword !df.read_csv()! code snippet.
\end{document}
Is this possible with the listings package?
Thanks
Michael
Based on https://tex.stackexchange.com/a/357239/36296 you could do something like (make sure that ! does not occur in the normal text or use a different character):
% !TeX program = lualatex
\documentclass{article}
\usepackage{xcolor,listings,realboxes,fancyvrb} % fancyvrb for '\Verb' macro
\definecolor{mygray}{rgb}{0.8,0.8,0.8}
\lstset{basicstyle=\ttfamily, breaklines = true, backgroundcolor=\color{mygray}}
\usepackage[doublespacing]{setspace} % just for this example
\usepackage{luacode} % for 'luacode' environment
\begin{luacode}
-- the following code employs Lua's powerful "string.gsub" function
function color_lstinline ( s )
s = string.gsub ( s , "%b!!", "\\Colorbox{mygray}{%0}" )
return s
end
\end{luacode}
%% Define 2 LaTeX macros to switch operation of Lua function on and off
\newcommand{\ColorLstinlineOn}{\directlua{
luatexbase.add_to_callback ( "process_input_buffer" ,
color_lstinline, "color_lstinline" )}}
\newcommand{\ColorLstinlineOff}{\directlua{
luatexbase.remove_from_callback ( "process_input_buffer" ,
"color_lstinline" )}}
\AtBeginDocument{\ColorLstinlineOn} % Default: activate the Lua function
\lstMakeShortInline[language=Python, keywordstyle={\bfseries \color{blue}}, backgroundcolor=\color{yellow}]!
\begin{document}
!for!
\end{document}

How to wrap LaTex command in new environment

This question has already been answered once (wrap LaTeX command in environment), yet I still struggle to make my own rather simple new environment command work.
What I wanted to do is to convert the following LaTex block, which shows the output of some code, into a command I can reuse.
\fbox{\begin{minipage}{\textwidth}
\texttt{
>> CODE OUTPUT
\end{minipage}}
It is clear that in order to make a new environment command that replicates what I do above, I will have to make use of wrappers. (Because of the \fbox and the \texttt command.)
I would like to do this without having to download yet another package, or going into the secret realms of LaTex with some predefined \dir command that is only there to do the same job twice.
Checking the link from before, it seems that a productive solution is to use \bgroup and \egroup. I would therefore write something like this:
\newenvironment{CodeOutput}
{\fbox\bgroup\begin{minipage}{\textwidth}\texttt\bgroup}
{\egroup\end{minipage}\egroup}
Yet this will still not work. (On Overleaf at least.) It would be great if there was a straightforward way of making commands like these. Thanks for any useful suggestions!
If want to write a command that does what you're after, then the following would work:
\newcommand{\mycmd}[1]{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily #1
\end{minipage}%
}%
}
The idea here works because the <arg>ument supplied to \mycmd{<arg>} is replaced by #1 in its entirety. If you want want to rewrite this as an environment, it's a little more difficult, purely because of \fbox. \fbox is doesn't have an environment-form equivalent the same way \texttt has \ttfamily (which is technically a font switch). There is a quick way around it provided by environ - it allows you to capture the contents of an environment in a macro \BODY:
\usepackage{environ}
\NewEnviron{myenvA}{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily \BODY
\end{minipage}%
}%
}
However, you do have the option by capturing the content of an environment inside a box and then setting the box inside an \fbox:
\newsavebox{\codebox}% To store the content of myenvB
\newenvironment{myenvB}{%
\begin{lrbox}{\codebox}%
\ttfamily\ignorespaces
}{%
\end{lrbox}%
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\usebox{\codebox}%
\end{minipage}}%
}
The following minimal example shows all the above cases:
\documentclass{article}
\usepackage{environ}
\newcommand{\mycmd}[1]{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily #1
\end{minipage}%
}%
}
\NewEnviron{myenvA}{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily \BODY
\end{minipage}%
}%
}
\newsavebox{\codebox}
\newenvironment{myenvB}{%
\begin{lrbox}{\codebox}%
\ttfamily\ignorespaces
}{%
\end{lrbox}%
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\usebox{\codebox}%
\end{minipage}}%
}
\begin{document}
\noindent
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily SoMe CoDe HeRe
\end{minipage}}
\bigskip
\noindent
\mycmd{SoMe CoDe HeRe}
\bigskip
\noindent
\begin{myenvA}
SoMe CoDe HeRe
\end{myenvA}
\bigskip
\begin{lrbox}{\codebox}
\ttfamily SoMe CoDe HeRe
\end{lrbox}
\noindent
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\usebox{\codebox}
\end{minipage}}
\bigskip
\noindent
\begin{myenvB}
SoMe CoDe HeRe
\end{myenvB}
\end{document}

\afterpage and \endfloat

How do I combine \afterpage and \endfloat to easily switch between having figures and tables at the end of the document or having them in the text?
I want to easily choose between my figures at the end of the document and my figures in the text. Because of that, sometimes I will use \afterpage package and other times I will use \endfloat would be nice to combine both.
Right now, all the times I try to run \endfloat when I have a clear page, I get the following message:
Argument of \efloat#xfloat has an extra }.
I already tried to include after page in the DeclareDelayedFloatFlavor, something like:
\DeclareDelayedFloatFlavor{afterpage}{figure}
It did not work.
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{float}
\usepackage{afterpage}
% ---------------------
%figures at the end
% ---------------------
\usepackage[nolists]{endfloat}
% force landscape at the end
\begin{document}
{\afterpage{
\begin{figure}
\end{figure}
}
\end{document}
If you want to switch between having figures within the text and at the end, I suggest to only use the endfloat package. Commenting or commenting it's optional argument disable will allow you to quickly alternate between figures at the end or in the text.
I'm not entirely certain what the purpose of afterpage was in your example, but if you used it to move the figure to a separate page, this can conveniently be done with the p floating specifier.
\documentclass{article}
\usepackage[
disable
]{endfloat}
\begin{document}
test
\begin{figure}[p]
xxx
\caption{caption}
\end{figure}
test
\end{document}

How to embed LaTeX keywords inside a LaTeX document using 'listings'

I want to cite LaTeX code into my document but how do I embed the keywords "\begin{lstlisting}" and "\end{lstlisting}" correctly?
CODE BELOW DOES NOT WORK (obviously):
\lstset{language=TeX, basicstyle=\footnotesize, numbers=left, numberstyle=\tiny, frame=single}
\begin{lstlisting}
\begin{lstlisting} % this is code
place your source code here % this is code
\end{lstlisting} % this is code
\end{lstlisting}
Do you have \usepackage{listings} in your preamble? If so, it should work. TeX is a supported language.
Here's a minimal example:
\documentclass{article}
\usepackage{listings}
\begin{document}
This is a StackOverflow test file.\\
To use \texttt{lstlisting}, include this in the preamble:
\begin{lstlisting}
\usepackage{listings}
\end{lstlisting}
Hope that helped :)
\end{document}
which compiles to
EDIT
To quote commands from the listings package (actually, only for \end{lstlisting}), escape to latex to print the \ character and you're all set. In the following, I've defined # as the escape character and everything within two # symbols is typeset in LaTeX. So here, I've input the \ using LaTeX and the rest within lstlisting and the \end{...} sequence is not interpreted as a closing the environment.
\documentclass{article}
\usepackage{listings}
\begin{document}
This is a StackOverflow test file.\\
Use escape characters to escape to \LaTeX
\lstset{escapechar=\#}
\begin{lstlisting}
\begin{lstlisting}
some code here
#\textbackslash#end{lstlisting}
\end{lstlisting}
Hope that helped :)
\end{document}
The output is
can you use a verbatim block?
\begin{verbatim}
\begin{lstlisting} % this is code
place your source code here % this is code
\end{lstlisting} % this is code
\end{verbatim}
You can use
\lstnewenvironment{OtherListing}
{}
{}
to create a new envirnment that behaves just list lstlisting, and \end{lstlisting} should not be forbidden in it.

Setting up author or address string variables in LaTeX

LaTeX is a wonderful language for writing documents. With the hyperref package and pdflatex, you easily generate documents with metadata, a nice feature to get your documents referenced right on the web.
I often use templates like:
\documentclass[11pt]{article}
\usepackage[pdftex, pdfusetitle,colorlinks=false,pdfborder={0 0 0}]{hyperref}%
\hypersetup{%
pdftitle={My title},%
pdfauthor={My name},%
pdfkeywords={my first keyword, my second keyword, more keywords.},%
}%
\begin{document}
\title{My title}
\author{My name}
\date{}
\maketitle
{\bf Keywords:} my first keyword, my second keyword, more keywords.%
My text is here...
\end{document}
So far, it's well. My question pops out from the example: is there a way to define string variables in the header so that they can be passed as arguments to hyperref and then to the frontmatter or to the text. Something like:
\documentclass[11pt]{article}
%-------definitions-----
\def\Author{My name}
\def\Title{My title}
\def\Keywords{my first keyword, my second keyword, more keywords.}
%--------------------------
\usepackage[pdftex, pdfusetitle,colorlinks=false,pdfborder={0 0 0}]{hyperref}%
\hypersetup{%
pdftitle={\Title},%
pdfauthor={\Author},%
pdfkeywords={\Keywords},%
}%
\begin{document}
\title{\Title}
\author{\Author}
\date{}
\maketitle
{\bf Keywords:} \Keywords %
My text is here...
\end{document}
This fails for the \maketitle part and for the hyperref metadata with ! Use of \Title doesn't match ! Argument of \let has an extra }.but also for including the keywords.
The correct template should look like:
\documentclass[11pt]{article}
%-------definitions-----
\newcommand{\Author}{My name}
\newcommand{\Title}{My title}
\newcommand{\Keywords}{my first keyword, my first keyword, more keywords.}
%--------------------------
\usepackage[pdftex, pdfusetitle,colorlinks=false,pdfborder={0 0 0}]{hyperref}%
\hypersetup{%
pdftitle={\Title},%
pdfauthor={\Author},%
pdfkeywords={\Keywords},%
}%
\begin{document}
\title{\Title}
\author{\Author}
\date{}
\maketitle
{\bf Keywords:} \Keywords %
My text is here...
\end{document}
Compiles fine and the metadata shows fine in the pdf reader.
Try using \newcommand{\Author}{My name} instead of \def.

Resources