All Projects → Vindaar → LatexDSL

Vindaar / LatexDSL

Licence: other
A mini DSL to generate LaTeX from Nim

Programming Languages

nim
578 projects

Projects that are alternatives of or similar to LatexDSL

ParsedownMath
LaTeX support in Parsedown
Stars: ✭ 13 (-40.91%)
Mutual labels:  latex
clj-book
Книга «Clojure на производстве»
Stars: ✭ 24 (+9.09%)
Mutual labels:  latex
stata-latex-workflows
Stata Workflows for LaTeX Output
Stars: ✭ 68 (+209.09%)
Mutual labels:  latex
xdupgthesis
西安电子科技大学研究生学位论文XeLaTeX模板
Stars: ✭ 271 (+1131.82%)
Mutual labels:  latex
webgui
Web Technologies based Crossplatform GUI Framework with Dark theme
Stars: ✭ 81 (+268.18%)
Mutual labels:  nim-lang
Yet-Another-LaTeX-Template-for-NPU-Thesis
西北工业大学硕博学位论文模版 | Yet Another Thesis Template for Northwestern Polytechnical University
Stars: ✭ 82 (+272.73%)
Mutual labels:  latex
ads2bibdesk
ads2bibdesk helps you add astrophysics articles listed on NASA/ADS to your BibDesk database using the new ADS Developer API
Stars: ✭ 32 (+45.45%)
Mutual labels:  latex
opendetex
Improved version of Detex - tool for extracting plain text from TeX and LaTeX sources
Stars: ✭ 179 (+713.64%)
Mutual labels:  latex
latex-examples
small (la)tex files showing features, solutions and attempts
Stars: ✭ 54 (+145.45%)
Mutual labels:  latex
concise-cheat-sheets
Cheat Sheets for programming languages and tools
Stars: ✭ 98 (+345.45%)
Mutual labels:  latex
awsome-list-of-cv-and-resume-templetes
a collection of cv and resume styles
Stars: ✭ 78 (+254.55%)
Mutual labels:  latex
snipmate-snippets-bib
Snipmate.vim support for BibTeX files
Stars: ✭ 13 (-40.91%)
Mutual labels:  latex
kmbeamer
My themes for Beamer.
Stars: ✭ 108 (+390.91%)
Mutual labels:  latex
dicy
A builder for LaTeX, knitr, literate Agda, literate Haskell and Pweave that automatically builds dependencies.
Stars: ✭ 22 (+0%)
Mutual labels:  latex
lazylatex
Because LaTeX shouldn't be boring! 🐠 LaTeX package inspired by sphinx-rtd-theme. Build with tcolorbox, minted, tikz, etc,.
Stars: ✭ 16 (-27.27%)
Mutual labels:  latex
golang-latex-listings
Golang definition for LaTeX's listings mode. Code coloration for Go in your LaTeX files!
Stars: ✭ 18 (-18.18%)
Mutual labels:  latex
biblatex-abnt
📚 Estilo para BibLaTeX compatível com as normas da ABNT
Stars: ✭ 97 (+340.91%)
Mutual labels:  latex
SCU Beamer Slide-demo
四川大学非官方Beamer模板 | Unofficial Beamer Template for Sichuan University
Stars: ✭ 28 (+27.27%)
Mutual labels:  latex
sshlatex
A collection of hacks to efficiently run LaTeX via ssh
Stars: ✭ 32 (+45.45%)
Mutual labels:  latex
nom-bibtex
A feature complete bibtex parser using nom
Stars: ✭ 13 (-40.91%)
Mutual labels:  latex

LaTeX DSL

latexdsl provides a convenient macro (and very soon a bunch of helper templates / macros) to generate LaTeX code from Nim.

The very short version is, it allows you to write:

let lang = "english"
let res = latex:
  \documentclass{article}
  \usepackage[`lang`]{babel}
  \usepackage[utf8]{inputenc}

to get:

\documentclass{article}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}

Now this might not seem all that useful by itself “I can just write a string literal with string interpolation”.

Yes, except: Every TeX command either entered using explicit backslash or opening a statement list will be checked at compile time against an enum of allowed TeX commands! This means we get compile time checks without having to manually write a very large number of helper templates like the following:

template bold(arg: untyped): untyped = "\\textbf{" & $arg & "}"

For limited TeX application in a project that’s certainly enough but definitely not scalable.

The same is done for every command that has a statement list as its argument. That’s also where another convenience feature comes in: any Nim block will be understood as a

\begin{command} 
your TeX
\end{command}

command. So the following:

import latexdsl
let res = latex:
  center:
    figure:
      \includegraphics[width=r"0.8\textwidth"]{myImage}
echo res

(Note the usage of raw string literals to work around stuff that isn’t allowed as Nim syntax)

does generate what you would expect:

\begin{center}
\begin{figure}
\includegraphics[width=0.8\textwidth]{myImage}
\end{figure}
\end{center}

Any optional parameter within [] will simply be handed as is into the result. The same is true for arguments within {} or any other command.

The compile time checks are done on:

  • anything starting with a \: \myCommandToBeChecked
  • anything that opens its own block:
    let res = latex:
      blockCommand[anOption]{anArgument}{anotherArgument}:
        "Some random stuff here"
        \checkMe
        

    Here blockCommand and \checkMe will be checked for validity while the other identifiers won’t be.

In case a command is not part of the enum yet, you can omit the CT check by prepending with two \\ instead of one.

An example of available sugar

