Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > 9441dd34b35358c518173cb439d91253 > files > 11

ispell-ro-1.0.1-4mdk.noarch.rpm

% -*-latex-*-
% 
\documentstyle[11pt,romana-]{article}

\input{pagesize}

\begin{document}

\begin{romana}
\title{``Corect'' --- un ``spell-check''-er pentru limba rom"an'a}
\author{Mihai Budiu --- mihaib@cs.cmu.edu} 
\date{16 mai 1997}

\maketitle

\begin{description}
\item[Subiect:] un corector de texte pentru limba rom"an'a
\item[Cuno'stin'te necesare:] familiaritate cu sisteme de prelucrare a
textelor
\item[Cuvinte cheie:] spell-check, emacs, ispell, standard,
inerna'tionalizare
\end{description}

\tableofcontents

\vspace{0.5cm}

Folosind programul {\tt ispell} am construit un pachet de utilitare
care u'sureaz'a scrierea 'si corectarea textelor 'in limba rom"an'a.
Pachetul este, sper, relativ u'sor de instalat 'si folosit pe
platforme Unix, 'si este disponibil oricui f'ar'a restric'tii.  

Poate fi ob'tinut prin web de la
\verb|http://www.cs.cmu.edu/~mihaib/ftp/rom-spell.taz|.  'In acest
articol discut 'in oarece detaliu despre una dintre sculele pe care
pachetul se bazeaz'a (excelentul program {\tt ispell}) 'si justific
unele dintre deciziile pe care le-am luat c'ind am construit pachetul.  
Pe alocuri divaghez despre importan'ta unui design clar separat, 'si
despre func'tia standardelor 'in ziua de azi.

\section{Programul {\tt ispell}}

{\tt ispell} este software ``free'', deci accesibil oricui.  Rolul lui
este destul de simplu: analizeaz'a texte 'si indic'a cuvintele a
c'aror grafie nu o cunoa'ste, permi't'ind 'in felul acesta corectarea
unora dintre erorile de dactilografie.  {\tt ispell} vine de la
``fabrican'ti'' cu o 'intreag'a suit'a de programe care permit
construirea, manipularea 'si 'intre'tinerea de dic'tionare.

{\tt ispell} este prin natura lui un program nu prea inteligent: are
la 'indem'in'a un dic'tionar cu {\em toate} cuvintele corecte, iar
ceea ce face este s'a caute fiecare cuv'int din textul de corectat
'in dic'tionar.  Dac'a g'ase'ste cuv'intul 'il socote'ste bun, dac'a
nu, se uit'a 'in dic'tionar dup'a cuvinte care sunt ``apropiate'' ca
scriere de cel absent, pe care apoi le propune spre 'inlocuire,
presupun'ind ca acel cuv'int a fost gre'sit scris.

Ce 'inseamn'a c'a ``dou'a cuvinte sunt aproape'' pentru {\tt ispell}?  
Un cuv'int este aproape de altul dac'a se poate ob'tine printr-una din 
urm'atoarele opera'tii:

\begin{itemize}
\item Ad'augarea unei litere;
\item 'Stergerea unei litere;
\item Transpunerea a dou'a litere consecutive.
\end{itemize}

De asemenea, {\tt ispell} poate identifica lipsa unui spa'tiu dintre
dou'a cuvinte.

De'si un astfel de program nu poate oferi nici o garan'tie 'in
producerea de texte corecte, este extrem de eficace 'in a elimina o
mare parte dintre erorile tipografice.

Chiar faptul c'a {\tt ispell} nu are nici o cuno'stin't'a despre
limb'a 'il face foarte util, pentru c'a permite folosirea lui cu texte
scrise 'in orice limb'a, cu condi'tia posed'arii unui dic'tionar
potrivit.

\section{Un principiu de Design}

Programe de genul {\tt ispell} exist'a de mult'a vreme 'in lumea Unix
(de ex. programul {\tt spell}; to spell = a scrie liter'a cu liter'a).
Ceea ce face {\tt ispell} atr'ag'ator este universalitatea lui.
{\tt ispell} este un exemplu tipic de program care
'incarneaz'a un foarte important principiu de proiectare 'in
calculatoare.  Acest principiu se manifest'a 'in separarea dintre {\em
mecanism} 'si {\em politic'a} (policy/mechanism).  Principiul indic'a
faptul c'a un aparat trebuie s'a fie c'it mai universal, ca s'a nu
oblige pe cel care 'il folose'ste la anumite feluri de manipulare,
care s'a 'ii reduc'a utilitatea.

Tehnica este extrem de important'a 'in proiectarea sistemelor de
operare, 'si 'in general a programelor care servesc drept unelte\footnote{
Prin antitez'a cu programele care fac ceva util ele 'insele: aplica'tiile.}
(de exemplu bibliotecile).  Un sistem de operare trebuie de exemplu
s'a-'ti ofere toate metodele prin care s'a po'ti controla {\em c'ind}
se vor executa programele tale, dar s'a nu impun'a o anumit'a ordine
de execu'tie a lor.  Sistemul de operare este cel care execut'a
programele, dar utilizatorul este cel care indic'a ordinea 'si
priorit'a'tile.

Un alt exemplu interesant este 'in re'telele de calculatoare: protocoalele
de transmisiune a datelor 'stiu s'a mute bi'ti de la un calculator la
altul, chiar foarte 'indep'artat.  'In acest caz mecanismul este cel
care transport'a datele.  Politica de alegere a traseului pe care le
urmeaz'a datele este 'ins'a complet separat'a de mecanismul de transport;
ea este decis'a de un set complet separat de protocoale, numite 
protocoale de rutare.  Aceast'a flexibilitate permite construirea de
protocoale de rutare noi 'si 'inlocuirea celor vechi ``din mers'',
f'ar'a a 'intrerupe func'tionarea re'telei 'in vreun fel.

Pe scurt: dac'a faci un aparat complicat, nu restr'inge modul 'in care
poate fi folosit, ci construie'ste-i suficiente m'inere c'it s'a
poat'a fi controlat 'in c'it mai multe feluri.

\section{Pachetul pentru limba rom"an'a}

Unde trebuie puse m'inerele nu este 'intotdeauna evident.
Proiectantul variantei interna'tionale a lui {\tt ispell}, Geoff
Kuenning, a studiat cu aten'tie locurile 'in care politica era
'ingropat'a 'in interiorul programului, 'si a 'incercat s'a o extrag'a
'in afar'a.  Acest lucru este vizibil utilizatorului prin faptul c'a
pentru a folosi {\tt ispell} trebuie s'a scrii o gr'amad'a de fi'siere
auxiliare, care controleaz'a modul 'in care lucreaz'a.  Ceea ce am
'si f'acut, pentru a putea face {\tt ispell} utilizat cu texte
rom"ane'sti.

'In cele ce urmeaz'a voi descrie pe scurt con'tinutul pachetului;
aceast'a descriere 'imi va prilejui identificarea por'tiunilor din
{\tt ispell} care sunt supuse controlului utilizatorului.

\subsection{Fi'sierele de prefixe/sufixe}

Principala pies'a din configurarea {\tt ispell} este fi'sierul de
afixe.  Numele nu este foarte fericit ales, pentru c'a func'tiunea
acestuia este, pe l'ing'a de a indica metode de derivare cu prefixe
'si sufixe (care pot fi folosite pentru a comprima dic'tionarele), 'si
descrierea parametrilor func'tion'arii lui {\tt ispell}.

O prim'a alegere cu care m-am confruntat a fost dac'a dic'tionarele
vor con'tine semne diacritice sau nu.  Pentru c'a nu m-am putut
hot'ar'i, p'in'a la urm'a am construit dou'a configura'tii 'si dou'a
dic'tionare, pentru ambele cazuri.

Pentru cazul semnelor diacritice a trebuit s'a fac fa't'a
urm'atoarelor dou'a decizii:

\begin{itemize}
\item Dac'a folosesc sau nu noile reguli de scriere ale Academiei cu
"a;  rezultatul 'il ghici'ti din textul de fa't'a, care este corectat
cu {\tt ispell};

\item Cum voi reprezenta semnele diacritice.  Aceast'a problem'a este
extrem de spinoas'a, 'si 'imi va da prilejul s'a fac o lung'a digresiune:
\end{itemize}

\subsection{Problema interna'tionaliz'arii}

Calculatoarele depind 'intr-o sumedenie de moduri subtile de faptul
c'a au fost concepute de oameni care foloseau mai ales limba englez'a
(orice istorie a calculatoarelor va recunoa'ste rolul americanilor
'si, ceva mai pu'tin, al englezilor).  Modul 'in care sunt prelucrate
textele, 'in care sunt afi'sate 'si citite este adesea str'ins legat
de caracteristicile speciale ale limbii engleze.  De acest lucru
'si-au dat seama cei care au 'incercat s'a universalizeze folosirea
calculatoarelor, pentru a le adapta 'si altor na'tii.

F'ar'a a avea preten'tia de a trata exhaustiv aceast'a problem'a, s'a
arunc'am o privire asupra influen'tei limbii asupra programelor.

\subsubsection{Traseul informa'tiei}

Pentru a prelucra texte avem trei categorii mari de opera'tii:

\begin{itemize}
\item Citirea textelor de la tastatur'a;
\item Prelucrarea textelor prin feluri'ti algoritmi;
\item Afi'sarea (vizualizarea) textelor.
\end{itemize}

Pentru fiecare din aceste activit'a'ti este responsabil un program
distinct.  De citirea tastaturii se ocup'a ``driver''-ul de terminal.
Acesta are de obicei mai multe func'tiuni:

\begin{itemize}
\item Deduce combina'tia de taste ap'asat'a; o reprezint'a printr-un
'sir de coduri;
\item Traduce codurile la o reprezentare ``standard''; de exemplu
c'ind ape'si tasta pe care scrie ``A'' returneaz'a codul ASCII al lui
``a'', care e 97.
\item C'iteodat'a face o minim'a editare a textului: de exemplu dac'a
ape'si pe DELETE 'sterge un caracter.
\end{itemize}

'In func'tie de sistemul de operare, utilizatorul are mai multe
op'tiuni la-ndem'in'a pentru a influen'ta driverul: poate s'a
citeasc'a direct codurile, s'a influen'teze modul 'in care se face
traducerea, s'a evite editarea automat'a textului.

Dac'a lucrezi pe un calculator la distan't'a, de exemplu conectat prin
{\tt telnet} prin re'tea, lucrurile se complic'a, pentru c'a 'intre driver-ul 
care cite'ste tastatura (aflat pe calculatorul local) 'si aplica'tia ta
(aflat'a la distan't'a) se mai interpun 'inc'a dou'a programe care
codific'a fiecare tast'a ap'asat'a:

\begin{itemize}
\item Programul local de {\tt telnet}, cite'ste tastele de la driver 'si le
traduce 'intr-un mod standardizat pentru comunica'tia prin re'tea;
\item Programul de la distan't'a, demonul {\tt telnetd}, care prime'ste de 
la {\tt telnet} codurile standard ale tastelor 'si le traduce pentru ma'sina 
de acolo.
\end{itemize}

Afi'sarea textelor este iar'a'si de obicei sarcina unui ``driver''.
Dac'a avem de-a face cu un terminal alfa-numeric (sau o fereastr'a
care emuleaz'a un astfel de terminal prin software), atunci de obicei
driver-ului i se dau secven'te de caractere ASCII, pe care 'stie el
cum s'a le afi'seze; din c'ind 'in c'ind i se dau 'si coduri numite
``caractere de control'', care de obicei nu las'a urme pe ecran, ci
'ii spun terminalului {\em cum} s'a manipuleze caracterele ce urmeaz'a.  
De exemplu putem indica, folosind caractere de control, 'in
ce loc pe ecran s'a se scrie urm'atorul caracter ASCII.  Care este
secven'ta de caractere de control care spune acest lucru depinde
de terminal; fiecare fabricant a inventat propriile conven'tii.

De c'ind firma Xerox a inventat ecranul grafic (``bitmapped screen''), 
a deveni un lucru comun ca interfa'ta dintre aplica'tie 'si utilizator s'a 
nu fie un simplu 'sir de caractere pe care terminalul le afi'seaz'a, ci o
matrice mare de punctule'te care pot fi controlate individual.
Aplica'tiilor li se pune la 'indem'in'a posibilitatea de a desena
orice form'a doresc; foarte frecvent 'ins'a sistemul de operare pune
la dispozi'tie func'tii de bilbiotec'a pentru a desena caractere cu
felurite forme (``fonturi'').

'In fine, ultimul aspect al prelucr'arii de texte este procesarea lor cu
feluri'ti algoritmi: c'aut'ari, sort'ari, tehnoredactare, corectur'a, editare,
transmitere de po'st'a electronic'a, etc.  Vom reveni pe scurt asupra fazei
de prelucrare dup'a ce discut'am despre standardizare.

\subsubsection{Standardizarea}

Un element cheie 'in interac'tiunea 'intre aceste p'ar'ti (drivere,
aplica'tii, biblioteci, sistemul de operare) este faptul c'a {\em
toate folosesc aceea'si metod'a de codificare}.  C'ind ap'asa'ti tasta
``A'', driverul de tastatur'a 'intoarce 97, iar aplica'tia 'stie c'a a
primit un ``A'', pe care 'il poate da bibliotecii de afi'sare, care
'stie c'a trebuie s'a deseneze o astfel de liter'a.

Oricine a lucrat pe o tastatur'a prost configurat'a, sau a 'incercat
s'a acceseze de la distan'ta o aplica'tie care decodific'a ciudat
tastatura, sau a manipulat tabele de translatare ale codurilor, sau a
primit mail cu caractere interna'tionale va 'in'telege importan'ta
acestei conven'tii.  Literei ``A'' i se asociaz'a codul 97 de c'atre
codul ASCII (American Standard Code for Information Interchange), care
este standardizat de ANSI (American National Standard Institute); e un
fel de STAS local.  Din fericire, datorit'a domina'tiei SUA 'in arena
calculatoarelor, ASCII este practic implementat de toat'a lumea.  'Si
organiza'tia mondial'a a standardelor ISO (International Standards
Organization) a acceptat ASCII sub numele ISO 646.  Codificarea ASCII
'ins'a recomand'a numai 128 de simboluri (din care 32 nici m'acar nu
sunt vizibile, ci sunt ``caractere de control'').  De 'indat'a ce
ie'sim din perimetrul acestora, domne'ste haosul.

Pentru caractere pe 8 bi'ti exist'a standardul ISO-8859, care ofer'a o
duzin'a de interpret'ari pentru caracterele cu coduri peste 128.
Pentru limba rom"an'a cea mai interesant'a interpretare este cea dat'a
de ISO-8859-2, numit'a 'si Latin-2, care con'tine toate semnele
speciale cu diacritice rom"ane'sti.  Problema acum este 'ins'a:
'inainte de a c'adea de acord ce semn este cel cu codul 200, trebuie
s'a c'adem de acord ce cod folosim din duzina de variante ISO sau alte
variante.  Plus c'a fiecare aplica'tie trebuie s'a fie capabil'a s'a 
interpreteze toate variantele, etc.

Tentative de standardizare 'si mai 'indr'azne'te s-au f'acut: un
consor'tiu gigant, din care fac parte Microsoft, IBM, Xerox, Sun 'si
alte (zeci) de firme din lumea calculatoarelor, a fost 'infiin'tat, pe
nume Unicode.  Acesta, cu ajutorul a zeci de exper'ti lingvi'sti a
propus o standardizare uniform'a a tuturor caracterelor, din toate
limbile lumii, folosind pentru aceasta 16 bi'ti pe caracter.  Fiecare
caracter ar avea astfel o reprezentare unic'a 'si ne-ambigu'a.
Dificult'a'tile de 'infr'int sunt enorme; de exemplu trebuie cumva
luate 'in considerare standardele na'tionale (cum ar fi cel elaborat
de Japonezi) 'si reconciliate.

Din p'acate concordia nu este 'inc'a realizat'a, pentru c'a ISO a
propus 'in acela'si scop propriul ei standard, diferit de Unicode, 
pe 32 de bi'ti, numit ISO DIS 10646.

Dificultatea la ora asta este deci nu c'a nu exist'a standarde, ci c'a
exist'a prea multe.  O aplica'tie poate folosi propriile ei conven'tii
interne pentru citirea tastaturii/modificare/afi'sare, dar de 'indat'a
ce se pune problema {\em schimbului} de informa'tii, absen'ta unui
standard unic (sau a unui num'ar mic de standarde) face problema intratabil'a.

'In general, via'ta noastr'a de toate zilele depinde enorm de
standarde, 'intr-un fel pe care nici nu-l realiz'am.  Dac'a nu am avea
standarde trenurile nu ar pute circula pentru c'a ecartamentul ar fi
diferit 'in 't'ari diferite (de altfel, la ru'si chiar este mai mare),
aparatele electrice nu ar func'tiona dec'it unde au fost proiectate
('si a'sa americanii merg la 110V), ma'sinile ar trebui s'a care
benzina de acas'a ca s'a se potriveasc'a cifra octanic'a, am vedea la 
televizor numai ce ar transmite bunica, cu care folosim aceea'si codificare, 
etc, etc.

\subsubsection{Prelucr'arile pe texte}

'Inainte de a ne 'indep'arta de zona standardelor interna'tionale, s'a
mai arunc'am o privire asupra unor 'intreb'ari care sunt legate de
reprezentarea caracterelor, 'si al c'aror r'aspuns influen'teaz'a modul 
'in care algoritmii vor procesa textele:  

\begin{itemize}
\item Nu toate limbile se scriu 'in aceea'si direc'tie; ebraica se
scrie de la dreapta la st'inga, iar japoneza pe vertical'a.  C'ind am
un text englezesc cu citate din vechiul testament 'in ebraic'a, cum
reprezint textul 'in calculator, 'in ce ordine?

\item Literele se pot scrie adesea 'in felurite moduri; chiar l'as'ind
la o parte informa'tia legat'a de font, dimensiune 'si orientare.  'In
arab'a unele litere se scriu diferit 'in func'tie de vecinii lor;

\item Voi reprezenta 'a ca dou'a semne (a 'si c'aciula) --- din care
c'aciula este un semn care ``nu ocup'a spa'tiu'', deci se scrie peste
cel anterior --- sau ca o singur'a liter'a?

\item Reprezint ``A'' 'si ``a'' ca pe o aceea'si liter'a, 'intr-un caz
modificat'a (m'arit'a), sau ca pe dou'a litere deosebite?

\item 'In anumite limbi un semn se comport'a ca mai multe litere ('in
german'a \ss\ se sorteaz'a ca 'si cum s-ar scrie ``ss''), dar se scrie
ca una singur'a.  'In alte limbi e invers: 'in Spaniol'a ``ll'' este
considerat'a o singur'a liter'a la sortare.  Algoritmii de sortare
devin deci mult mai complica'ti, pentru c'a nu mai pot face simple
compara'tii liter'a cu liter'a (o simpl'a sortare lexicografic'a).

\item 'In limba chinez'a literele nu sunt ordonate alfabetic, ci dup'a
num'arul de liniu'te cu care se deseneaz'a.

\item Informa'tii ca: sf'ir'situl de paragraf, de pagin'a, indentarea,
num'arul de spa'tii albe sunt sau nu reprezentabile prin caractere
(cum sunt de exemplu 'in setul ASCII ``New-Line'' sau ``Tab'')?

\item C'ind scriu programe 'in C, cum reprezint caractere
interna'tionale pentru mesaje date utilizatorului?

\item Cum pot crea un fi'sier cu nume 'in Swahili?

\item Cum se scrie o expresie regulat'a 'in Kanji?
\end{itemize}

Oricare din aceste probleme poate fi rezolvat'a, dar p'in'a c'ind nu
toat'a lumea le va rezolva pe toate 'in acela'si fel (prin intermediul
unui standard), programele risc'a s'a manipuleze obiecte pe care nu le
mai 'in'telege nimeni 'in afar'a de autori.

Probabil c'a 'inving'ator 'in lupta standardelor va ie'si p'in'a la
urm'a Unicode, datorit'a suportului unor firme extrem de mari, 'si
datorit'a calit'a'tilor sale tehnice.  Standardul este descris 'in 8
cm\footnote{grosime.} de h'irtie la ora actual'a, 'si mai cre'ste.

Sistemul de operare Windows NT de la Microsoft este construit
integral cu Unicode 'in interior; totul, de la nume de fi'siere la
mesaje de eroare este construit pe 16 bi'ti.  Biblioteci speciale
transform'a datele manipulate de programele ``vechi'' (care lucreaz'a
cu caractere pe 8 bi'ti) 'in Unicode 'inainte de a ruga driverele din
nucleu s'a le afi'seze.  Chiar faptul ca Windows NT domin'a pia'ta
sistemelor de operare la ora actual'a este un motiv major pentru ca
Unicode s'a 'inving'a.

\subsubsection{Reprezentarea diacriticelor}

'Inchei aici digresiunea mea despre standarde 'si reprezentarea
caracterelor interna'tionale, 'si revin la pachetul meu mult mai
modest, care 'incearc'a s'a rezolve unele dintre problemele limbii
rom"ane.

Hot'ar'irea mea final'a a fost s'a reprezint absolut tot textul
folosind semne ASCII, lucru care o s'a m'a scuteasc'a de o sumedenie
de probleme de portabilitate, pentru c'a virtual toate terminalele din
lume recunosc setul de caractere ASCII.  'In schimb mi-am propus s'a
folosesc o conven'tie care s'a aib'a urm'atoarele propriet'a'ti:

\begin{itemize}
\item S'a foloseasc'a semnele ASCII 'intr-un mod ne-ambiguu (de
exemplu dac'a a's fi folosit semnul {\tt a+} pentru 'a, a's fi avut
mari dificult'a'ti 'in a distinge formulele matematice de texte cu
diacritice; conven'tia pe care am aleas-o 'in final nu e perfect 
ne-ambigu'a, dar e tolerabil de neambigu'a, cred;

\item Ca o consecin't'a a ne-ambiguit'a'tii, ar trebui s'a fie foarte
u'sor de scris un program care s'a converteasc'a un text scris cu
diacritice folosind conven'tia mea, 'in orice alt'a conven'tie de 
reprezentare.  Practic dac'a fac un {\em search-and-replace} pe un text 
pot ob'tine orice alt'a conven'tie.  Par-examplu, dac'a dvs. folosi'ti pentru 
'a semnele /a, 'si eu folosesc \{a\}, atunci 'inlocuind uniform \{a\} cu /a
convertesc un text din reprezentarea mea 'in a dumneavoastr'a.

\item Semnele pe care le folosesc s'a fie u'sor de tastat.  'In limba
rom"an'a exist'a o sumedenie de cuvinte cu semne diacritice, deci
m'ina mea va trebui s'a nu se deplaseze prea mult pe tastatur'a pentru a
scrie semnele 'inso'titoare; de preferabil s'a nu folosesc SHIFT sau
ceva 'inrudit.

\item Metoda s'a se 'impace bine cu alte programe care manipuleaz'a
texte.  De exemplu eu scriu texte folosind editorul Emacs (vede'ti 'si
articolul meu din PC-Report pe Mai 1997, aflat 'si la
\verb|http://www.cs.cmu.edu/~mihaib/articles|), iar 'in Emacs tasta
{\tt M-f} se deplaseaz'a peste un cuv'int.  A's fi vrut ca semnele
diacritice pe care le folosesc s'a nu fie considerate de Emacs ca
fiind 'inafara cuvintelor.
\end{itemize}

P'in'a la urm'a alegerea s-a oprit asupra semnului apostrof: ' .  De
aceea voi scrie acum literele astfel:\end{romana} \verb|'a 'i 's 't|
\begin{romana} pentru 'a, 'i, 's, 't.

Probabil c'a alegerea pentru "a a fost mai pu'tin fericit'a: am ales
\end{romana}\verb|"a|\begin{romana}.

Dar s'a revenim la fi'sierele de configurare pentru {\tt
ispell}\footnote{Ca dovad'a c'a principiile enumerate mai sus au fost bune,
ini'tial alesem semnul $\backslash$ pentru diacritic; schimbarea la
apostrof a fost 'ins'a foarte simpl'a, 'si a fost cauzat'a de dorin'ta
de a inter-opera cu \LaTeX pentru care semnul $\backslash$ are o semnifica'tie
special'a.}.

Odat'a ce am hot'ar'it ce litere voi folosi, am purces la a scrie un
fi'sier de configurare pentru {\tt ispell}.  Formatul fi'sierului este
documentat 'in paginile de manual ale programului {\tt ispell}.  Acesta este
con'tinutul fi'sierului {\tt rom.signs.aff}: fi'sierul de afixe pentru
limba rom"an'a cu semne diacritice (cel pentru configura'tia f'ar'a 
diacritice este mai simplu).
\end{romana}

\begin{verbatim}
nroffchars    ().\\*
texchars      ()\[]{}<\>\\$*.%
stringchar    "'a" "'A"
stringchar    "'i" "'I"
stringchar    "'s" "'S"
stringchar    "'t" "'T"
stringchar    "\"a" "\"A"
wordchars     [a-z] [A-Z]
\end{verbatim}

\begin{romana}
Folosind un limbaj foarte simplu 'ii descriu lui {\tt ispell} care
caractere au semne speciale 'in fi'sierele scrise pentru {\tt nroff}
'si \TeX\ (acestea sunt dou'a programe foarte r'asp'indite 'in
lumea Unix pentru tehnoredactarea de texte, care au folosesc ni'ste
limbaje speciale pentru a descrie aranjarea 'in pagin'a a textului.
Practic eu trebuie s'a 'ii spun lui {\tt ispell} c'a atunci c'ind
manipulez un text scris pentru {\tt nroff}, respectiv \TeX, trebuie
s'a ignore cuvintele care descriu aranjarea 'in pagin'a, 'si s'a
corecteze numai restul textului.)

Apoi 'ii indic lui {\tt ispell} c'a voi interpreta perechile de semne
apostrof-a, apostrof-A, etc. drept o singur'a liter'a 'in textele
mele.  Asta este foarte important pentru c'a 'ii spune lui {\tt
ispell} c'a ``f'i's'' este ob'tinut din ``f's'i'' prin schimbarea a
dou'a litere (deci este ``aproape''), 'si nu prin permutarea unui 'sir 
de 4 caractere (cuvintele se vor scrie cu conven'tia mea astfel:
\end{romana}\verb|f'i's    f's'i|).

\begin{romana}
'In fine, indic faptul c'a semnele ASCII obi'snuite pentru litere sunt
componente ale cuvintelor.  {\tt ispell} permite reguli 'si mai
rafinate, pentru a indica de pild'a c'a anumite caractere sunt
considerate litere numai dac'a apar 'in interiorul unui cuv'int (cum
ar fi de pild'a liniu'ta de unire --), sau pentru a indica faptul c'a
{\tt nroff} sau \TeX\ denot'a altfel un acela'si caracter.

Observa'ti c'it de flexibil este {\tt ispell}: comportarea programului
este influen'tat'a de o gr'amad'a de parametri dinafar'a, din fi'sierul
de configurare.  Aceasta este separarea de politic'a 'si mecanism de
care vorbeam, care 'ii permite lui {\tt ispell} s'a fie simultan
folosit 'in condi'tii at'it de diferite.

\subsection{Dic'tionarele}

A doua problem'a spinoas'a era: de unde dic'tionare?  La aceast'a
'intrebare am r'aspuns imediat.  

\subsubsection{Achizi'tia de date}

{\tt ispell} este un program interactiv, care este suficient de
'in'telept s'a fie de acord c'a nu 'stie totul.  De fiecare dat'a
c'ind {\tt ispell} g'ase'ste un cuv'int necunoscut, pe l'ing'a faptul
c'a 'imi ofer'a o list'a de posibile corecturi, 'imi ofer'a
posibilitatea de a introduce cuv'intul 'in dic'tionar.  Exact pe asta
m-am bazat 'si eu: voi construi dic'tionarul incremental, rul'ind 
{\tt ispell} pe texte (c'it se poate de) corecte.  Dup'a o faz'a 
plictisitoare 'in care m'a va 'intreba mai toate cuvintele, va 'inv'a'ta 
vocabularul meu de baz'a 'si va deveni eficace.

Construc'tia dic'tionarelor este 'in plin'a desf'a'surare, de'si
ambele (cel cu diacritice 'si cel f'ar'a) au c'ite 40 de mii de
cuvinte la ora actual'a.  Principala mea surs'a de vocabular este
edi'tia pe Internet a ziarelor ``Rom"ania Literar'a'' 'si ``Dilema'',
plus, mai pu'tin, textele pe care le scriu eu 'insumi.

\subsubsection{Analiza statistic'a}

Dup'a ce am str'ins c'iteva mii de cuvinte, am folosit celelalte
programe din pachetul cu care vine {\tt ispell} pentru a face o
analiz'a statistic'a a dic'tionarelor.  Analiza este util'a pentru c'a
'in fi'sierele de configurare 'ii pot descrie lui {\tt ispell} simple
reguli de derivare cu prefixe 'si sufixe, pe care apoi el le
folose'ste pentru a reduce m'arimea dic'tionarelor, memor'ind o
singur'a dat'a r'ad'acinile comune.  Pachetul care con'tine programul {\tt
ispell} ofer'a pentru acest scop programele {\tt findaffix}, care
analizeaz'a exhaustiv un dic'tionar, gener'ind informa'tii despre
poten'tialele deriv'ari, 'si {\tt tryaffix}, care evalueaz'a economia
care se poate ob'tine folosind un anumit affix.

\subsubsection{Compresia prin prefixe 'si sufixe}

Cum se folosesc afixele pentru a reduce m'arimea dic'tionarului?
Pentru fiecare afix se define'ste (manual) c'ite o prescurtare de o
liter'a.  De exemplu, pentru prefixul ``re-'' am alocat litera E.
Atunci, 'in loc ca 'in dic'tionar s'a apar'a cuvintele ``educare'' 'si
``reeducare, va ap'area doar o 'inregistrare de forma ``educare/E''.
Practic am 'inlocuit un cuv'int 'intreg cu dou'a litere (/ 'si E).

Pachetul {\tt ispell} vine 'impreun'a cu un alt program numit {\tt
munchlist}, care, d'indu-i-se un dic'tionar 'si o list'a de afixe,
comprim'a dic'tionarul la o reprezentare minim'a.  Rezultatul este
foarte eficace; chiar cu fi'sierele relativ primitive de afixe pe care
le-am f'acut am reu'sit s'a reduc m'arimea dic'tionarelor la
aproximativ 50-55\%.

Restul fi'sierelor de configurare a afixelor este ocupat cu regulile
prin care afixele se ata'seaz'a cuvintelor.  {\tt ispell} 'stie s'a
opereze mici modific'ari asupra r'ad'acinilor; asta cre'ste enorm
utilitatea afixelor.  Iat'a un fragment tipic dintr-o descriere a unui
``flag'' din {\tt rom.signs.aff}:
\end{romana}

\begin{verbatim}
suffixes

flag *I:
    U           >       LUI             # bou  > boului
    [^UA]       >       ULUI            # porc > porcului
    [GC] A      >       -A,II           # vaca > vacii
    [^CG] A     >       -A,EI           # baba > babei
\end{verbatim}
\begin{romana}

Traducere: indicatorul I va func'tiona 'in 4 feluri, depinz'ind de forma
r'ad'acinii cuv'intului la care se aplic'a:

\begin{enumerate}
\item Dac'a r'ad'acina se termin'a 'in ``U'', atunci indicatorul I va
cauza concatenarea 'sirului ``lui''.  De exemplu, 'in dic'tionar
cuv'intul ``bou/I'' va genera simultan ``bou'' 'si ``boului'';

\item Dac'a r'ad'acina {\em nu} (nega'tia este indicat'a de semnul 
\verb|^|) se termin'a 'in ``U'' sau ``A'', atunci adaug 'sirul ``ului'';

\item Dac'a r'ad'acina se termin'a 'in ``ga'' sau ``ca'', atunci
regula va 'sterge ``A''-ul de la coad'a 'si va concatena un ``ii'';

\item 'In fine, dac'a r'ad'acina se termin'a 'in ``a'', dar nu 'in 
``ca'' sau ``ga'', atunci 'sterg ``A''-ul 'si adaug ``ei''.
\end{enumerate}

Observa'ti c'a aceste reguli nu sunt folosite pentru a {\em genera}
noi cuvinte din cele existente, ci doar pentru a comprima un set de
cuvinte dat, deci nu pot gre'si dac'a avem de-a face cu o excep'tie
(de exemplu cuv'intul ``poarta'', care dup'a regulile de mai sus ar
deveni ``poartei'').  Singura consecin't'a este c'a ambele cuvinte 
vor ap'area 'in dic'tionar, pentru c'a nu se poate aplica compresia 
(voi avea 'si ``poarta'' 'si ``por'tii'' 'in dic'tionar).

\subsection{Interfa'ta cu emacs}

{\tt ispell} este prin construc'tie un program interactiv: analizeaz'a
textul, 'si la prima eroare scrie pe ecran por'tiunea de text
suspicioas'a, indic'ind posibile corecturi, 'si a'stept'ind ca
utilizatorul s'a ia m'asuri.

Dl. Kuenning 'ins'a a fost suficient de 'in'telept pentru a 'inzestra
{\tt ispell} cu un mod de func'tionare ``batch'': ne-interactiv.
Dac'a {\tt ispell} este pornit cu modificatorul {\tt -a} atunci nu mai
scrie nimic pe ecran 'si nu mai cite'ste tastatura, ci scrie 'si
cite'ste de la intrarea 'si ie'sirea sa standard.  Practic de la
intrare {\tt ispell} cite'ste un cuv'int, iar la ie'sire trimite
'siruri de caractere care descriu p'arerea lui despre acel cuv'int (dac'a
e corect, dac'a nu ce variante sunt, etc).  De exemplu, (de data asta
'in englez'a):

\begin{verbatim}
$ echo helo | ispell -a 
@(#) International Ispell Version 3.1.20 10/10/95
& helo 9 0: halo, held, hell, hello, helm, help, hero, he lo, he-lo
$
\end{verbatim}

Conven'tiile prin care {\tt ispell} r'aspunde sunt u'sor complicate;
pe scurt, 'in linia de mai sus a spus c'a nu crede c'a acel cuv'int e
corect, (prin semnul \&), 'si a indicat apoi 9 posibilit'a'ti corecte,
separate prin virgule.

Aceasta este o alt'a instan't'a a faimoasei separa'tii dintre
politic'a 'si mecanism: mecanismul de corectare nu implementeaz'a 'si
politica de interac'tiune.

Asta permite interfa'tarea altor programe cu {\tt ispell}.  De exemplu
editorul de texte Emacs 'stie s'a converseze cu {\tt ispell},
bag'indu-i pe g'it (intrarea standard) cuvintele dintr-un buffer unul
c'ite unul. 'In func'tie de r'aspuns discut'a el 'insu'si cu utilizatorul,
pentru a 'inlocui cuvintele gre'site.

\subsection{Fi'sierul de stil pentru \LaTeX}

Pentru c'a 'imi tehnoredactez fi'sierele 'in \LaTeX, era natural s'a
caut o metod'a de a folosi conven'tia de scriere cu apostroafe direct
'in \LaTeX.  Nu a fost prea dificil, pentru c'a am dat peste un
fi'sier de stil construit de Alexandru 'si Dan Corlan pe care mi l-am
'insu'sit, 'si 'in care am operat ni'ste minuscule
modific'ari.  Fi'sierul pune la-ndem'in'a un nou ``environment'', numit
{\tt romana}, 'in interiorul c'aruia semnul apostrof 'si respectiv
ghilimelele produc diacritice.  Practic pot scrie acum texte astfel:
\end{romana}

\begin{figure}[h]
\begin{center}
\begin{tabular}{p{6.3cm}|p{2cm}|p{6.3cm}}
\begin{minipage}{6.1cm}
\begin{verbatim}
\documentstyle[romana-]{article}
\begin{document}
'In aceast'a parte apostroful
nu are nici o influen't'a.
\begin{romana}
Dar 'in aceast'a parte se 
transform'a 'in diacritice.
\end{romana}
\end{document}
\end{verbatim}
\end{minipage}
& 
\begin{romana}
'si voi genera urm'atorul document:
\end{romana}
&
\begin{minipage}{6.1cm}
'In aceast'a parte apostroful nu are nici o influen't'a.
\begin{romana}
Dar 'in aceast'a parte se transform'a 'in diacritice.
\end{romana}
\end{minipage}
\end{tabular}
\end{center}
\end{figure}

\begin{romana}
Fi'sierul de stil ar putea beneficia de mici 'imbun'at'a'tiri, pentru
c'a anumite combina'tii se comport'a ciudat (de exemplu nu se mai pot
scrie acolade dup'a ghilimele), dar este mai adesea util dec'it
d'aun'ator.

\subsection{Interfa'ta corectorului de limba rom"an'a cu utilizatorul}

\subsubsection{Instalare}

Pentru a putea folosi {\tt corect}, trebuie 'int'ii sa ave'ti pachetul
cu {\tt ispell}.  Necesare sunt fi'sierele {\tt buildhash} 'si {\tt
ispell}; de celelalte v'a pute'ti lipsi.  Dac'a ave'ti un sistem Unix,
le pute'ti lua de la {\tt ftp://prep.ai.mit.edu/pub/gnu}.

Pagina lui {\tt ispell} este la {\tt
http://fmg-www.cs.ucla.edu/fmg-members/geoff/ispell.html}; acolo mai
pute'ti afla o gr'amad'a de lucruri utile despre acest program.

Cel care instaleaz'a pachetul de fi'siere are o misiune relativ
simpl'a: trebuie s'a decid'a locul unde fi'sierele se vor plasa 'si
cum ajung utilizatorii la ele.  Exist'a dou'a variante de baz'a:

\begin{enumerate}
\item Instalarea este f'acut'a pentru 'intregul sistem (de
administrator, 'in a'sa fel 'inc'it to'ti utilizatorii s'a poat'a
beneficia);
\item Un utilizator f'ar'a privilegii 'i'si instaleaz'a pachetul
pentru uzul personal 'in contul lui.
\end{enumerate}

Cel care instaleaz'a va trebui s'a citeasc'a {\tt Makefile}-ul 'si s'a
modifice c'iteva variabile.  Valorile care ar fi interesante sunt {\tt
ROMSPELLBASE} 'si {\tt LATEXDIR}, 'si indic'a unde se vor plasa
dic'tionarele, respectiv fi'sierul de stil pentru \LaTeX.

Pentru ca utilizatorii s'a poat'a accesa fi'sierul de stil, el trebuie
s'a fie 'intr-un loc 'in care \LaTeX s'a-l poat'a c'auta.
Administratorul 'il poate pune acolo unde sistemul local are toate
celelalte fi'siere de stil.  Un utilizator obi'snuit 'il poate pune
oriunde, 'si apoi poate indica lui \LaTeX acel loc folosind variabila
{\tt TEXINPUT}.  De exemplu, eu mi-am pus fi'sierul {\tt romana-.sty}
'in {\tt \$HOME/data/tex} 'si am pus variabila astfel: \end{romana}

\begin{verbatim}
export TEXINPUTS=".:$HOME/data/tex:"
\end{verbatim}

\begin{romana}
'In plus, pentru ca Emacs s'a poat'a invoca {\tt ispell} pentru a
corecta texte rom"ane'sti, fi'sierul {\tt for-emacs}, care este
generat automat, ar trebui executat de Emacs-ul tuturor utilizatorilor
care scriu 'in rom"an'a.  Iar'a'si, exist'a dou'a variante: fiecare
utilizator poate concatena acest fi'sier la propriul fi'sier de
ini'tializare {\tt .emacs}, sau acest fi'sier poate fi pus de
administrator 'intr-un fi'sier global de ini'tializare al lui Emacs
(de exemplu {\tt site-start.el}).

\subsubsection{Utilizare}

Dup'a ce administratorul a f'acut treburile murdare de instalare,
folosirea corectorului ar trebui s'a fie banal'a.  Datorit'a unui mic
script, tot ce trebuie f'acut pentru a corecta un text este de a tasta:

\begin{verbatim}
corect fisier-de-corectat
\end{verbatim}

Simplu ca bun'a ziua!

(Dac'a fi'sierul este scris 'in rom"an'a cu diacritice, tasta'ti {\tt
corect -s fisier}.)

Pentru a corecta din Emacs folosi'ti comenzile Emacs:

\begin{verbatim}
M-x ispell-change-dictionary
\end{verbatim}

La 'intrebarea care urmeaz'a, r'aspunde'ti {\tt romana}, respectiv {\tt
rom-diacritice}, dup'a cum dori'ti.  Apoi tasta'ti:

\begin{verbatim}
M-x ispell-buffer
\end{verbatim}

\end{romana}
\end{document}