Robitex's Blog

Ideas in the web

Archivi Mensili: gennaio 2011

Installare Kile sotto Windows


Procediamo con calma

Leggendo meglio un post che annunciava una nuova versione beta per Kile, uno dei migliori editor per LaTeX per gli utenti del pinguino, ho notato un link in basso, quello delle news. Dalla sezione delle news sono poi passato all’home page dello spartano sito di Kile dove con sorpresa ho notato che tra i sistemi operativi supportati compariva anche Windows, cosa che veniva confermata in ultima riga con la frase :

Kile can run natively on Microsoft Windows. Installation instructions can be found here.

Non che prima la cosa fosse impossibile, ma adesso diviene così semplice che…

I passi dell’installazione

Naturalmente è necessario che una distribuzione TeX (come MiKTeX o TeX Live) sia già correttamente installata sul sistema, dunque, le istruzioni si possono seguire direttamente dal Wiki dedicato. Di seguito vi riporto la procedura come l’ho seguita io.

Per prima cosa occorre installare un piccolo (ma ben fatto) programma dal sito The KDE on Windows Initiative, scaricandone l’eseguibile che svolge la funzione di installer. Costruito come un wizard, questo programma si è rivelato assai robusto presentando step a cui quasi sempre è sufficiente rispondere premendo il tasto Next lasciando così le impostazioni di default, tranne per scegliere il server di download, che ho impostato a http://www.winkde.org per usufruire delle versioni più recenti forse anche a scapito della velocità di download, e per selezionare i due pacchetti Kile, dato per una versione del 2 gennaio 2011, e kdebase-workspace come potete vedere nello screenshot qui sotto.

A package selection step on the KDE installer

A package selection step on the KDE installer

Evviva, Kile è sbarcato su Windows!

Terminate le fasi dell’installazione (la più lunga è quella del download dei file), l’editor si potrà avviare immediatamente dal menù Start di Windows Xp o di Windows 7, nel gruppo Office della voce KDE 4.5.4 Realese ed eccolo in splendida forma:

Devo dire che fa un certo effetto vedere il carattere backslash nei percorsi di configurazione: Kile è effettivamente sbarcato su Windows…
Alla prossima!

Annunci

Un modello di pagina per appunti


Prendere appunti

Per qualsiasi studente prendere appunti si rivela un attività importante per utilizzare al meglio i momenti di spiegazione da parte dei docenti, ma anche i partecipanti ad una conferenza od ad un incontro aziendale possono avvantaggiarsi con l’applicazione di un metodo che per forza di cose deve essere personalizzato.

Vi sono diversi metodi che si traducono in un modello di pagina con cui, durante la lezione, applicare le regole che consistono essenzialmente nel rimanere concentrati capendo i concetti che si stanno ascoltando e nel riportarli per importanza e struttura, e nel ripassare il prima possibile per aggiungere particolari e fissare i contenuti.

Il web è una fonte di informazioni utile, ma occorre sempre sperimentare e raffinare. Molto utili per esempio, sono frecce e schemi anche molto semplici, simboli di abbreviazione ed aree di pagina a diversa priorità.

Il modello che ho messo a punto si suddivide in due aree affiancate: la principale detta Notes è quella dove vengono trascritti i concetti principali eventualmente adottando un identazione (a questo scopo utilizzo dei piccoli puntini sulla riga come vedremo tra poco), ed un area laterale destra detta Secondary dove inserire brevi note su curiosità, dettagli od altri riferimenti.

Download modello pagina singola

Download modello pagina fronte/retro

Codice Metapost

Dall’idea di disegnare pagine di quaderno per la scuola elementare, descritta in questo mio post, ne ho tratto il seguente codice Metapost facilmente personalizzabile che realizza il modello descritto.

Il codice è suddiviso in tre sezioni: l’avvio con la definizione dei principali parametri geometrici del modulo, la sezione delle funzioni ed il disegno vero e proprio degli elementi della pagina. Con questa organizzazione, è semplice modificare un parametro iniziale (per esempio la distanza tra le righe Notes), mentre la definizione di funzioni di disegno rende più compatta e concettuale l’operazione di disegno.

Da notare anche come si è fatto uso del font monospaziato Inconsolata utilizzando nel preambolo l’istruzione verbatimtex (che ho tratto da un post del forum del GuIT), quindi per far girare il codice occorre una distribuzione abbastanza completa del sistema TeX, che naturalmente comprende l’eseguibile di Metapost chiamato mpost.

