Robitex's Blog

Ideas in the web

Archivi Categorie: LaTeX

Un simpatico effetto funzionale in LuaTeX


La domanda

A volte capita di chiedersi all’improvviso se l’idea che ci è appena balenata in mente può effettivamente esser realizzata.

Stavo esaminando alcune caratteristiche di LuaTeX quando una domanda è sorta spontanea: è possibile creare una macro che accetti una funzione matematica scritta dall’utente e la esegua su un argomento anch’esso variabile?

Si tratta quindi di far eseguire una funzione matematica definita sul momento, in pieno stile functional.

La macro dovrebbe accettare due argomenti: il primo è la funzione da usare e il secondo l’argomento numerico su cui eseguire il calcolo:

\applyfun{<funzione>}{<numero>}

Nel documento troveremo poi il risultato cercato. La cosa interessante è che il primo parametro della macro, la funzione, è concettualmente simile al secondo argomento essendo entrambi dei valori.

Per esempio, vorremmo poter scrivere:

Il quadrato di 10 è \applyfun{function (x) return x*x end}{10}!

LuaTeX della famiglia TeX

LuaTeX è un motore di composizione tipografico della gloriosa famiglia TeX. Questi programmi compilano un file di testo scritto dall’utente per fornire il corrispondente documento pdf.

Nel file di testo — detto sorgente — si adopera una sorta di linguaggio istruendo il programma alla gestione di sommari, riferimenti incrociati, titoli, eccetera.

In molti paesi opera un TUG, un TeX User Group. In Italia è attivo da 15 anni il GuIT Gruppo di utilizzatori Italiani di TeX, il cui sito può darvi tutte le informazioni necessarie.

Dimenticavo di dirvi che il sistema TeX è stato uno dei primi esempi di software libero, perciò siete ancor più liberi di usarlo per scrivere i vostri documenti.

La risposta

Ebbene la risposta è positiva! Si, è possibile e se non ci credete compilate con LuaTeX il codice seguente:

% luatex