Without making this example more complicated than necessary, let’s consider an artificial case of performing some data analysis, ending up with a plot and the desire to convert both our data and plot into something directly embeddable in a TeX document.

import ggplotnim, latexdsl, strformat

# let's assume we have a complicated proc, which performs our
# data analysis and returns the result as a ggplotnim `DataFrame`

proc complexCalculation(): DataFrame =
  # here be code your CPU hates ;)
  result = seqsToDf({ "Num" : @[17, 43, 8, 22],
                      "Group" : @["Group 1", "Group 2", "Group 3", "Group 4"] })

# let's perform our complex calc
let df = complexCalculation()
# and create a fancy plot for it
let path = "examples/dummy_plot.png"
ggplot(df, aes(Group, Num)) + 
  geom_bar(stat = "identity") + 
  xlab("Age group") +
  ylab("Number of participants") +
  ggsave(path)

# now we could construct a TeX figure and table for the data manually,
# but for these use cases two helper procs exist. `figure` and `toTexTable`.

# We want to include the information about the group with the most participants
# into the caption of the table. So create the correct caption computationally
# without having to worry about causing code / paper to get out of sync
echo df
let maxGroup = df.filter(f{int -> bool: `Num` == max(df["Num"])})
echo maxGroup
# create two nice labels:
let figLab = "fig:sec:ana:participants"
let tabLab = "tab:sec:ana:participants"
# for simplicity we will use the same caption for figure and table, with different
# references
let cap = "Number of participants in the experiment by age group. Group " &
  &"{maxGroup[\"Group\", 0]} had the most participants with {maxGroup[\"Num\", 0]}" &
  " subjects."
# and add a reference to the table we will create 
let figCap = latex:
  "The data used for the figure is found in tab. " \ref{`tabLab`} "."
let fig = figure(path, caption = cap & figCap, label = figLab, width = textwidth(0.8),
                 checkFile = true)
# NOTE: The `checkFile` argument performs a runtime check on the given path to make
# sure the file that is supposed to be put into a TeX document actually exists!
# and finally for the table:
let tabCap = latex:
  "The data is plotted in fig. " \ref{`figLab`} "."
let tab = toTexTable(df, caption = cap & tabCap, label = tabLab)

# and from here we could insert the generated TeX code directly into a TeX document.
# We'll just print it here.
echo fig
echo tab

Which generates the following plot:

./examples/dummy_plot.png

and outputs the following TeX code to the terminal (this is the unformatted output):

\begin{figure}[htbp]
\centering
\includegraphics[width=0.8\textwidth]{examples/dummy_plot.png}
\label{fig:sec:ana:participants}
\caption{Number of participants in the experiment by age group. Group Group 2 had the most participants with 43 subjects.The data used for the figure is found in tab. \ref{tab:sec:ana:participants}.
}

\end{figure}



\begin{table}[htbp]
\centering

\begin{tabular}{l l}
\toprule
Num & Group\\
\midrule
17 & Group 1\\
43 & Group 2\\
8 & Group 3\\
22 & Group 4
\bottomrule
\end{tabular}

\caption{Number of participants in the experiment by age group. Group Group 2 had the most participants with 43 subjects.The data is plotted in fig. \ref{fig:sec:ana:participants}.
}
\label{tab:sec:ana:participants}

\end{table}

NOTE: The Dataframe helper functionality is only available on Nim versions starting from v1.6!

Caveats

Of course not every possible LaTeX code can be represented as valid Nim code. The known caveats and workarounds are listed here:

  • value + unit pairs, e.g.
    margin=2cm
        

    Use string literal:

    margin="2cm"
        
  • string literals for TeX commands, be sure to use raw literals, due to \r, \n, \p etc being interpreted as control characters. E.g. here we need string literals, because # is a Nim comment:
    \protect\numberline{\thesection}#1
        
    r"\protect\numberline{\thesection}#1"
        
  • multiline arguments to {}:
    \newcommand\invisiblesection[1]{
      \refstepcounter{section}
      \addcontentsline{toc}{section}{r"\protect\numberline{\thesection}#1"}
      \sectionmark{"#1"}
    }
        

    Use Nim Pragma syntax for multiline blocks, {. multiLine .}:

    \newcommand\invisiblesection[1]{.
      \refstepcounter{section}
      \addcontentsline{toc}{section}{r"\protect\numberline{\thesection}#1"}
      \sectionmark{"#1"}
    .}
        

    NOTE: this still has a downside: you cannot do nested blocks inside the pragma syntax!

Soon to come

Soon there will be convenience features to e.g. turn a number of same length Nim sequences to a LaTeX table or helper templates to create a figure.

Also a nice feature would be to generate a full basic TeX file to write the created TeX code into a document and compile it.

In addition to that the compile time checking enum will be extendable at CT using registerTexCommand.

Just why?

Well, I had to generate a bunch of PDFs from a database for the modules / courses in each degree at my department at Uni. At first I wrote the code for TeX generation based on pure string interpolation. But that hurt my soul knowing what Nim is capable of.

So that’s why I decided to see how far one can push native TeX as valid Nim code. Pretty happy with it.

The main part of the code that generates the files mentioned above there can be found here:

https://gist.github.com/Vindaar/545cf13fb09d75843ea0eef0dec1dae0

(the full code is only hosted on an internal, non public Bitbucket instance unfortunately).

Maybe still not the prettiest Nim code one has ever seen (and that file there is WIP anyway), but the TeX parts aren’t gonna change a whole lot. At least I’m happy with this. :)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].