prologues:=3;

verbatimtex
\documentclass{minimal}
\usepackage{inconsolata}
\nofiles
etex; 

outputtemplate := "%j.mps";

% Modello per appunti
beginfig(1)
   
   %%% sezione definizione costanti dimensionali
   
   % dimensione di pagina
   pagewidth := 210mm;
   pageheight:= 297mm;
   
   % margini delle linee area Notes
   sxNotes := 16mm; % sinistro
   dxNotes := 52mm; % destro
   tpNotes := 23mm; % superiore
   btNotes := 15mm; % inferiore
   
   dxSecondary := 10mm; % bordo destro area secondaria
   gap := 2mm;          % distanza linee Notes e Secondary
   
   % distanza dei punti di livello
   d := 12mm;
   
   % altezza linea principale
   q := 6mm;
   
   %%% sezione definizione funzioni

   % funzione di disegno riga orizzontale
   def notesLine(expr y)=
      % spessore linea
      sp := 0.28pt;
      
      % disegno linea
      draw (sxNotes,y+2.25mm)--
           (sxNotes + sp/2,y)--
           (pagewidth-dxNotes-sp/2,y)
               withpen pencircle scaled sp
               withcolor 0.4white;

      % disegno punti di struttura
      drawdot (sxNotes+d,y)
         withpen pencircle scaled 1.5sp
         withcolor 0.4white;

      drawdot (sxNotes+2d,y)
         withpen pencircle scaled 1.5sp
         withcolor 0.4white;
   enddef;
   
   % funzione di disegno riga area Secondary
   def secondaryLine(expr y)=
      % spessore linea
      sp := 0.2pt;
      
      % disegno linea
      draw (pagewidth-dxNotes-sp/2 + gap,y)--
           (pagewidth-dxSecondary-sp/2,y)
         withpen pencircle scaled sp
         withcolor 0.6white;
   enddef;
   
   def labLine(expr a, txt, l)=
      label.urt(txt, a) withcolor 0.5white;
      
      lg := 1pt;
      draw a+(-lg, 4mm-lg)--
           a-(lg, lg)--
           a+(l, -lg)
           withcolor 0.5white;
   enddef;
   
   
   %%% disegno punti di bounding box pagina
   drawdot (1pt,1pt)
      withpen pencircle scaled 0.5pt
      withcolor white;
   drawdot (pagewidth-1pt,pageheight-1pt)
      withpen pencircle scaled 0.5pt
      withcolor white;
   
   %%% disegno modulo degli appunti
   
   % numero di linee del notes
   nn := floor((pageheight-tpNotes-btNotes)/q);
   
   %
   % Notes: area principale linee orizzontali
   for i=0 upto nn:
      notesLine( btNotes + i * q);
      secondaryLine( btNotes + i * q );
   endfor;
   
   refsx := pagewidth-dxNotes+gap;
   labY    := 10.5mm;
   labGap  := 5mm;
   
   % lesson label
   labLine((refsx,pageheight- labY),
          btex \ttfamily Lesson: etex,
          dxNotes-gap-dxSecondary);

   labLine((refsx,pageheight-labY-labGap),
           btex \ttfamily Date: etex,
          dxNotes-gap-dxSecondary);

   labLine((refsx,pageheight-labY-2*labGap),
           btex \ttfamily Page: etex,
          dxNotes-gap-dxSecondary);
   
   % speaker label

   labLine((sxNotes,pageheight-labY),
           btex \ttfamily Speaker: etex,
           pagewidth-dxNotes-sxNotes);

   labLine((sxNotes,pageheight-labY-labGap),
           btex \ttfamily Istitute: etex,
           pagewidth-dxNotes-sxNotes);

   labLine((sxNotes,pageheight-labY-2*labGap),
           btex \ttfamily Contact info: etex,
           pagewidth-dxNotes-sxNotes);
   
   % disegno circoli di foratura
   circleDist := 80mm;
   circleBottom := (pageheight - 3*circleDist)/2;
   
   for i=0 upto 3:
      draw fullcircle
         scaled 4mm
         shifted (12.75mm, i * circleDist + circleBottom)
         withpen pencircle scaled 0.5pt
         withcolor 0.5 white;
   endfor;
   
   % altezza y dei segni mediani dei fori
   circlei := circleBottom+circleDist/2;
   circleii:= circlei+2*circleDist;
   
   % disegno marche orizzontali di foratura
   draw (11mm, circlei)--(14mm, circlei)
      withpen pencircle scaled 0.5pt
      withcolor 0.5 white;
   draw (11mm, circleii)--(14mm, circleii)
      withpen pencircle scaled 0.5pt
      withcolor 0.5 white;
endfig;
end

Buona lezione…

Da Word a jpeg in 10 secondi


Scarica l’articolo in formato PDF per la stampa

Quando una soluzione è …

A dimostrazione di quanto sia ormai affidabile, utile, pratico ed efficiente il software libero vi riporto un piccolo episodio accaduto stamani, quando mi hanno rivolto la seguente domanda “Mi puoi trasformare Word in immagini?”, che tradotto significa voler ottenere le immagini jpeg di ciascuna delle pagine di un documento Word.

elegante per davvero come…

L’unico vero limite del software libero si direbbe sia un fattore esterno ai set di funzionalità ed è questo: la volontà degli utenti di imparare ad utilizzarlo.

Sono disponibili via web manuali, guide e tutorial di efficaci strumenti di lavoro, ma è raro che vengano utilizzati nonostante gli utenti ne conoscano il nome e l’ambito operativo.

Certo, se l’utente usa il solito programma non perderà tempo ad impararne altri, costasse solo il tempo dell’installazione, ma questa situazione in moltissimi casi non è quella ideale quando si possono ottenere risultati migliori, a volte assai migliori, con software di costo zero utilizzati con regolare licenza.

Ma gli strumenti liberi non sono solo un aiuto in sostituzione di altri software a cui siamo abituati. Essi favoriscono una forma mentis con cui l’utente adatta, combina e sperimenta nuove inaspettate soluzioni. Bando quindi alla pigrizia, alla sciatteria informatica e vai con l’inventiva e la qualità fino al dettaglio: il computer non ci sostituisce nel dare eleganza al nostro lavoro

dare un paio di comandi…

Per fortuna, molti software liberi sono multipiattaforma e quindi disponibili anche per Windows, dunque ho aperto una finestra di console dopo aver ottenuto il documento Word in formato pdf a cui ho assegnato il nome di daritagliare.pdf, ed ho digitato un paio di comandi:

>pdfcrop --margin=5 daritagliare.pdf daconvertire.pdf
>convert -density 200 daconvertire.pdf image.jpg

Il primo programma, pdfcrop, fa parte della collezione TeX ed elabora il pdf restituendolo con le pagine prive di bordo, il secondo di Image Magick e produce i file jpeg dalle pagine ritagliate del pdf (i nome dei file vengono numerati). La procedura è indipendente dal numero di pagine, mentre è possibile regolare la risoluzione delle immagini agendo sull’opzione -density.

Ritagliando il pdf prima della trasformazione in immagine, la pagina può essere scontornata perfettamente con pdfcrop, l’utility utilissima di Heiko Oberdiek. Image sarà poi veramente Magick.

Ciao.

Verticalizzare nodi in Nolian


Scarica l’articolo nel formato PDF per la stampa

Nolian scripting series, episode 3

Verticalizzare! Quando?

Di solito non modello le fondazioni a platea direttamente in InMod perché preferisco costruire la mesh per conto mio direttamente in Nolian, mi è capitato quindi, di importare da un file binario, i dati di una platea di una struttura molto simile rispetto in quella in lavorazione (in realtà la stessa struttura modificata in varie versioni, sigh!).

L’operazione è riuscita perfettamente ma alcuni nodi al piede dei pilastri, risultavano collegati alla mesh con un rigel non perfettamente verticale. Nolian ha aggiustato le posizioni dei nodi che capitavano vicini a nodi esistenti, di sua spontanea volontà.

Per rendere i rigel di nuovo verticali, occorreva risistemare le coordinate dei nodi corrispondenti della mesh, ma ecco che una manciata di righe di codice Lua può abbreviarci il lavoro.

La nuova funzione axy()

Ho pensato ad una funzione chiamata axy(), ovvero assegna x ed y, con il seguente funzionamento: seleziono il nodo al piede del pilastro e poi quello sulla platea, dopo di che la funzione esce fatta la modifica.

Ecco il codice da gestire secondo le indicazioni contenute nel primo episodio (ricordo che dopo la configurazione sarà disponibile in console il comando axy() ):