% definizione della macro
\def\applyfun#1#2{%
\directlua{
local fun = #1
tex.sprint(fun(#2))
}}

Experimental!

\applyfun{function (x) return math.log(x)+10 end}{12}

Ok.

Il quadrato di $\pi$ vale
\applyfun{function (x) return x*x end}{3.14159}.

End job.
\bye

E mi raccomando, non provate a farlo con Word o LibreOffice…
Alla prossima.
R.

Annunci

TeXStudio: inserire la data corrente


Perché data e ora?

Una delle cose che mi mancavano in TeXStudio era la possibilità d’inserire nel sorgente LaTeX la data e l’ora corrente con una semplice combinazione di tasti. Questa funzionalità mi permette di tracciare molto semplicemente l’evoluzione temporale del documento e di misurare il tempo che ho impiegato per scriverne una data porzione.

Infatti, in un sorgente LaTeX è possibile inserire dei commenti tramite il carattere di percentuale: tutto quello che vi compare dopo verrà ignorato dal compositore tipografico in fase di compilazione.

Una stringa di timestamp potrebbe per esempio essere:

% 12/06/2015 :: 11:35:32 ::

Come vedete il timestamp è preceduto dal carattere di commento del simbolo percentuale seguito dalla data e dall’ora. Sarebbe un tantino noioso inserirlo a mano digitandolo da tastiera nella finestra dell’editor per di più quando il tempo stringe e la relazione va consegnata 🙂

Per chi non ha mai sentito il termine LaTeX, ho l’onere di provocare io questo evento e di indirizzarvi naturalmente al sito del TeX User Group nazionale — il GuIT — per trarne ulteriori informazioni.

Scripting in TeXStudio

Pur preferendo l’essenzialità di uno shell editor per LaTeX come TeXWorks, ultimamente ho cominciato a usare TeXStudio per le sue numerosissime feature. Tra queste vi è la possibilità di associare una combinazione di tasti all’esecuzione di uno script in Javascript come recita il manuale.

Questo post vi spiega come realizzarlo.

Al lavoro con le macro in Javascript

Innanzi tutto si apre la finestra di modifica delle macro che vedete qui sotto (da menù: Macro -> Modifica macro):

TeXStudio macro window

TeXStudio macro window

Si preme il tasto + per inserirne una nuova e dopo averne specificato il nome basta scrivere il codice nella rispettiva finestra inserendo obbligatoriamente nella prima riga il testo “%SCRIPT”. Questa chiave farà in modo che TeXStudio interpreti il codice seguente come codice Javascript.

Per inserire testo possiamo avvalerci del metodo insertText() dell’oggetto editor. Facciamo una prova con questo primo script:

%SCRIPT

editor.insertText("% testo inserito via macro :-)")

Adesso, tornati alla finestra principale di TeXStudio possiamo eseguire lo script con la combinazione di tasti “Shift + F1” se abbiamo inserito la macro nella posizione 1. Aprendo il menù macro dovremo vedere tra le voci quella nuova di prova con l’indicazione della combinazione di tasti associata.

A questo punto è solo questione di trovare le funzioni Javascript per la data: Date() e di fare un po’ di prove con i metodi dell’oggetto. Ovviamente non è mia intenzione approfondire il linguaggio Javascript ma solo scrivere il codice per l’inserimento automatico del timestamp secondo un formato personalizzato mostrato precedentemente.
Prima di mostrarvi il codice completo vi saluto.
R.

%SCRIPT
var dt = new Date()
var y = dt.getFullYear()
var m = dt.getMonth() + 1
if (m < 10) { m = "0" + m}

var d = dt.getDate()
var s1 = "% " + d + "/" + m + "/" + y

var hour = dt.getHours()
var min = dt.getMinutes()
if (min<10) {min = "0"+min}
var sec = dt.getSeconds()
if (sec<10) {sec = "0" + sec}
var s2 = " :: " + hour + ":" + min + ":" + sec

editor.insertText(s1 + s2 + " :: ")

Roma: GuITmeeting 2013


Il luogo del convegno

Ciao a tutti,
tra pochi giorni si terrà a Roma il decimo convegno nazionale del GuIT.

Partecipate numerosi correndo ad iscrivervi perchè l’evento è un’ottima occasione per saperne di più sul sistema TeX ed è libero e gratuito.

Si parlerà dunque di un software libero sviluppato da oltre trent’anni in grado di produrre ottima documentazione sia per qualità tipografica che per una modalità di lavoro e gestione dei dati.

Il convegno è un momento importante nell’attività del GuIT, il TeX User Group italiano ufficiale che ha come missione quella di diffondere l’uso di TeX nel nostro paese, per conoscere, apprezzare e parlare nel clima di amicizia e condivisione 🙂 .

Arrivederci a Roma!
R.

Differenza di orari in TeX


Ciao,
in questo assolato e caldo meriggio d’estate, vi presento problema e soluzione di un caso particolare che forse a questo punto vi incuriosirà.

Differenza di orari

Dovendo compilare un report, non potevo certo non farlo con LaTeX ed allora mi son trovato il problema di calcolare diverse differenze orarie. Per esempio tra le 10:25 e le 11:40 sono trascorse un’ora e quindici minuti, alias 1:15.

Torna comodo scrivere una macro con argomenti delimitati — visto come sono TeXnico? — che calcoli i minuti trascorsi dalla mezzanotte per ciascun orario, esegua la differenza e riconverta il risultato nel formato ore:minuti.

Ecco il codice da compilare con pdflatex ovviamente:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

% contatori di minuti
\newcount\mi
\newcount\mii

% determina la differenza oraria
\def\timediff(#1:#2-#3:#4){%
% mii contiene i minuti dell'orario di uscita
\mii=#3
\multiply\mii by 60
\advance\mii by #4
% mi contiene i minuti dell'orario di entrata
\mi=#1
\multiply\mi by 60
\advance\mi by #2
% mii contiene il numero dei minuti effettuati
\advance\mii by -\mi
\mi=\mii
\divide\mii by 60
\the\mii:%
\multiply\mii by 60
\advance\mi by -\mii
\ifnum\mi<10
    0%
\fi
\the\mi
}

\begin{document}
Tra le 14:35 e le 18:38 abbiamo: \timediff(14:35-18:38).
\end{document}

Se poi devo arrotondare alla mezz’ora per difetto?

Tranquilli, niente panico (cit.), è sufficiente

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

% contatori di minuti
\newcount\mi
\newcount\mii

% determina la differenza oraria
% con l'arrotandamento alla mezz'ora
% per difetto
\def\timediff(#1:#2-#3:#4){%
% mii contiene i minuti dell'orario di uscita
\mii=#3
\multiply\mii by 60
\advance\mii by #4
% mi contiene i minuti dell'orario di entrata
\mi=#1
\multiply\mi by 60
\advance\mi by #2
%% mii contiene il numero dei minuti effettuati
\advance\mii by -\mi 
%% mii contiene il numero delle mezz'ore
\divide\mii by 30 
%
\ifodd\mii
    \mi=3
\else
    \mi=0
\fi
%% mii contiene il numero delle ore
\divide\mii by 2
\the\mii:\the\mi 0%
}

\begin{document}
Tra le 14:35 e le 18:38 abbiamo: \timediff(14:35-18:38).
\end{document}

Una volta tanto finisco prima — non vi farò l’esempio della soluzione equivalente in LaTeX3 od in LuaTeX, questo passa il convento e dovrete accontentarvi.
Ok, allora a voi la parola con un classico…
Alla prossima.
R.

Opuscoli e booklet


Sommario

Utilizzeremo il sistema TeX per comporre documenti in formato A4 su libretti in formato A3.

Capita…

Capita di dover stampare fronte retro dei documenti ripiegando i fogli in un libretto. Chiameremo questa modalità booklet oppure opuscolo.
L’esempio è il seguente: abbiamo a disposizione un documento di quattro pagine nel formato A4 e vorremo comporlo nel formato A3 fronte retro in modo che il foglio A3 ripiegato formi l’opuscolo, come in questa raprresentazione:

Fronte:
+-----++-----+
|  4  ||  1  |
|     ||     |
+-----++-----+

retro:
+-----++-----+
|  2  ||  3  |
|     ||     |
+-----++-----+

La soluzione con LaTeX

Quella che vi propongo è una soluzione che ha il pregio di rappresentare un esempio che può essere applicato a casi anche molto più complicati di quello in esame, e consiste nel salvare un file di testo puro nella stessa cartella contenente il file che chiameremo docA4.pdf con le quattro pagine, con il seguente contenuto:

\documentclass{minimal}
\usepackage[a3paper,landscape]{geometry}
\usepackage{pdfpages}

\begin{document}
\includepdf[pages={4,1,2,3},nup=2x1]{docA4}
\end{document}

Compilando questo file (dategli l’estensione .tex) quello che succede è questo:

  1. viene impostato il formato di pagina A3 orizzontale;
  2. viene caricato il pacchetto pdfpages che definisce il comando \includepdf;
  3. e poi si inseriscono nel documento una alla volta e nella sequenza corretta, le pagine del documento in A4.

Il comando \includepdf offre molte altre opzioni: consultate la documentazione del pacchetto per scoprirle.

Un documento di esempio

Volendo, possiamo produrre sempre con LaTeX un documento da utilizzare per verificare che il codice precedente funziona. Basta compilare questo codice più complicato del precedente perché fa uso di un po’ di programmazione della nuova libreria LaTeX3, in modo da poter generare documenti demo di qualsiasi lunghezza (basta cambiare l’argomento del comando \demodoc):

\documentclass{minimal}
\usepackage[a4paper]{geometry}
\usepackage{graphicx}
\usepackage{xparse}

%%% codice LaTeX3
\ExplSyntaxOn
\NewDocumentCommand{ \demodoc }{ m }
   {
   \demodoc_repeat:n { #1 }
   }

\cs_new_protected:Nn \demodoc_repeat:n
   {
   \int_step_inline:nnnn { 1 }{ 1 }{ #1 }
      { \centering
        \scalebox{12}{##1}
        \newpage
      }
   }
\ExplSyntaxOff

\begin{document}
\demodoc{4}
\end{document}

Ecco pronto da scaricare il file risultato docA4.pdf.

Note tecniche

Per avvalersi delle magie compositive di pdfpages per la costruzione di opuscoli, occorre installare sul vostro computer una distribuzione TeX – che fa sempre comodo e non costa nulla – ed io vi consiglio spassionatamente TeX Live disponibile per praticamente tutti i sistemi operativi.

Ciao a tutti!

Napoli: tutto pronto per il GuITmeeting


GuITmeeting2012

Tra pochissimi giorni, Sabato 27 ottobre 2012 si terrà a Napoli il GuITmeeting 2012, uno dei più importanti tra i meeting organizzati dal GuIT, Gruppo utilizzatori italiani di TeX, che per la prima volta non si svolgerà nell’aula magna della scuola Sant’Anna di Pisa, ma nell’altrettanto prestigiosa sala del Centro congressi Partenope dell’Università degli Studi di Napoli Federico II.

Anch’io parteciperò molto volentieri essendo perfino riuscito a presentare un lavoro di cui vi posso dire solo il titolo: “La grafica ad oggetti con LuaTeX”.

Non mancate sarà una bellissima occasione

Qualsiasi cosa stiate facendo, collegatevi subito con il sito del GuIT alla pagina del modulo d’iscrizione 🙂 !
Grazie, ci vediamo a Napoli!

L’Arte della pericolosità sismica – Parte 2


Sommario

Con un nuovo tocco di colore, torniamo sulla mappa della pericolosità sismica italiana per produrre un’altra pagina artistica. Questa volta useremo una scala di colori con quelli della nostra bandiera…

Colore italiano

Riprendendo il codice illustrato in questo post, è sufficiente creare una nuova funzione Lua, riportata in seguito, per ottenere la mappa sottostante:

La mappa di pericolosità sismica in versione tricolore

La mappa di pericolosità sismica in versione tricolore

Il colore, funzione dell’accelerazione, varierà da verde per il valore minimo a bianco per l’accelerazione media, fino ad arrivare al rosso per l’accelerazione massima.
In LaTeX, un colore può essere miscelato facilmente con il bianco specificandone dopo il nome ed un punto esclamativo, un valore variabile da 0 a 100. Il valore nullo corrisponde al colore bianco, mentre il valore 100 lascia intatto il colore.
Così, l’espressione ‘green!50’ corrisponde al colore bianco con il 50% di verde.

Il codice seguente mostra la funzione che genera l’espressione del colore in funzione dell’accelerazione. Valori bassi di pericolosità saranno rappresentati da un colore verde mescolato con sempre meno bianco a mano a mano che l’accelerazione decresce, mentre valori elevati saranno rappresentati da un colore rosso mescolato ad una componente decrescente di bianco:

-- funzione di interpolazione lineare
local function linear(x,x1,x2,y1,y2)
   return y1 + (y2-y1)*(x-x1)/(x2-x1)
end

-- funzione scala di colori dal verde al rosso
-- passando per il bianco
local function green2red(ag)
   local agmean = (agmax+agmin)/2
   local basecol, val
   if ag < agmean then
      basecol = 'green'
      val = linear(ag, agmin, agmean, 100, 0)
   else
      basecol = 'red'
      val = linear(ag, agmean, agmax, 0, 100)
   end
   
   return string.format('%s!%d', basecol, val)
end

Ho stampato anche questa nuova mappa, naturalmente a colori, e l’ho appesa in ufficio a beneficio della collezione primavera estate 2012.
Ciao.

L’Arte della pericolosità sismica


Sommario

Attraverso i software del mondo TeX, creeremo una visualizzazione artistica della mappa di pericolosità sismica italiana contenuta nella norma D.M. 14/01/2008. L’elaborazione grafica sarà opera del potente pacchetto TikZ progettato per LaTeX, mentre un piccolo programma in Lua si occuperà della costruzione logica.

Pericolosità sismica S1

Il progetto S1 di INGV, l’Istituto Nazionale di Geofisica e Vulcanologia, recepito poi dalla normativa tecnica, ha definito la pericolosità sismica nel territorio italiano attraverso una griglia di punti distanti uno dall’altro poco più di 5 km.
L’idea è quella di replicare le rappresentazioni grafiche diffuse dall’INGV con gli strumenti del mondo TeX, realizzando mappe a colori con i valori dell’accelerazione di picco al suolo PGA, Peak Ground Accelaration (un risultato è riportato in fondo all’articolo).

Immagine della mappa S1 tratta dal sito INGV

Immagine della mappa S1 tratta dal sito INGV

Struttura del codice

Ecco una descrizione di come verranno elaborati i dati:

  • uno script principale in Lua, efficiente linguaggio di scripting, leggerà i dati della pericolosità producendone un file di testo contenente comandi grafici per TikZ;
  • un sorgente LaTeX elaborerà i comandi producendo la mappa grafica in formato pdf.

I dati

Ho tradotto la tabella scaricabile dal sito del Consiglio dei Lavori Pubblici, contentente i dati di pericolosità sismica, in una forma direttamente comprensibile da Lua: ecco come appare il contenuto del file di dati che ho chiamato ‘GridS1.lua’:

GridS1 = {
[13111] = {lon=6.5448, lat=45.134, Tr30={0.0263, 2.50, 0.18}, Tr50={0.0340, 2.51, 0.21}, ...ecc
[13333] = {lon=6.5506, lat=45.085, Tr30={0.0264, 2.49, 0.18}, Tr50={0.0341, 2.51, 0.21}, ...ecc
[13555] = {lon=6.5564, lat=45.035, Tr30={0.0264, 2.50, 0.18}, Tr50={0.0340, 2.51, 0.20}, ...ecc
...ecc

Creare i comandi grafici

Disegneremo per ciascun punto della griglia S1, un quadratino colorato secondo una data scala di colori associata al valore della PGA, ma per farlo dobbiamo risolvere due problemi:

  • tradurre la coppia longitudine, latitudine dei punti in coordinate nel piano x, y;
  • associare un colore al valore di accelerazione.

Il sorgente Lua mostrato nel seguito dapprima carica in memoria i dati strutturati della griglia, determina i valori minimi e massini dell’accelerazione tra tutti i 10751 punti (per il tempo di ritorno di 475 anni) utili in seguito, poi definisce le due funzioni fondamentali di trasformazione delle coordinate (trasf()) e di associazione valore->colore (wavecolor).

Preparato il terreno, lo script si conclude con la funzione go(), che scrive su un file esterno chiamato defpoint.tex, le istruzioni TikZ di disegno.

Notate che la funzione go() accetta come argomenti anche delle funzioni. Il vantaggio immediato di questo tipo di programmazione disponibile in Lua è che la funzione go() diviene indipendente sia dal tipo di trasformazione di coordinate che dalla scala di colore (io ho scelto di lavorare con la definizione di colore basato sulla lunghezza d’onda della luce con rapporto lineare rispetto alla PGA).

Per i più curiosi, nei commenti del codice sono riportati i due punti della maglia S1 corrispondenti al punto sismicamente più pericoloso e quello meno pericoloso sul territorio della penisola italiana…

-- carica la tabella dati dal file GridS1.lua
dofile "GridS1.lua"

-- funzione di massimo o minimo valore
local function S1(funval, key)
   local rif = funval(GridS1[13111])
   local id

   for idx, t in pairs(GridS1) do
      local val = funval(t)
      if key == "max" then
         if  val > rif then
            rif = val
            id = idx
         end
      elseif key == "min" then
         if val < rif then
             rif = val
             id = idx
          end
       else
          error("The key '"..key"' is not supported.")
       end
    end
    return rif, id
end
-- funzioni di estrazione dati singolo nodo
local function Lat(t)
    return t.lat
end
local function Lon(t)
    return t.lon
end
local function Ag475(t)
    return t.Tr475[1]
end
local function countNode()
    local i = 0
    for _, t in pairs(GridS1) do
       i = i + 1
    end
    return i
end
-- valori minimi e massimi dei dati di mappa
local agmax, idmax = S1(Ag475, 'max')  --> 0.278 , 49640
local agmin, idmin = S1(Ag475, 'min')  --> 0.0364, 12693

-- latitudine
local latmax = S1(Lat, 'max')   --> 47.178
local latmin = S1(Lat, 'min')   --> 36.573

-- longitudine
local lonmax = S1(Lon, 'max')   --> 18.594
local lonmin = S1(Lon, 'min')   --> 6.5448

-- numero nodi S1 (solo per saperlo...)
local numnode = countNode()     --> 10751

-- funzione di servizio
local function makecmdfile(fn, t)
   local outputfile = assert(io.open(fn..".tex","w"))
   outputfile:write(table.concat(t,"\n"))
   outputfile:close()
end

-- restituisce le coordinate di mappa
-- da quelle geografiche
local function trasf(lon, lat)
   -- fattore di conversione gradi->cm
   local f = 4.1

   return 0.80*lon*f, lat*f
end

-- funzione scala di colori wavelets
local function wavecolor(ag)
   local w1 = 363
   local w2 = 814
   local m = 80
   w1 = w1 + m
   w2 = w2 - m
   return w1 + (w2-w1)*(ag-agmin)/(agmax-agmin)
end

-- maschera di formato disegno
local cmask = '\\convertcolorspec{wave}{%d}{rgb}\\col\\color[rgb]{\\col}'
local dmask = '\\draw (%0.3f,%0.3f) node {};'

-- filename = nome senza estensione del file risultato
-- fcoord = funzione di trasformazione coordinate
-- fcolor = funzione di trasformazione colore
local function go(filename, fcoord, fcolor)
   -- memorizzazione comandi
   local t = {}
   for id, dati in pairs(GridS1) do
      local ag = Ag475(dati)
      local lt = Lat(dati)
      local ln = Lon(dati)

      t[#t+1] = string.format(cmask, fcolor(ag))
      t[#t+1] = string.format(dmask, fcoord(ln,lt))
   end

   makecmdfile(filename, t)
end

-- esecuzione
go('defpoint', trasf, wavecolor)

Creare la mappa

Per creare la mappa è sufficiente compilare con pdfLaTeX questo minuscolo file:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{xcolor}
\tikzstyle{every node}=[
    fill,
    minimum size=0.1pt
]

\begin{document}
\begin{tikzpicture}
\input{defpoint}
\end{tikzpicture}
\end{document}

Risultato

La mappa risultato è questa, insieme di 10751 quadratini colorati in modo diverso uno dall’altro (fate un click sull’immagine per scaricarla, un’esperienza da brivido…):

Mappa della pericolosità sismica italiana

La mappa della pericolosità sismica italiana risultato dell’elaborazione descritta nell’articolo

Note tecniche

Per riprodurre la mappa eseguendo il codice mostrato nel post, occorre disporre di una installazione TeX, come TeX Live o MiKTeX, e l’interprete Lua, tutti strumenti gratuiti, o meglio, liberi.
Avremo potuto lavorare con un unico strumento (Lua incorporata in TeX, ovvero LuaTeX, ma lascio il facile esercizio al lettore che non perderà l’occasione di inventarsi nuove scale di colore… 🙂
Alla prossima!

LuaTeX and METAPOST


La libreria MPlib in LuaTeX

METAPOST, il noto linguaggio di disegno vettoriale, è stato incluso in LuaTeX sotto forma della libreria MPlib. Possiamo quindi inserire codice METAPOST direttamente in un sorgente LuaTeX.

Questa modalità, non richiede conversioni del formato d’uscita di METAPOST (.mps) ne la necessità di particolari opzioni di compilazione, mentre per procedere ancora più velocemente con l’unico passo di compilazione, basta utilizzare un editor come TeXWorks, in cui LuaTeX si avvia con un semplice click.
Da riga di comando darete invece la classica istruzione:

... alla riga di comando
... (occorre una installazione di
... TeX Live abbastanza recente)

$ luatex nomefile

Sorgente modello

In concreto, trovate di seguito il template del codice in linguaggio TeX dove si dovrà inserire il codice METAPOST tra le macro \mplibcode e \endmplibcode, con le uniche attenzioni di non lasciare in esso, ne righe vuote ne commenti con il carattere percentuale:

% source template
% LuaTeX with Metapost

\input luamplib.sty
\nopagenumbers

\mplibcode
   <codice METAPOST>
\endmplibcode
\bye

Il codice fornirà il pdf della figura che scontorneremo poi con l’utility pdfcrop (ecco perché si sopprime la numerazione di pagina), per inserire il risultato in altri documenti. Naturalmente, mutatis mutandis, potremo lavorare allo stesso modo ma con LuaLaTeX per avere a disposizione la potenza espressiva di LaTeX.

Un esempio è riportato nel seguente codice, che produce la figura successiva scaricabile come pdf.

% a drawing example

\input luamplib.sty
\nopagenumbers

\mplibcode
beginfig(1);
u := 100mm;
for a = 0 step 15 until 90:
draw origin -- u*dir(a)
  withpen pencircle scaled 2pt
  withcolor red;
endfor;
endfig;
\endmplibcode
\bye

An example of a METAPOST figure building directly in LuaTeX engine.


Non male!
Un saluto.
R.

Click and script


Scarica l’articolo nel formato PDF

Sommario

In questo post impareremo come personalizzare il menù contestuale in Nautilus, il gestore di file incorporato in Gnome, fino a compilare al volo sorgenti LaTeX e compiere moltissime altre operazioni che possono essere ripetitive.

Il menù contestuale

Nelle moderne interfacce grafiche il menù contestuale è un efficace idea che presenta all’utente le operazioni effettuabili su uno specifico oggetto. Se per esempio si tratta di un file compresso il click destro sull’icona che lo simboleggia, attiverà un menù contestuale che presenta le apposite voci per l’estrazione del contenuto.

In Linux, nel Desktop Environment Gnome è possibile associare a questi menù piccoli programmi per lanciarli comodamente dopo aver selezionato i file d’interesse.

Nautilus-scripts

Nautilus è il file manager di Gnome. Grazie al supporto per lo scripting, le operazioni per creare una nuova voce di menù contestuale sono davvero semplici, allo stesso modo di quelle da svolgere per creare un nuovo modello di documento come già illustrato in questo post. Basta creare il file con il codice, assegnargli i permessi di esecuzione e spostarlo nella directory nascosta $HOME/.gnome2/nautilus-scripts.

Menù contestuale su un file compresso in Gnome

Menù contestuale su un file compresso in Gnome

Come è naturale sui sistemi Linux, possiamo scrivere script in molti linguaggi, da Bash a Python. Noi utilizzeremo anche Lua pertanto dovrete assicurarvi che sia installato sul vostro sistema.

I nostri comandi personalizzati

Ecco in concreto, alcune idee di personalizzazione del menù. Ciascun nuovo comando contestuale deriva da esigenze della pratica quotidiana.
Molte altre idee possono essere realizzate per rendere più semplice l’utilizzo del pc, per esempio unire più file di testo o spedire documenti ad un indirizzo di posta elettronica…

Mandare in stampa un documento

Se desidero lanciare la stampa di un file PDF lo apro con un visualizzatore ed eseguo il comando di stampa. Se i PDF da stampare sono molti invece, apro il terminale, posiziono la working directory e lancio la stampa di tutti i PDF presenti con il comando:

$ lpr *.pdf

Con qualche conoscenza in più di Bash (il linguaggio standard per l’amministrazione dei sistemi Linux ma anche di quelli Mac OS X ormai), si costruisce un piccolo e semplicissimo script:

#!/bin/bash

for arg do
    lpr "$arg"
done

Salviamone il contenuto in un file di testo chiamato per esempio goToPrinter, assegniamogli i permessi di esecuzione (anche dal menù Proprietà) e spostiamolo nella directory nascosta $HOME/.gnome2/nautilus-scripts. Di seguito la sequenza dei comandi e l’immagine della sessione corrispondente al terminale:

$ chmod +x goToPrinter
$ mv goToPrinter ~/.gnome2/nautilus-scripts
Sessione al terminale per la creazione del Nautilus script

Sessione al terminale per la creazione del Nautilus script

Elencare file

Modificando un poco lo script precedente possiamo ottenere facilmente un file di testo contenente la lista dei file selezionati sostituendo ad lpr il comando echo e reindirizzandone l’output verso un file. Utilizzeremo poi la libreria zenity per mostrare un dialogo che mostri all’utente il numero dei file conteggiati.

#!/bin/bash

for arg do
    echo "$arg"
done >> listoffiles.txt

zenity --info --width=200 --height=100 \
       --title="Conteggio file elencati" \
       --text="Numero di file elencati: $# "

Compilare un sorgente LaTeX

Compilare un sorgente LaTeX non è un problema se ci si avvale di un editor come TeX Works, oppure direttamente del terminale, ma se lo possiamo fare con un semplice click destro sulla selezione di file è davvero elegante.
Il codice in Lua provvede a filtrare i file selezionati al momento dell’apertura del menù contestuale in base all’estensione solitamente assegnata ai sorgenti LaTeX.

#!/usr/bin/lua

-- ottengo la lista dei file selezionati
-- dalla variabile d'ambiente opportuna
--
local s = os.getenv("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS")

-- per ogni file con estensione .tex
-- procedo alla compilazione
--
for path in string.gmatch(s,"(.-)\n") do
   -- estrazione estensione
   local ext = string.match(path,"%.(.-)$")
   
   -- se l'estensione esiste allora compilo
   -- se è un sorgente .tex
   if ext then
   if string.lower(ext) == "tex" then
      local ps = "(.-)%." .. ext .. "$"
      local name = string.match(path,ps)
      
      os.execute('pdflatex -interaction=nonstopmode "'..name..'"')
      os.remove(name..".log")
      os.remove(name..".aux")
   end
   end
end

-- end of Lua script

Ottenere il pdf di file di testo

Con poche modifiche possiamo adattare il codice precedente per ottenere uno script che converte i file di testo in formato PDF utilizzando LaTeX:

#!/usr/bin/lua

local docsource = [[
\documentclass[a4paper]{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[italian]{babel}

\usepackage[margin=20mm]{geometry}

\usepackage{inconsolata}

\begin{document}
\ttfamily
%s
\end{document}
]]

-- ottengo la lista dei file
local s = os.getenv("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS")

for path in string.gmatch(s,"(.-)\n") do
   -- estrazione estensione
   local ext = string.match(path,"%.(.-)$")
   
   -- se l'estensione esiste allora creo il pdf con LaTeX
   if ext then
   if string.lower(ext) == "txt" then
      local ps = "(.-)%." .. ext .. "$"
      local filename = string.match(path,ps)
      
      -- lettura del file
      local textfile = io.open(path,"r")
      local content = string.gsub(textfile:read("*all"),"\n","\n\n")
      local sourcetexfile = string.format(docsource,content)
      textfile:close()
      
      -- creazione sorgente
      local sf = io.open(filename..".tex","w")
      sf:write(sourcetexfile)
      sf:close()
      
      os.execute("pdflatex -interaction=nonstopmode "..filename)
      os.remove(filename..".log")
      os.remove(filename..".aux")
      os.remove(filename..".tex")
   end
   end
end

-- end of Lua script

Conclusioni

Il menù contestuale è davvero comodo. In Linux possiamo utilizzare diversi linguaggi di scripting per creare nuove voci di comandi con cui semplificare il lavoro quotidiano analizzando attentamente le nostre necessità.
Un saluto.

Note tecniche

Sul sistema devono essere installati e correttamente configurati i pacchetti e gli eseguibili di un sistema TeX ed un interprete Lua.
Gli esempi potrebbero richiedere leggere modifiche per distribuzioni Linux diverse da Ubuntu 10.04.

%d blogger hanno fatto clic su Mi Piace per questo: