I read the question (title) as using some other language to create a TeX document, so this answer is like that.
The language is Ruby, and the library is kramdown which is a library for parsing and converting a superset of Markdown. It includes a LaTeX converter by default, but I wanted to try my hand at making a converter for my own TeX format (which is basically plain-xetex with some additions).
If you look at the sources for the LaTeX converter, you'll see how delightfully easy to approach it is. At least I did, unlike Pandoc's, but that could well be because I'm more familiar with Ruby than I am with Haskell.
Inside the class, one could just handle the conversion in a single method, but like in the LaTeX converter, one could use that to dispatch to a conversion method for a specific element type.
Here's an example of an list element for plain-xetex:
def convert_ul(el, opts)
opts[:level] = opts[:level].to_i.succ
retval = "\\smallskip\n" << inner(el, opts) << '\smallskip'
opts[:level] -= 1
return retval
end
alias :convert_ol :convert_ul
def convert_li(el, opts)
@ulmarks ||= %w(• ⬦ ‒)
type = "\\#{"item" * opts[:level]}"
case opts[:parent].type
when :ul : "#{type}{#{@ulmarks[opts[:level]-1]}} "
when :ol : "#{type}{#{opts[:index]+1}.} "
end << inner(el, opts)
end
Yes it's not perfect ;-)
, but shows how easy it is to start working on the conversion, and start to get real, tangible results!
But the interesting thing I noticed when starting to do this, was that I started to wonder how much of the TeX code I want to create on this conversion step (think about verbatim in footnotes, for example, and other similar \catcode
madness, or TOC, or refs, etc.), and how much I'd want to do as TeX macros. This isn't very clear-cut (for me, at the moment at least); on one hand, one could really go to the extremes and use nothing but the primitives (which would be pretty cool I think), or at the other extreme, build a macro for everything. This realization was really big for me, as it opens up a lot of possibilities.
A ConTeXt converter would be pretty cool to make, too.