function axy(x,y)
     if not x or not y then
          print("Sel node con la posizione planimetrica desiderata...")
          _sel.doselect( true )
          local nodobase = _sel.nodes()
          _sel.clear()
          if #nodobase > 1 then
             print ("Selezionati più nodi, riprova.")
             return
          else
	     local p = _n.get(nodobase[1])
	     x = p.x
             y = p.y
          end
     end
     
     print("Selezionare nodo da cambiare con x=" .. x .." e y="..y .." ...")
   
     _sel.doselect( true )
     local nodo = _sel.nodes()
     _sel.clear()
     
     if #nodo > 1 then
         print ("Selezionati più nodi, riprova.")
         return
     end
     
     local pointAux = {}
     pointAux.x = x
     pointAux.y = y
     nodeIndex = nodo[1]
     
     _n.set(nodeIndex, pointAux)
end

Commento al codice

La prima parte del codice della funzione non fa altro che decidere se le coordinate planimetriche sono o no state specificate dall’utente. Se no, aspetta che si selezioni un nodo prelevandone poi i valori utili delle coordinate con la funzione di libreria _n.get() che, come recita il manuale stringatissimo di Softing (più stringato di così…), restituisce il punto relativo all’indice del nodo specificato. Punto che non è altro che una tabella Lua con chiavi x, y, e z.
Riassumendo, la funzione _sel.nodes() restituisce una tabella con gli indici dei nodi selezionati, che in realtà in questo caso sono solo uno, appunto di posizione 1. L’indice dell’array viene passato alla _n.get() per il prelievo dei valori.

La seconda parte invece, effettua l’assegnazione ad un secondo nodo selezionato: si crea infatti un punto detto pointAux con le nuove coordinate e lo si passa alla funzione _n.set() assieme all’indice del nodo selezionato. Più difficile a dirsi che a farsi!

Grazie ed alla prossima!

Gli strumenti di Linux


Scarica l’articolo in PDF per la stampa

Quanto è immediato sviluppare

Improvvisamente mi sono reso conto che un sistema Linux è una formidabile collezione di strumenti informatici che molte volte sono immediatamente disponibili fin dalla prima installazione e, per di più, si tratta di software rilasciato con licenze libere e gratuite in continuo sviluppo.

Grazie ad internet, pochi minuti sono l’unica cosa che serve per attrezzare il nostro computer. Prendiamo per esempio Ubuntu che appena finita l’installazione offre già tutti i principali linguaggi di scripting come Bash, Python, Lua, Perl, Ruby, e che permette il prelievo dai repository ufficiali di potenti compilatori come gcc. Anche le altre maggiori distribuzioni non sono da meno.
Strumenti con cui siamo liberi di costruire i programmi complessi e le utility per compiti specifici, e che quindi ci mettono a disposizione direttamente l’enorme potenza elaborativa dell’informatica.

In altre parole, un sistema operativo libero offre un eccezionale kit di strumenti liberi per lo sviluppo e, viceversa, che è stato necessario scriverli per poter sviluppare liberamente.

Verificheremo ora quanto sia immediato accedere ad uno di questi strumenti.

Hello World!

E allora apriamolo il terminale per compilare ed eseguire il classico programma Ciao Mondo! in uno dei linguaggi per eccellenza che ha fatto il successo commerciale di Microsoft, Oracle e Google: il C++.

Step 0: gcc

Per installare gcc in Ubuntu date il comando (tranquilli se il compilatore è già installato il gestore di pacchetti vi dirà semplicemente se per esso sono disponibili o no aggiornamenti):

$ sudo apt-get install build-essential

Step 1: scrivere il sorgente C++

Aprite l’editor di testi che preferite per digitare il seguente codice del programma didattico per eccellenza:

#include <iostream>

int main () {
    std::cout << "Hello World!\n";
}

Salvate poi il file con il nome hello.cpp nella cartella cpp posizionata sulla Scrivania.
Diremo dopo qualche spiegazione sul codice perché vorrei concentrarmi per ora sulla procedura pratica di compilazione.

Il sorgente di Hello World! nell'editor

Il sorgente di Hello World! nell'editor

Step 2: compilazione

All’apertura del terminale la directory di lavoro è la /HOME dell’utente indicata anche con il carattere tilde ~ come potete notare nell’immagine quì sotto. Raggiungiamo la nostra directory di lavoro con il comando cd (change dir) usufruendo del completamento automatico dei nomi premendo il tasto Tab, e compiliamo il sorgente con il comando g++:

:~$ cd Scrivania
:~/Scrivania$ cd cpp
:~/Scrivania/cpp$ g++ hello.cpp -o hello

Il compilatore gcc per i programmi in C++ è chiamato appunto g++ e prende come argomenti il nome del file sorgente e il nome del programma risultante detto file oggetto per cui è individuato da quello che segue l’opzione -o.

La sequenza di compilazione ed esecuzione del programma

La sequenza di compilazione ed esecuzione del programma

Step 3: esecuzione

Il compilatore ha dunque prodotto il file oggetto che abbiamo chiamato hello. Si tratta di un file binario contenente le istruzioni eseguibili direttamente dal nostro processore. Eseguiamolo con:

:~/Scrivania/cpp$./hello

Quindi alla riga di comando basta semplicemente scrivere il nome del programma e dare un invio, considerando che il punto rappresenta la directory di lavoro (quindi ~/Scrivania/cpp). Si infatti i comandi digitati al terminale vengono ricercati per l’esecuzione in un set di directory di cui la nostra cpp non fa parte, allora è necessario dare il percorso completo del file oggetto, proprio con quel punto slash.

1.234.567 è un numero primo?

Non ho certo la pretesa di insegnare il C++, ma posso darvi alcune rapide spiegazioni commentando un esempio di programma più complesso: eseguire il test di primalità su un numero.

Si tratta di provare a dividere il numero n per tutti i suoi probabili divisori da 2 all’intero che non supera il valore della radice quadrata di n. Usiamo l’operatore modulo rappresentato dal simbolo di percentuale, che restituisce il resto della divisione intera tra due numeri naturali:

int a = 1234;
int b = 56;

int resto = a % b;

Nel precedente frammento di codice C++, si dichiarano gli interi a e b e si assegna ad una terza varibile il valore del resto della loro divisione. Se il resto è zero allora b è un divisore di a, che perciò non è un numero primo (in questo caso il resto vale 2).

Ecco il sorgente completo. Inseritelo in un file chiamato prime.cpp, compilatelo ed eseguitelo alla stesso modo degli step precedenti per conoscere se effettivamente il numero 1234567 è o non è un numero primo.

Potete anche copiare il file oggetto nella cartella ~/bin (la tilde vi ricordo rappresenta la home directory dell’utente), che è un percorso tra quelli del set di ricerca degli eseguibili. Una volta fatto, basterà digitare il nome del programma indipendentemente dalla working directory (veramente molto comodo).

#include <iostream>  // per cout
#include <cmath>     // per floor() e sqrt()

int main() {
    using namespace std;
 
    int n = 1234567;            // numero da testare
    int limit = floor(sqrt(n)); // limite superiore dei divisori
    bool isPrime = true;        // flag di uscita dal ciclo for
    int firstDiv;               // il più piccolo divisore trovato
    
    for (int i=2; i<=limit; i++){
         if (n%i==0){
              isPrime = false;
              firstDiv = i;
              break;
         }
    }
        
    if (isPrime) {
         cout << "The number " << n << " is prime!\n";
    } else {
         cout << "The number " << n << " is not prime, sorry\n";
         cout << "Divider: " << firstDiv << ".\n";
    }
}// end of program>

Le due direttive include del codice, a rigore non fanno parte del linguaggio. Indicano semplicemente che devono essere rese disponibili le funzionalità delle librerie iostream, per le operazioni standard di ingresso/uscita (ovvero input/output), e cmath, per le funzioni matematiche standard. Altra istruzione che ha a che fare con la gestione del codice è l’istruzione using namespace che inserisce i nomi di std nel namespace globale. Ciò significa che i nomi delle funzioni della libreria standard (namespace std) saranno direttamente disponibili senza che sia necessario specificarne il namespace, come invece abbiamo fatto nel primo programma, dove è stato utilizzato il qualificatore :: (la funzione cout, console output della libreria standard si scrive al completo std::cout).

Chi ha progettato il C++ ha fatto di tutto per consentire di strutturare i programmi in ogni maniera, ed il modo più scontato è quello di suddividerli in moduli funzionali. Alcuni particolari file chiamati header contengono appunto le dichiarazioni degli oggetti di un modulo, ne dichiarano in altre parole l’interfaccia, ed è questo che li rende possibili.

