Robitex's Blog

Ideas in the web

Leggere la directory corrente con lualatex


Certi compiti difficili…

In LaTeX si sa, certi compiti sono particolarmente difficili, altri, forse, impossibili. Uno di questi è inserire nel documento la directory corrente. Non che sia indispensabile, anzi, direi che leggere il path del file nel documento solo perché si pensa che un giorno possa essere utile per ritrovare il file, penso sia poco elegante. Comunque…

Risolvere con lualatex

Compilare un sorgente LaTeX con lualatex comporta solo lievi modifiche, e la possibilità di far eseguire codice Lua attraverso la nuova primitiva \directlua{}.
Di per se Lua non offre sofisticate librerie per l’accesso al disco, così occorrerebbe installare la Lua File system Library installabile in Ubuntu con il relativo pacchetto nel repository universe chiamato liblua5.1-filesystem0, ed in Windows con il programma LuaRocks.
Tuttavia LuaTeX viene compilata assieme alla libreria Lua Filesystem, così è possibile utilizzarla senza che si debba installare esplicitamente.

Le funzioni della libreria lfs sono riportate nel manuale disponibile on-line su questo sito, e sono tutte memorizzate nella tabella lfs. Per i nostri scopi utilizzeremo la funzione currentdir(), che restituisce il path della directory corrente, sempre che non ci siano errori.

Riporto il codice di un sorgente LaTeX da compilare con lualatex che conterrà il percorso dello stesso file sorgente, ma che funziona solo con Linux come spiegherò fra poco.

% funziona per Linux
\documentclass{minimal}

\newcommand{\curdir}{%
   \directlua{tex.sprint(lfs.currentdir())}
}

\begin{document}
\curdir
\end{document}

Il post non vuole altro che segnalare quanto compiti assai complicati e dispendiosi in termini di tempo per trovare una soluzione, siano semplici ed eleganti con lualatex, che si basa sul nuovo motore di composizione ancora in fase di sviluppo LuaTeX.

Ed è per questo che è stata riportata la soluzione per Linux, perché quella per Windows è leggermente più complicata: occorre sostituire nel percorso del file il carattere backslash perché se il percorso della directory corrente entra così com’è nel flusso di token, verrà interpretata come una serie di comando che produrranno un errore.

Nei file system di tipo Unix, il carattere che separa i nomi è la slash e non ci sono quindi problemi. In Window se per esempio il path della directory di lavoro è “C:\Documenti” corrisponderà ai caratteri C: seguiti dalla macro \Documenti, un bel inconveniente.

Ecco il codice per Windows (e che funziona perfettamente anche in Linux perché il path rimarrà immutato). Nel codice dovendo inserire il carattere di escape del motore di composizione se ne evita l’effetto utilizzando la macro primitiva string.

% funziona anche in Windows
\documentclass{minimal}

\newcommand{\curdir}{%
    \directlua{
    require "lfs"
    local cd = string.gsub(lfs.currentdir(),
              [[\string\]],
	      [[\string\textbackslash ]])
   tex.sprint(cd)}
}

\begin{document}
\curdir
\end{document}

Rovesciare il punto di vista

Il comando \curdir così come l’abbiamo definito ha un difetto di efficienza: ogni volta che lo eseguiamo, con la libreria lfs determina la directory corrente, ovvero qualcosa che in realtà conoscevamo dalla prima chiamata alla macro.
Se per esempio nel documento il percorso del file viene inserito a piè di pagina, avremo tante chiamate a lfs.currentdir() tante quante sono le pagine stesse, ma se rovesciassimo il punto di vista sfruttando proprio il problema del backslash?

Nel seguente codice, completo per la compilazione con lualatex, si esegue la funzione per determinare il path e poi si inserisce nel flusso dei token che saranno “digeriti” dal motore tipografico, la definizione di una macro che espande semplicemente al path stesso.
In questo modo, la funzione di libreria viene chiamata solo una volta, mentre nel documento l’autore si troverà una macro standard, espandibile ed efficiente.
Per prima cosa, ho racchiuso il codice Lua in un blocco do … end, per eliminare dalla memoria qualsiasi variabile, poi ho memorizzato per comodità in una variabile stringa chiamata bs il carattere di backslash.
La definizione di una macro che espande al path è: \def\curdir{valore del path}, così è sufficiente chiamare la funzione tex.sprint() con l’equivalente del comando, utilizzando l’operatore di concatenazione delle stringhe di Lua sintatticamente definito da due punti .. .

\documentclass{minimal}

\directlua{
    do
       require "lfs"
       local bs = "\string\\"
       local cd = string.gsub(lfs.currentdir(),
              bs,
	      bs.."textbackslash ")

       tex.sprint(bs.."def"..bs.."curdir{"..cd.."}")
    end
}

\begin{document}

\texttt{\curdir}

\emph{\curdir}

\curdir

\curdir

\curdir

\end{document}

Saluti ed Auguri di Buon Natale e Felice Anno nuovo!!!

2 risposte a “Leggere la directory corrente con lualatex

  1. Agostino 22/02/2011 alle 12:48

    Per gestire gli underscore nei persorsi ho usato questo:

    \directlua{
    do
    require "lfs"
    local bs = "\string\\"
    local cd = string.gsub(lfs.currentdir(),
    bs,
    bs.."textbackslash ")

    local us = "\string\_"
    local cd1 = string.gsub(cd,
    us,
    bs.."textunderscore ")

    tex.sprint(bs.."def"..bs.."curdir{"..cd1.."}")
    end
    }

    Saluti,
    Agostino

    • robitex 22/02/2011 alle 13:00

      Ciao Agostino,
      è con grande piacere che ti do il benvenuto sul blog.
      Vedo che adesso ti diletti anche con Lua, eh…
      Ottimo contributo.
      A presto.
      R.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: