[lualatex] Exemples d'utilisation

Tout ce qui concerne le langage TeX/LaTeX et ses variantes. Ce langage est utilisable sur le forum via les balises tex.
[participation réservée aux membres inscrits]
Règles du forum
Merci de soigner la rédaction de vos messages et de consulter ce sujet avant de poster. Pensez également à utiliser la fonction recherche du forum.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

[lualatex] Exemples d'utilisation

Message non lu par MB »

Bonjour, l'objectif de ce sujet est de partager des exemples d'utilisation de lualatex.

La documentation de luatex étant assez austère et ne proposant quasiment aucun exemple, ce sujet peut s'avérer utile à tous ceux qui souhaiteraient s'initier à l'utilisation de ce moteur.
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Voici un premier exemple permettant d'afficher en rouge toutes les lettres majuscules d'un document. Il s'agit d'un exemple inspiré du paquet chickenize.

Code : Tout sélectionner

\documentclass{article}
\usepackage{luacode,lipsum}
\begin{luacode}
color_push = node.new(node.id("whatsit"),node.subtype("pdf_colorstack"))
color_pop  = node.new(node.id("whatsit"),node.subtype("pdf_colorstack"))
color_push.command = 1
color_pop.command = 2
function uppercasecolor(head)
  for line in node.traverse_id(node.id("hhead"),head) do
    for upper in node.traverse_glyph(line.head) do
      if node.has_attribute(upper,luatexbase.attributes.uppercasecolorattr) then
        if (((upper.char > 64) and (upper.char < 91)) or ((upper.char > 57424) and (upper.char < 57451))) then
          color_push.data = "255 0 0 rg"
          line.head = node.insert_before(line.head,upper,node.copy(color_push))
          node.insert_after(line.head,upper,node.copy(color_pop))
        end
      end
    end
  end
  return head
end
luatexbase.add_to_callback("post_linebreak_filter",uppercasecolor,"uppercasecolor")
\end{luacode}
\begin{document}
\lipsum[1-1]
\end{document}
lualatex_red_uppercase.png
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Voici une adaptation de l'exemple précédent, permettant d'afficher en rouge toutes les lettres e (majuscule ou minuscule).

Code : Tout sélectionner

\documentclass{article}
\usepackage{luacode,lipsum}
\begin{luacode}
color_push = node.new(node.id("whatsit"),node.subtype("pdf_colorstack"))
color_pop  = node.new(node.id("whatsit"),node.subtype("pdf_colorstack"))
color_push.command = 1
color_pop.command = 2
function ecolor(head)
  for line in node.traverse_id(node.id("hhead"),head) do
    for n in node.traverse_glyph(line.head) do
      if node.has_attribute(n,luatexbase.attributes.uppercasecolorattr) then
        if (n.char == string.byte("e") or n.char == string.byte("E")) then
          color_push.data = "255 0 0 rg"
          line.head = node.insert_before(line.head,n,node.copy(color_push))
          node.insert_after(line.head,n,node.copy(color_pop))
        end
      end
    end
  end
  return head
end
luatexbase.add_to_callback("post_linebreak_filter",ecolor,"ecolor")
\end{luacode}
\begin{document}
\lipsum[1-1]
\end{document}
lualatex_red_e.png
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Autre exemple inspiré du paquet chickenize et permettant cette fois de supprimer toutes les lettres e (minuscule).

Code : Tout sélectionner

\documentclass{article}
\usepackage{luacode,lipsum}
\begin{luacode}
function remove_e(head)
    for n in node.traverse_glyph(head) do
        if n.char == string.byte("e") then
            node.remove(head,n)
        end
    end
    return head
end

luatexbase.add_to_callback("pre_linebreak_filter",remove_e,"remove all letters e")
\end{luacode}
\begin{document}
\lipsum[1-1]
\end{document}
lualatex_remove_e.png
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
zariski63
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 498
Inscription : jeudi 14 octobre 2010, 09:20
Statut actuel : Enseignant
Localisation : Clermont-Ferrand

Re: [lualatex] Exemples d'utilisation

Message non lu par zariski63 »

Merci beaucoup. En effet on peut faire des choses remarquablement efficaces.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Petit exemple faisant appel à luamplib, qui permet d'exécuter du code Metapost directement via luatex.

Code : Tout sélectionner

\documentclass{article}
\usepackage{luamplib}

\newcommand{\clock}[2]{\leavevmode\begin{mplibcode}
r := 1cm; len := 4bp;
def clock(expr hour, minute) =
  path cadran; cadran = fullcircle scaled (2r); draw cadran;
  for i = 1 step 1 until 12:
    a := 30i;
    draw ((r, 0) -- (r-len, 0)) rotated a;
    endfor;
  drawarrow origin -- r*dir(90-(30*hour+0.5*minute)) scaled 0.6;
  drawarrow origin -- r*dir(90-6*minute) scaled 0.8;
enddef;
beginfig(1); clock(#1,#2); endfig; \end{mplibcode}}

\begin{document}

\begin{center}
\begin{tabular}{ccc}
\clock{20}{30} & \clock{23}{15} & \clock{3}{40}
\end{tabular}
\end{center}

\end{document}
clock.png
clock.png (9.94 Kio) Consulté 2564 fois
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2035
Inscription : samedi 29 décembre 2007, 00:58

Re: [lualatex] Exemples d'utilisation

Message non lu par projetmbc »

Très bon exemple. Que le code est lisible...
Et si une section LuaLaTeX s'ouvrait ?
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Je ne suis personnellement pas très friand de la syntaxe de Metapost (qui est me semble-t-il proche de celle de Metafont) car je suis plus habitué à celle d'Asymptote (plus proche du C++).

Pour ce qui concerne un section lualatex, j'y avais déjà pensé lorsque j'ai restructuré le forum il y a quelques temps, mais vu le faible nombre d'utilisateurs, ça ne semble pas forcément nécessaire, d'autant plus que lualatex reste un compilateur latex parmi d'autres.

Pour l'instant, on pourra se contenter d'indiquer [lualatex] dans le titre des messages qui le concernent.
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Autre petit exemple avec des fonctions permettant de dénombrer des arrangements et des combinaisons.

Voici le contenu du fichier combinatorics.lua dans lequel la fonction cnp donne le coefficient binomial $C_n^p$ et la fonction anp donne le nombre d'arrangements $A_n^p$.

Code : Tout sélectionner

function cnp(n,p)
    if (p == 0 or p == n) then
        return 1
    else
        return n*cnp(n-1,p-1)/p
    end
end

function anp(n,p)
    if p == 0 then
        return 1
    else
        return (n-p+1)*anp(n,p-1)
    end
end

function fwrite(z)
    tex.sprint(string.format("%.0f",z))
end
On peut alors utiliser le fichier tex suivant.

Code : Tout sélectionner

\documentclass{article}
\directlua{dofile('combinatorics.lua')}
\newcommand{\cnp}[2]{\directlua{fwrite(cnp(#1,#2))}}
\newcommand{\anp}[2]{\directlua{fwrite(anp(#1,#2))}}
\begin{document}
\begin{itemize}
\item $A_7^5 = \anp{7}{5}$
\item $C_7^5 = \cnp{7}{5}$
\end{itemize}
\end{document}
Qui va donner le résultat suivant après une compilation lualatex.
combinatorics.png
combinatorics.png (5.68 Kio) Consulté 1321 fois
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

On peut également combiner avec Tikz pour construire un triangle de Pascal.

Code : Tout sélectionner

\documentclass{article}
\usepackage{tikz}
\directlua{dofile('combinatorics.lua')}
\newcommand{\cnp}[2]{\directlua{fwrite(cnp(#1,#2))}}
\newcommand{\anp}[2]{\directlua{fwrite(anp(#1,#2))}}
\begin{document}
\begin{tikzpicture}[scale=0.8,cnp/.style={rectangle,draw,fill=gray!20,minimum size=2em}]
\foreach \n in {0,...,6} {
    \foreach \p in {0,...,\n} {
        \draw (\p,6-\n) node[cnp] {\cnp{\n}{\p}};}}
\end{tikzpicture}
\end{document}
triangle_pascal.png
triangle_pascal.png (13.67 Kio) Consulté 1319 fois
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2035
Inscription : samedi 29 décembre 2007, 00:58

Re: [lualatex] Exemples d'utilisation

Message non lu par projetmbc »

Cela va se finir en un package ... :-)

Tant qu'à faire j'aurais tout fait faire à Lua.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

projetmbc a écrit : dimanche 30 janvier 2022, 17:43 Tant qu'à faire j'aurais tout fait faire à Lua.
Il aurait effectivement été tout à fait possible de construire le triangle de Pascal à l'aide de Metapost, via luamplib.
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Pour les utilisateurs de pstricks, j'en profite pour signaler que le paquet luapstricks permet la compilation de code pstricks directement via lualatex, comme indiqué sur la page oficielle de pstricks.
2021-11-13: update With up-to-date PSTricks you can run yor PSTricks source with lualatex. The output is a PDF file without using GhostScript. The only macro which does not work is \pscharpath.
Par exemple, le code suivant est directement compilé sans aucun problème par lualatex car le paquet intègre un interpréteur Postscript en Lua.

Code : Tout sélectionner

\documentclass[pstricks,border=0.2cm]{standalone}
\usepackage{pstricks-add}
\begin{document}
\psset{algebraic,plotpoints=500}
\begin{pspicture}(-8,-3.5)(8,3.5)
\psellipse[fillstyle=solid,fillcolor=yellow,linewidth=6.5pt](0,0)(8,3.5)
\pscustom*{%
    \psplot{0}{0.5}{2.25}
    \psplot{0.5}{0.75}{3*abs(x)+0.75}
    \psplot{0.75}{1}{9-8*abs(x)}
    \psplot{1}{3}{1.5-0.5*abs(x)-6*sqrt(10)/14*(sqrt(3-x^2+2*abs(x))-2)}
    \psplot{3}{7}{3*sqrt(1-(x^2)/49)}
    \psplot{7}{4}{-3*sqrt(1-(x^2)/49)}
    \psplot{4}{-4}{(abs(x/2)-(3*sqrt(33)-7)*x^2/112)+sqrt(1-(abs(abs(x)-2)-1)^2)-3}
    \psplot{-4}{-7}{-3*sqrt(1-(x^2)/49)}
    \psplot{-7}{-3}{3*sqrt(1-(x^2)/49)}
    \psplot{-3}{-1}{1.5-0.5*abs(x)-6*sqrt(10)/14*(sqrt(3-x^2+2*abs(x))-2)}
    \psplot{-1}{-0.75}{9-8*abs(x)}
    \psplot{-0.75}{-0.5}{3*abs(x)+0.75}
    \psplot{-0.5}{0}{2.25}
}
\end{pspicture}
\end{document}
batman.png
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Un autre petit exemple, qui permet de représenter des dominos via luamplib.

Code : Tout sélectionner

\documentclass{article}
\usepackage{luamplib}

\newcommand{\domino}[2]{\leavevmode\begin{mplibcode}
u := 1cm;
def drawdots(expr n,p) =
    if n mod 2 <> 0:
        drawdot(p+(u/2,u/2));
    fi;
    if n>1:
        drawdot(p+( u/4, u/4));
        drawdot(p+(3u/4,3u/4));
        if n>3:
            drawdot(p+(u/4,3u/4));
            drawdot(p+(3u/4,u/4));
            if n>5:
                drawdot(p+( u/4,u/2));
                drawdot(p+(3u/4,u/2));
            fi;
        fi;
    fi;
enddef;
def domino(expr a,b) =
    pickup pencircle scaled 1pt;
    draw (0,0) -- (2u,0) -- (2u,u) -- (0,u) -- cycle;
    draw (u,0) -- (u,u);
    pickup pencircle scaled 5pt;
    drawdots(a,(0,0));
    drawdots(b,(u,0));
enddef;
beginfig(1); domino(#1,#2); endfig; \end{mplibcode}}

\begin{document}

\begin{center}
\begin{tabular}{cccccc}
\domino{0}{1} & \domino{1}{2} & \domino{2}{3} & \domino{3}{4} & \domino{4}{5} & \domino{5}{6}
\end{tabular}
\end{center}

\end{document}
dominos.png
dominos.png (5.31 Kio) Consulté 1224 fois
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2035
Inscription : samedi 29 décembre 2007, 00:58

Re: [lualatex] Exemples d'utilisation

Message non lu par projetmbc »

Merci pour ce nouvel exemple...

Pour le code, il me semble plus clair d'opter pour ce qui suit (même si je comprends l'idée d'éviter des tests inutiles).

Code : Tout sélectionner

def drawdots(expr n,p) =
    if n mod 2 <> 0:
        drawdot(p+(u/2,u/2));
    fi;
    if n>1:
        drawdot(p+( u/4, u/4));
        drawdot(p+(3u/4,3u/4));
    fi;
    if n>3:
    	drawdot(p+(u/4,3u/4));
        drawdot(p+(3u/4,u/4));
    fi;
    if n>5:
    	drawdot(p+( u/4,u/2));
    	drawdot(p+(3u/4,u/2));
    fi;
enddef;
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Oui, c'est une possibilité.
Un autre exemple dans le même genre, qui permet d'afficher des caractères en braille.

Code : Tout sélectionner

\documentclass{article}
\usepackage{luamplib}

\newcommand{\braille}[1]{\leavevmode\begin{mplibcode}
def braille(expr s) =
    u := 6pt;
    for k=0 upto 5:
        x := (k div 3)*u; y := (3-k mod 3)*u;
        if substring (k,k+1) of s = "0":
            draw fullcircle scaled 3pt shifted (x,y);
        else:
            filldraw fullcircle scaled 3pt shifted (x,y);
        fi;
    endfor;
enddef;
beginfig(1); braille("#1"); endfig; \end{mplibcode}}

\begin{document}

\begin{center}
\begin{tabular}{ccccccccccccc}
\fbox{\braille{111000}} &
\fbox{\braille{101010}} &
\fbox{\braille{101001}} &
\fbox{\braille{010100}} &
\fbox{\braille{011100}} &
\fbox{\braille{000000}} &
\fbox{\braille{110000}} &
\fbox{\braille{111010}} &
\fbox{\braille{100000}} &
\fbox{\braille{010100}} &
\fbox{\braille{111000}} &
\fbox{\braille{111000}} &
\fbox{\braille{100010}}
\end{tabular}
\end{center}

\end{document}
braille.png
braille.png (7.27 Kio) Consulté 1181 fois
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2035
Inscription : samedi 29 décembre 2007, 00:58

Re: [lualatex] Exemples d'utilisation

Message non lu par projetmbc »

Un mystère demeurera... Que peuvent signifier ces symboles L, O, U, I, S, B, R, A, I, L, L, E ?
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Très mystérieux effectivement. :D
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: [lualatex] Exemples d'utilisation

Message non lu par MB »

Encore un exemple inspiré du paquet chickenize, qui permet de compter et d'afficher le nombre de mots dans un document. Cette valeur est affichée à la fois en bas de la dernière page du document et à la fin log (via le callback "stop_run").

Code : Tout sélectionner

\documentclass{article}
\usepackage{luacode,lipsum,xcolor}
\begin{luacode}
wordnumber = 0

function countwords(head)
    for glyph in node.traverse_glyph(head) do
        if glyph.next.id == node.id("glue") then
             wordnumber = wordnumber+1
        end
    end
    wordnumber = wordnumber+1
    return head
end

function printwordnumber()
    texio.write_nl("wordnumber=" .. wordnumber)
end

luatexbase.add_to_callback("pre_linebreak_filter",countwords,"countwords")
luatexbase.add_to_callback("stop_run",printwordnumber,"printwordnumber")
\end{luacode}
\AtEndDocument{\par\vfill\hfill\textcolor{red}{[wordnumber=\directlua{tex.sprint(wordnumber) wordnumber=wordnumber-1}]}}
\begin{document}

\lipsum[1-4]

\end{document}
wordnumber.png
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2035
Inscription : samedi 29 décembre 2007, 00:58

Re: [lualatex] Exemples d'utilisation

Message non lu par projetmbc »

Bonjour et merci mais pour le coup c'est très fragile car par exemple on obtient 8 mots dans le cas suivant.

Code : Tout sélectionner

Un, deux et trois mots : $a + b$ .