La sintassi del C++, che assomiglia volutamente a quella del genitore C, semplice, essenziale, è stata a sua volta ispiratrice di molti altri linguaggi successivi ed altrettanto famosi come Java e C#.

Alla prossima. Ciao.

Righe e quadretti


Download per gli impazienti

Dai link seguenti potete scaricare i fogli pronti per la stampa in formato PDF. Per le personalizzazioni ed i perfezionamenti non vi resta che leggere l’intero post dove vi viene illustrato il codice che li realizza.

Pagina a quadretti
Pagina a righe
Carta Millimetrata

La stampa dei file richiede un attimo di attenzione perché il vostro lettore PDF potrebbe adattare la pagina all’area stampabile che è leggermente più piccola per via dei margini. Meglio allora stampare senza che siano settati parametri di adattamento.
Notate anche che le dimensioni dei due file sono veramente minuscole perché non contengono nessun font.

Per scaricare l’articolo intero in PDF cliccate questo link.

Quadretti

Se siete insegnanti di prima elementare (o genitori), può essere utile poter stampare pagine quadrettate per la matematica od a righe per l’italiano.
Ecco allora un simpatico post per inizio anno, in cui disegneremo con Metapost i due fogli desiderati.

Ho misurato le dimensioni di un quaderno a quadretti A4 di prima elementare ottenendo che un quadretto misura 5 mm: cambiando questo parametro all’inizio del sorgente e ricompilando (vedi l’ultimo paragrafo “Note pratiche”), potete ottenere la dimensione del quadretto che volete.

Quaderno a quadretti

Per prima cosa posizioniamo l’origine del sistema di riferimento della figura in basso a destra.
Il codice Metapost è caratterizzato dalle due funzioni hline() e vline() che disegnano rispettivamente linee orizzontali e verticali prendendo tre parametri: l’ordinata (o l’ascissa) della linea, lo spessore ed il colore di penna da usare (le proprietà della penna passate come argomento saranno utili per la stampa della pagina a righe).
Si noti che le coordinate delle linee sono stati corretti di metà dello spessore di linea per produrre una figura esattamente inclusa in una pagina di formato A4.
Infatti, una linea orizzontale larga quanto il foglio A4 e di ordinata per esempio 100mm si scriverebbe semplicemente come nel frammento di codice seguente, ma così la linea uscirebbe di metà spessore utilizzando una penna pencircle. Riportiamo quindi anche il codice per la linea entro pagina:

% linea sbordante di metà spessore agli estremi
draw (0,100mm) -- (210mm,100mm);

% linea entro i margini di pagina
% assumendo che lo spessore della penna sia 1pt
draw (0.5pt,100mm) -- (210mm-0.5pt,100mm);

La griglia a quadretti sarà poi ottenuta con due cicli for, le cui variabili intere determineranno la posizione della linea sul foglio.

% imposta il nome del file di putput contenente il disegno
% come nomefilesorgente.mps
outputtemplate :="%j.mps";

% Quaderno a quadretti
beginfig(1)
   % dimensione di pagina (A4)
   pagewidth := 210mm;
   pageheight:= 297mm;
   
   % dimensione del quadretto
   q := 5mm;
   
   % numero colonne e righe
   nx := floor(pagewidth/q)-1;
   ny := floor(pageheight/q)-1;
   
   % funzione di disegno riga verticale
   def vline(expr x, sp, col)=
      draw (x,0+sp/2)--(x,pageheight-sp/2)
         withpen pencircle scaled sp
         withcolor col;
   enddef;

   % funzione di disegno riga orizzontale
   def hline(expr y, sp, col)=
      draw (0+sp/2,y)--(pagewidth-sp/2,y)
         withpen pencircle scaled sp
         withcolor col;
   enddef;
   
   % loop di disegno righe verticali
   for i=0 upto nx:
      vline(q/2+i*q, 0.32pt, 0.7white);
   endfor;
   
   % loop di disegno righe orizzontali
   for i=0 upto ny:
      hline(q/2+i*q, 0.32pt, 0.7white);
   endfor;
endfig;
end

Righe

Il quaderno a righe per l’italiano della prima elementare è un po’ più complicato perché le righe orizzontali sono diversamente spaziate. L’altezza di una riga è di 19mm con due spaziature da 7mm per avere una riga centrale di 5mm (la figura in alto illustra questo tipo di spaziatura). Inoltre le due righe verticali esterne sono colorate in rosso cupo.

Quaderno a righe (click to download the PDF file)

Quaderno a righe (click to download the PDF file)

Nel codice seguente si è assunto un sistema di riferimento con origine nell’angolo in alto a sinistra (semplicemente perché ho misurato il margine superiore di 27.5mm).

outputtemplate :="%j.mps";

% Quaderno a righe
beginfig(1)
   pagewidth := 210mm;
   pageheight:= 297mm;
   
   h1 := 7mm;
   h2 := 5mm;
   hb := 27.5mm;
   
   x1 := 18mm;
   x2 := x1 + 170mm;
   col := 28mm;
   
   % funzione di disegno riga verticale
   def vline(expr x, sp, col)=
      draw (x,-0-sp/2)--(x,-pageheight+sp/2)
         withpen pencircle scaled sp
         withcolor col;
   enddef;

   % funzione di disegno riga orizzontale
   def hline(expr y, sp, col)=
      draw (0+sp/2,y)--(pagewidth-sp/2,y)
         withpen pencircle scaled sp
         withcolor col;
   enddef;
   
   def row(expr y)=
      hline(y-h1, 0.28pt, 0.7white);
      hline(y-h1-h2, 0.28pt, 0.7white);
      hline(y-2*h1-h2, 0.28pt, 0.7white);
   enddef;
   
   vline(x1, 0.32pt, 0.8red);
   vline(x2, 0.32pt, 0.8red);
   
   hline(-hb, 0.28pt, 0.7white);
   
   for i=0 upto 12:
      row(-hb-i*(2*h1+h2));
   endfor;
   
   for i=0 upto 4:
      vline(x1+col+1mm+i*col, 0.28pt, 0.7white);
   endfor;
endfig;
end

Carta millimetrata

Il formato della carta millimetrata prevede una quadrettatura principale ogni centimetro, una secondaria interna ogni 5mm, e la quadrettatura più sottile ad ogni millimetro. L’origine del sistema di riferimento della figura è sempre in alto a sinistra.

Carta millimetrata (click to download)

Carta millimetrata (click to download)

Prima versione

Nella prima versione del codice l’idea è quella di disegnare le righe orizzontali e verticali nei tre spessori della carta millimetrata con 6 cicli for. Si inizia con le linee sottili poi si reimposta spessore e colore della penna per quelle intermedie e così via. Questo ordine fa in modo che quando le linee verticali ed orizzontali si sovrappongono quelle più scure non vengano segnate con colore meno intenso.
Dal punto di vista del linguaggio di Metapost nel codice si è utilizzato la funzione mod che restituisce il resto della divisione tra i due operandi.

outputtemplate :="%j.mps";

% Foglio di carta millimetrata
%   Origine sistema di riferimento:
%   in alto a sinistra del foglio
beginfig(1)
   u := 1mm;
   pagewidth := 210;
   pageheight:= 297;
      
   % funzione di disegno riga verticale
   def vline(expr x)=
      draw (x*u, -sp/2)--(x*u, -pageheight*u+sp/2);
   enddef;

   % funzione di disegno riga orizzontale
   def hline(expr y)=
      draw (sp/2, y*u)--(pagewidth*u-sp/2, y*u);
   enddef;
   
   % line sottili
   sp:= 0.15pt;
   drawoptions(withpen pencircle scaled sp
               withcolor 0.70white);
   
   for i=1 upto pageheight-1:
      if not (i mod 5 = 0):
         hline( -i );
      fi;
   endfor;
   
   for i=1 upto pagewidth-1:
      if not (i mod 5 = 0):
          vline( i );
      fi;
   endfor;
   
   % linee intermedie
   sp:= 0.30pt;
   drawoptions(withpen pencircle scaled sp
               withcolor 0.55white);
   
   for i=5 step 10 until pageheight-1:
      hline( -i );
   endfor;
   
   for i=5 step 10 until pagewidth-1:
      vline( i );
    endfor;
   
   % linee pesanti ad 1 centimetro
   sp:= 0.42pt;
   drawoptions(withpen pencircle scaled sp
               withcolor 0.45white);
   
   for i=10 step 10 until pageheight-1:
      hline( -i );
   endfor;
   
   for i=10 step 10 until pagewidth-1:
      vline( i );
    endfor;
endfig;
end

Seconda versione

