2

Context of my question

I am developing bismon (temporary name), some kind of persistent domain specific language for static source code analysis tied to GCC (to become a successor of my late GCC MELT). Details are unimportant here, but curious people might have a look into its README.md on github.

For the purpose of this question, bismon could be viewed as some dynamically typed Scheme or Lua like language (even if it is not really that). I have complete control on it, and I can tailor it to be even more like that. So for this question we could pretend that bismon is some Scheme-like stuff, like Guile

I need to start writing some documentation about it (that was already the case in GCC MELT, where I generated .texi file for texinfo), and some of that documentation (hopefully more and more) will be generated by bismon itself (even if obviously it is not)

I am running all that on Linux/Debian, and I don't care about other operating systems. I have texlive, so lualatex (version 1.07), and hevea. I'm fluent on Linux & Ocaml (and somehow Lua) and hacking a tiny bit is not an issue for me (e.g. patching slightly hevea in Ocaml, or writing simple lua scripts).

I need to generate a PDF report (with some hyperlinks inside it), and some HTML5 form of it (that is, a set of HTML5 and other files nicely looking thru some recent browser). Of course I'm thinking of using lualatex & hevea (but I could chose other approaches, provided they are based upon free software preferably packaged on Debian).

Ideally I want to have some of the documentation generated, since showing the actual output. And some of that could happen in the same process (e.g. a Guile one) running during the whole processing of the document.

It is important for me to generate some of the documentation, including sample "inputs" and "outputs" (this ensure that the documentation is failful to the current state of bismon).

So I dream of being able to typeset something like

Here is the factorial in Scheme:
\begin{myguilecode}
 (define (fact n) (if (< n 1) 1 (* n (fact (- n 1)))))
\end{myguilecode}

And later in the same document, I dream of having

When we ask about \texttt{fact}, our Scheme interpeter shows that 
it is some function:
\begin{runguilecode}
fact
\end{runguilecode}
Of course, we can compute the factorial of 5:
\begin{runguilecode}
(fact 5)
\end{runguilecode}

and at that point I dream that the code is nicely appearing, with its output. Notice that I need the same guile process to (conceptually) co-exist with LaTeX one. So perhaps something similar to the effect of GeneratedLaTeX

When we ask about \texttt{fact}, our Scheme interpeter shows that 
it is some function:
\begin{alltt}
fact
\end{alltt}
$\Rightarrow$
\begin{alltt}
\$1 = #<procedure fact (n)>
\end{alltt}
Of course, we can compute the factorial of 5:
\begin{alltt}
(fact 5)
\end{alltt}
$\Rightarrow$
\begin{alltt}
\$2 = 120
\end{alltt}

For example the Ocaml manual is available in HTML and PDF formats and some parts of it is generated.

Choosing between two (and a half) approaches.

  • I could use some preprocessing, perhaps "literate programming" like technique, that is generate LaTeX .tex files. E.g. I would code (perhaps in GPP) some preprocessable stuff which gets expanded to the LaTeX code, e.g. generates a huge LaTeX file containing GeneratedLaTeX

  • I could use some interpretation techniques, that is write some lua scripts for LuaLaTeX which runs Guile (somewhere) and read its output. Basically something similar to some \input doing a popen(3) (or even computing some of it in Lua), not an fopen(3). It is probably trickier for HeVeA.

  • I might consider generating all of the LaTeX from inside bismon, but I am not easy with that idea today. I feel it is more reasonable to have some of the LaTeX typed manually by me under emacs

My current preference is for the second approach.

Your comments are welcome.

  • 1
    Welcome to TeX.SX! Maybe you can look into PythonTeX, which is despite the name not only for Python. – moewe May 3 '18 at 14:05
4

That is not problem in LuaTeX. Thanks to the FFI (requires LuaJITTeX or LuaTeX ≥ 1.0.3) you can call arbitrary C functions. Since Guile is an embedding language it comes with a rich C-API which can be easily used from within LuaTeX. I simply copied the function declarations from the C header file and pasted them into the ffi.cdef.

This requires --shell-escape because FFI is considered unsafe but no external programs will actually be called.

The code sample below is of course specific to Guile but since you are the developer of bismon, you could provide such functions, compile bismon as a dynamically linked library and load it into Lua to perform similar tasks.

\documentclass{article}
\usepackage{luacode}
\begin{luacode}
local ffi = assert(require("ffi"))

local SCM = assert(ffi.load("libguile-2.2.so"))

ffi.cdef[[
typedef struct scm_unused_struct *SCM;
void scm_init_guile (void);
SCM scm_c_eval_string (const char *expr);
SCM scm_c_lookup (const char *name);
SCM scm_variable_ref (SCM var);
SCM scm_object_to_string (SCM obj, SCM printer);
char *scm_to_locale_string (SCM str);
void scm_dynwind_free (void *mem);
]]

SCM.scm_init_guile()
function guile_eval_string(expr)
    local object = SCM.scm_c_eval_string(expr);
    local display = SCM.scm_variable_ref(SCM.scm_c_lookup("display"))
    local result = SCM.scm_object_to_string(object, display);
    local c_str = SCM.scm_to_locale_string(result)
    local str = ffi.string(c_str)
    SCM.scm_dynwind_free(c_str)
    return str
end
\end{luacode}

% Run guile code
\newcommand\guile[1]{\directlua{guile_eval_string("\luaescapestring{#1}")}}

% Run guile code and typeset its output using verbatim catcodes
\newcommand\guilerun[1]{\directlua{tex.sprint(-2,guile_eval_string("\luaescapestring{#1}"))}}

\usepackage{alltt}
\usepackage{environ}

\NewEnviron{myguilecode}{%
  % Typeset ...
  \begin{alltt}
    \BODY
  \end{alltt}
  % ... and run!
  \guile{\BODY}%
}

\NewEnviron{runguilecode}{%
  % Typeset ...
  \begin{alltt}
    \BODY
  \end{alltt}
  $\Rightarrow$
  % ... and run and typeset result
  \begin{alltt}
    \guilerun{\BODY}
  \end{alltt}
}

\begin{document}

Here is the factorial in Scheme:
\begin{myguilecode}
(define (fact n) (if (< n 1) 1 (* n (fact (- n 1)))))
\end{myguilecode}
When we ask about \texttt{fact}, our Scheme interpeter shows that 
it is some function:
\begin{runguilecode}
fact
\end{runguilecode}
Of course, we can compute the factorial of 5:
\begin{runguilecode}
(fact 5)
\end{runguilecode}

\end{document}

enter image description here

  • Thanks. What about getting HTML, perhaps with hevea ? – Basile Starynkevitch May 4 '18 at 10:46
  • 1
    What do you mean by “getting HTML”? Maybe have a look at ConTeXt, it can export XML. – Henri Menke May 4 '18 at 10:51
  • I mean, some set of HTML5 and other files nice looking with a modern web browser – Basile Starynkevitch May 4 '18 at 10:54
  • 1
    @BasileStarynkevitch No, LuaLaTeX generates PDF (maybe DVI). There exist some incomplete external LaTeX parsers (e.g. tex4ht, pandoc), which can translate a subset into HTML, but not from within LaTeX itself. If you are auto-generating documentation for your program, you should probably look at special documentation generators such as Doxygen or Sphinx. These can export to all kinds of formats (they can also generate PDF via LaTeX). – Henri Menke May 4 '18 at 10:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.