Dansk Sprognævns Retskrivningsordbog i Linux = ro

1. Oversæt C-programmet, f.eks. med kommandoen:
gcc -Wall -O2 -o ro ro.c
2. Flyt det eksekverbare program (»ro«) et passende sted hen, f.eks.:
mv ro /usr/local/bin
3. Flyt manualsiden et passende sted hen, f.eks.:
mv ro.1 /usr/local/man/man1/
4. Læs manualsiden:
man ro

Filerne er her:

—————————————————————————
ro.c
—————————————————————————

/*
* Copyright (C) 2001 Byrial Ole Jensen <byrial@image.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place – Suite 330, Boston, MA 02111, USA.
*/

#define DEFAULT_RODIR “/mnt/cdrom”
#define ROALL_FWD “roall.fwd”
#define ROFLAT_FWD “roflat.fwd”

#define VERSION “ro 0.93 (2001-02-18)”

/*
* HISTORIE
*
* ro 0.91 (2000-03-29)
*
* ro 0.92 (2001-02-17)
* – Rettet en fejl som i visse tilfælde betød at en forkert del
* af en ordbogsartikel blev fremhævet som værende opslagsordet.
*
* ro 0.93 (2001-02-18)
* – Rettet en fejl i ord_fundet(). “tur-retur” kunne ikke findes
* fordi artiklen som den eneste ikke er afsluttet med punktum.
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
#include <locale.h>
#include <ctype.h>

enum tilvalg
{
DEFAULT, JA, NEJ
};

#define FED “\x1B[1m”
#define ALM “\x1B[0m”

#define MAX_ORD_STR 128
#define MAX_ART_STR 2048

static char ord[MAX_ORD_STR]; /* Opslagsord fra roall.fwd */
static char artikel[MAX_ART_STR]; /* Artikel fra roflat.fwd */
static int klasse = 0; /* Udskriv ordklasse? */
static int nr = 0; /* Udskriv ordnummer? */
static int opslag = 0; /* Udskriv kun opslagsordet */
static enum tilvalg fed = DEFAULT; /* Fremhæv opslagsordet */

static void udskriv_artikel (void);
static int ord_fundet (const char *artikelord, const char *oplsagsord);

int main (int argc, char *argv[])
{
int i;
int cflags = REG_NOSUB;
const char *regex;
regex_t preg;
FILE *all;
FILE *flat;

int hit = 0;
const char *rodir;
enum tilvalg extended = DEFAULT;

if ((rodir = getenv (“RODIR”)) == NULL)
rodir = DEFAULT_RODIR;

setlocale (LC_CTYPE, “”);

while (((i = getopt (argc, argv, “eEfFiknov”)) != EOF))
{
switch (i)
{
case ‘e’:
extended = JA;
break;
case ‘E’:
extended = NEJ;
break;

case ‘f’:
fed = JA;
break;
case ‘F’:
fed = NEJ;
break;

case ‘i’:
cflags |= REG_ICASE;
break;

case ‘k’:
klasse = 1;
break;

case ‘n’:
nr = 1;
break;

case ‘o’:
opslag = 1;
break;

case ‘v’:
puts (VERSION “\n”
“Copyright (C) Byrial Ole Jensen <byrial@image.dk>\n”
“Programmet er frit – alle må distribuere og ændre det\n”
“i henhold til betingelserne i »GNU General Public License«.”);
return 0;

case ‘?’:
/* ignorer ukendt tilvalg */
break;
}
}

if (optind + 1 < argc)
{
fprintf (stderr, “For mange kommandolinjeargumenter\n”
“\n”
“Brug: %s [-eEfFiknov] opslag\n”, argv[0]);
return 1;
}

if (fed == DEFAULT)
fed = isatty (STDOUT_FILENO) ? JA : NEJ;

regex = (optind == argc) ? “.” : argv[optind];

if (extended == JA ||
(extended == DEFAULT && strpbrk (regex, “?+{|(“)))
cflags |= REG_EXTENDED;

if (regcomp (&preg, regex, cflags))
{
fprintf (stderr, “Fejl i det regulære udtryk\n”);
return 1;
}

if (chdir (rodir))
{
fprintf (stderr, “Kan ikke gå til kataloget %s\n”, rodir);
return 1;
}
if ((all = fopen (ROALL_FWD, “r”)) == NULL)
{
fprintf (stderr, “Kan ikke åbne filen ” ROALL_FWD “\n”);
return 1;
}
if ((flat = fopen (ROFLAT_FWD, “r”)) == NULL)
{
fprintf (stderr, “Kan ikke åbne filen ” ROFLAT_FWD “\n”);
return 1;
}

while (1)
{
int i;
char *c;

c = ord;
while ((i = getc (all)))
{
if (i == EOF)
goto slutaf;

if (i >= 0x80 && c – ord >= 6)
{
switch (i)
{
case 0x91: i = ‘æ’; break;
case 0x9b: i = ‘ø’; break;
case 0x86: i = ‘å’; break;
case 0x92: i = ‘Æ’; break;
case 0x9d: i = ‘Ø’; break;
case 0x8f: i = ‘Å’; break;
case 0x82: i = ‘é’; break;
case 0x81: i = ‘ü’; break;

default:
ord[5] = 0;
fprintf (stderr, “Fejl: Ukendt tegn i opslagsord nr. %s: %c (%d)\n”,
ord, *c, (unsigned char) *c);
return 1;
}
}

*c++ = i;
}
*c = 0;

c = artikel;
while ((*c++ = getc (flat)))
;

/* de 6 første tegn bruges til nr. og type */
if (regexec (&preg, ord + 6, 0, 0, 0) == 0)
{
hit++;
udskriv_artikel ();
}
}

slutaf:
printf (“\nI alt %d hit\n”, hit);
return 0;
}

static void udskriv_artikel ()
{
char *c;

for (c = artikel + 6; *c ; c++)
{
if ((unsigned char) *c >= 0x80)
{
switch (*c)
{
case (char) 0x91: *c = ‘æ’; break;
case (char) 0x9b: *c = ‘ø’; break;
case (char) 0x86: *c = ‘å’; break;
case (char) 0x92: *c = ‘Æ’; break;
case (char) 0x9d: *c = ‘Ø’; break;
case (char) 0x8f: *c = ‘Å’; break;
case (char) 0x82: *c = ‘é’; break;
case (char) 0x81: *c = ‘ü’; break;

case (char) 0xaa: *c = ‘\xa0’; break; /* no break space */
case (char) 0xf5: *c = ‘§’; break;
case (char) 0xa9: *c = ‘\xae’; break; /* reg. varemærke (R) */
case (char) 0xa2: *c = ‘ó’; break;
case (char) 0xf8: *c = ‘°’; break;
case (char) 0xa1: *c = ‘í’; break;
case (char) 0x94: *c = ‘ö’; break;
case (char) 0xbf: *c = ‘.’; break; /* Kan ikke vise promilletegn */

default:
fprintf (stderr, “Fejl: Ukendt tegn i artikel om %s: %c (%d)\n”,
ord, *c, (unsigned char) *c);
exit (1);
}
}
}

if (nr)
printf (“%.5s “, artikel);
if (klasse)
printf (“%c%c “, artikel[5] & 0x7F, artikel[5] & 0x80 ? ‘+’ : ‘ ‘);
if (opslag)
{
if (fed == JA)
printf (FED “%s” ALM “\n”, ord + 6);
else
puts (ord + 6);
}
else
{
if (fed == JA)
{
/* Find opslagsordet i artiklen:
*
* Det vil være i starten, eller hvis samme artikel bruges til
* flere opslagsord, kan det stå længere inde efter et ” el. “.
* Desuden kan der uanset placeringen være et foranstillet tal,
* og en ‘|’ inde i ordet.
*
* En staveform kan godt være begyndelsen af en længere alternativ
* form (f.eks agar el. agar-agar), her vil den korte form altid stå
* forrest pga. alfabetiseringen.
*
* Men en staveform kan også være begyndelsen af en bøjningsform af
* et andet ord som alfabetiseres før det aktuelle ord. Det skal man
* være opmærksom på når man f.eks leder efter opslagsordet “vable” i
* denne artikel: “vabel, vab(e)len, vabler el. vable -n, -r.”
* Version 0.91 fandt ikke den rigtige placering her, så vi prøver en
* ny algoritme:
*
* 1) Peg på første ord i artiklen.
*
* 2) Sammenlign opslagsordet med det udpegede ord i artiklen
* (ignorer | og foranstillede tal).
*
* 3) Er de ens, er det rigtige ord fundet, ellers peg på det
* førstkommende ord efter en forekomst af ” el. ” og gå til
* punkt 2).
*/
char *udpeget_ord = artikel + 6;
int fundet;

while (1)
{
if (isdigit (udpeget_ord[0]) &&
udpeget_ord[1] == ‘.’ &&
udpeget_ord[2] == ‘ ‘)
udpeget_ord += 3;
fundet = ord_fundet (udpeget_ord, ord + 6);
if (fundet)
break;

udpeget_ord = strstr (udpeget_ord, ” el. “);
if (udpeget_ord)
udpeget_ord += 5;
else
break;
}

if (!fundet)
{
/* Det hænder at opslagsordet ikke findes i artiklen fordi
* ord som “afrikaaner” også kan slås op med den ukorrekte
* stavemåde “afrikåner”.
*/
puts (artikel + 6);
}
else
{
char *c;
size_t i;

/* Udskriv den del af artiklen som kommer før opslagsordet */
for (c = artikel + 6 ; c < udpeget_ord ; c++)
putchar (*c);

/* Udskriv opslafsordet i fed skrift */
fputs (FED, stdout);
for (i = strlen (ord + 6); i ; i–)
{
if (*c == ‘|’)
{
fputs (ALM “|” FED, stdout);
c++;
}
putchar (*c++);
}
fputs (ALM, stdout);

/* Udskriv den sidste del af artiklen */
puts (c);
}
}
else
puts (artikel + 6);
}
}

/*
* Undersøger om et givet ord fra en ordbogsartikel er lig med
* opslagordet.
*/
static int ord_fundet (const char *artikelord, const char *opslagsord)
{
do
{
if (*opslagsord == 0)
return 1;
if (*artikelord == ‘|’)
artikelord ++;
} while (*artikelord ++ == *opslagsord ++);
return 0;
}

—————————————————–
ro.1 <- ro manual
—————————————————–

.TH ro 1 “Marts 2000” Unix Brugermanualer

.SH NAVN
ro \- Slå ord op i Retskrivningordbogen

.SH SYNOPSIS
.B ro [-eEfFiknov] [
.I reg-udtryk
.B ]

.SH BESKRIVELSE
.B ro
slår op i Retskrivningordbogen og udskriver de artikler hvis
opslagsord matcher det angivne regulære udtryk. Er der ikke angivet
noget regulært udtryk udskrives hele ordbogen.

.SH TILVALG
.IP -e
Fortolker det regulære udtryk som et »Extended Regular Expression«.
Det er forhåndsindstillingen hvis nogen af tegnene »?+{|(« forekommer i
udtrykket.

.IP -E
Fortolker det regulære udtryk som et »Basic Regular Expression«.
Det er forhåndsindstillingen hvis ingen af tegnene »?+{|(« forekommer i
udtrykket.

.IP -f
Udskriver opslagsordet med fed skrift.
Det er forhåndsindstillingen hvis der udskrives til en terminal.

.IP -F
Udskriver ingen koder til ændring af skrifttypen (ingen fed skrift).
Det er forhåndsindstillingen hvis der ikke udskrives til en terminal.

.IP -i
Undlader at skelne mellem store og små bogstaver.

.IP -k
Vil udskrive den ordklassekode som findes ved hver opslagsord i
Retskrivningsordbogen. Koderne består af bogstaverne fra A – Z og
tallene fra 1 – 8. Efter koden udskrives et plus (+) hvis der er flere
alternativer stavemåder for opslagsordet. Koderne er forklaret i et
senere afsnit.

.IP -n
Vil udskrive et løbenummer for hvert opslagsord. Nummerne går fra 00001
til 63981.

.IP -o
Vil kun udskrive selve de fundne opslagsord i stedet hele
ordbogsartiklen for ordene.

.IP -v
Udskriver programmets versionsnummer, dato og en notits om ophavsret, og
afslutter uden at gøre andet.

.SH FILER
Programmet bruger datafilerne fra Retskrivningsordbogens cd-rom-udgave.
Nærmere bestemt filerne »roall.fwd« med alle opslagsord og »roflat.fwd«
med alle artikler. Se næste afsnit om miljøvariable for placeringen af
disse filer.

Ordbogsfilerne distribueres
.I ikke
med dette program da det ville krænke Dansk Sprognævns ophavsret.

.SH MILJØVARIABLE
.IP RODIR
Det filkatalog som programmet vil lede efter ordbogsfilerne i. Hvis
»RODIR« ikke er defineret, bruges »/mnt/cdrom«.

.IP LC_ALL,\ C_CTYPE,\ LANG
Lokalitetsindstilling. Se nærmere i næste afsnit om tegnsæt.

.SH TEGNSÆT
Programmet arbejder internt med tegnsættet
.BR latin1 (7)
også kaldet iso-8859-1, og omsætter det tegnsæt som ordbogsfilerne er
gemt i (DOS Code Page 850 med enkelte ændringer), til dette.

Det regulære udtryk som der søges efter, skal være i latin1, og uddata
vil være i latin-1.

Det forventes ligeledes en lokalitetsindstilling (se
.BR locale (7))
som angiver latin1 som det lokale tegnsæt til brug for at kunne undlade
at skelne mellem store og små bogstaver (se
.BR -i -tilvalget).

Jeg håber på i en senere udgave af
.B ro
at kunne understøtte flere tegnsæt, specielt
.BR utf-8 (7).

.SH ORDKLASSEKODER
Ordklassekoderne som kan udskrives ved brug af
.BR -k -tilvalget,
ser ud til at betyde følgende:

.IP A
adjektiv
.IP B
substantiv, intetkøn
.IP C
ubøjeligt adjektiv
.IP D
adverbium
.IP E
substantiv, intetkøn eller fælleskøn
.IP F
forkortelse
.IP G
substantiv, findes kun i flertal
.IP H
ubøjeligt substantiv
.IP I
udråbsord
.IP J
verbum, passiv
.IP K
konjuktion
.IP L
præposition eller adverbium
.IP M
adverbium eller konjuktion
.IP N
talord
.IP O
lydord
.IP P
pronomen
.IP Q
forkortelse, bøjes som substantiv (fælleskøn)
.IP R
præposition
.IP S
substantiv, fælleskøn
.IP T
bestemt artikel [den]
.IP U
verbum, uregelmæssigt
.IP V
verbum, datid på -te
.IP W
verbum, datid på -ede, eller både -te og -ede
.IP X
diverse ord uden bøjningsangivelse (egennavne, faste udtryk i flere ord,
uregelmæssige bøjningsformer af andre opslagsord)
.IP Y
præposition, adverbium eller konjuktion
.IP Z
substantiv uden bestemt form
.IP 1
adjektiv, findes kun i flertal
.IP 2
præposition eller konjunktion
.IP 3
forkortelse, bøjes som substantiv (intetkøn)
.IP 4
ubøjeligt adjektiv eller præposition
.IP 5
adverbium eller udråbsord
.IP 6
ubestemt artikel [en]
.IP 7
pronomen eller talord [anden]
.IP 8
ubøjeligt adjektiv eller adverbium

.SH FEJL
Programmet understøtter kun latin1-tegnsættet, som ikke kan gengive
indholdet af Retskrivningsordbogen korrekt. Der burde være et
promilletegn i artiklen for »promille«, men det kan ikke gengives.

Sammenhængen mellem store og små bogstaver til brug for
.BR -i -tilvalget
afhænger af lokalitetsindstillingen i programmets miljø selvom
programmet alligevel kun kan arbejde med et bestemt tegnsæt.

.SH FORFATTER

Byrial Ole Jensen <byrial@image.dk>

.SH COPYRIGHT

Programmet: Copyright (c) 2000 Byrial Ole Jensen <byrial@image.dk>.

Programmet er frit – alle må distribuere og ændre det i henhold til
betingelserne i »GNU General Public License«.

Datafiler (Retskrivningsordbogen): Copyright (c) 1986, 1996 Dansk
Sprognævn.

.SH SE OGSÅ
Programmet er inspireret af Jens Kristian Søgaards Perl-program
.BR ordbog.pl (1)
(<URL: http://www.jksoegaard.dk/Ordbog/>) som har samme funktion som
.BR ro ,
men er betydeligt langsommere.

Dette indlæg blev udgivet i Knowledge Base, Linux, Old Base. Bogmærk permalinket.

Skriv et svar