La seconda soluzione utilizza due soli cicli for, uno per le linee orizzontali ed uno per le linee verticali, e lo spessore è di volta in volta regolato da una funzione chiamata importance che in base a quale linea sta per essere disegnata imposta colore e spessore opportuno. La funzione importance rende la soluzione più elegante della precedente con il vantaggio che è immediato regolare il suo costrutto if per ottenere qualsiasi tipo di quadrettatura, per esempio per aggiungere una marcatura ogni 10 centimetri. Tuttavia tracciando prima tutte le righe in una direzione, le righe più chiare nell’altra si sovrappongono a quelle più scure già presenti con un risultato in stampa non perfetto.

outputtemplate :="%j.mps";

% Foglio di carta millimetrata
%   Origine sistema di riferimento:
%   in alto a sinistra del foglio
beginfig(1)
   u := 1mm;
   pagewidth := 210;
   pageheight:= 297;
   
   % funzione di definizione dello spessore
   def importance(expr n)=
      if n mod 10 = 0:
         sp := 0.42pt;
         drawoptions(withcolor 0.425white);
      elseif n mod 5 = 0:
         sp := 0.30pt;
         drawoptions(withcolor 0.550white);
      else:
         sp := 0.15pt;
         drawoptions(withcolor 0.700white);
      fi;
   enddef;
   
   % funzione di disegno riga verticale
   def vline(expr x)=
      importance(x);
      draw (x*u, -sp/2)--(x*u, -pageheight*u+sp/2)
      withpen pencircle scaled sp;
   enddef;

   % funzione di disegno riga orizzontale
   def hline(expr y)=
      importance(y);
      draw (sp/2, y*u)--(pagewidth*u-sp/2, y*u)
      withpen pencircle scaled sp;
   enddef;
   
   for i=1 upto pageheight-1:
      hline( -i );
   endfor;
   
   for i=1 upto pagewidth-1:
      vline( i );
   endfor;
endfig;
end

Note pratiche

Per una prima introduzione a Metapost potete leggerla in questo post, mentre per l’installazione è conveniente installare una distribuzione TeX adatta per il vostro sistema come per esempio TeX Live che vi rifornirà di splendidi programmi liberi e gratuiti come appunto Metapost.
Per installare la TeX Live vi sono molte guide che trovate pure in questo blog, per esempio questa per Ubuntu Linux e questa per Windows.

Per la compilazione dei sorgenti occorre aprire una finestra di comando (o terminale) e digitare il comando mpost nomefile dove nomefile è il file testuale che contiene il codice.
La figura generata da Metapost sarà il file dal nome nomefile.mps che sostanzialmente contiene istruzioni Postscript. Per tradurle nel formato PDF occorre scrivere un file sorgente LaTeX e compilarlo con pdflatex come il seguente (modificare opportunamente il nome del file da includere):

\documentclass{minimal}
% serve l'opzione hiresbb per leggere
% i valori del bounding box di alta
% risoluzione
% l'immagine vettoriale da inserire
% è esattamente un rettangolo A4
\usepackage[hiresbb]{graphicx}
\usepackage[margin=0pt,a4paper]{geometry}
\begin{document}
\noindent\includegraphics{quadri.mps}
\end{document}

In definitiva, la procedura classica per ottenere il PDF comprende due compilazioni la prima con Metapost e la seconda con pdflatex.
Per comodità vi riporto anche uno script in Lua sul cui file basta fare un doppio click per far eseguire tutte le compilazioni (una sorta di make). Perché funzioni i file contenenti il codice Metapost delle figure ed i sorgenti LaTeX per la produzione del PDF, devono essere chiamati come risulta dai commenti iniziali del codice:

#!/usr/bin/lua

--[[
     Quaderno a quadretti:
     quadri.mp (codice Metapost)
     quadri.tex (sorgente LaTeX)

     Quaderno a righe
     righe.mp (codice Metapost)
     righe.tex (sorgente LaTeX)
--]]

-- run metapost (filename without extension):
os.execute("mpost righe")
os.execute("mpost quadri")

-- run pdflatex (filename without extension):
os.execute("pdflatex righe")
os.execute("pdflatex quadri")

-- remove temporary file:
os.remove("righe.log")
os.remove("quadri.log")
os.remove("righe.aux")
os.remove("quadri.aux")
os.remove("righe.mps")
os.remove("quadri.mps")

Alla prossima e Buon Anno 2011!!!

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