#!/bin/sh
# ordbanken – oppslag i Norsk ordbank etter ord som tilfredstiller visse kriterium.
#
# Copyright © 2008, 2009 Karl Ove Hufthammer <karl@huftis.org>.
#
#     This file is part of Ordbanken.
#
#     Ordbanken 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 3 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, see <http://www.gnu.org/licenses/>.

# Nokre nødvendige variablar, samt standardverdiar.
mappe="/usr/local/share/ordbanken"
fargekod=1  # Fargelegg resultatet.
klammer=1   # Vis òg klammeformer.
parentes=1  # Legg klammeparentes rundt klammeformene.
html=0      # Vis tekst og ikkje HTML.

sprak=$SPRAK_ORDBANKEN
if [ -z "$sprak" ] # Nynorsk som standardspråk viss ikkje noko anna er valt.
then
  sprak=nn
fi

# Versjonsnummer og copyright-år.
versjon='2009-06-07'
copyar='2008, 2009'

# Namn og adresse for feilrapportar.
adresse='Karl Ove Hufthammer <karl@huftis.org>'

# Sjekk om verktøyet «look» finst.
LOOK_PROG=$(command -v look)
LOOK_FINST=$?

# Vis informasjon om korleis skriptet skal brukast.
bruk() {
echo -e 'Bruk: ordbanken [VAL] grunnord [KRITERIUM1] [KRITERIUM2] ...
Slår opp ordet «grunnord» i fullformsordlista til Norsk ordbank,
med eventuell filtrering etter eitt eller fleire kriterium.\n'

echo \
'Verdiar for VAL:
  -s, --sprak=SPRÅKKODE	Vel ordliste, der SPRÅKKODE er nn for
  	nynorsk (standard) eller nb for bokmål.
  -e, --eksempel	Vis eksempel på bruk, samt nokre tips.
  -f, --fargekod	Fargekod resultatet (standard).
  -F, --ikkje-fargekod	Ikkje fargekod resultatet.
  -k, --klammer	Vis òg klammeformer (standard).
  -K, --ikkje-klammer	Vis ikkje klammeformer.
  -p, --parentes	Vis klammeparentesar rundt klammeformer (standard).
  -P, --ikkje-parentes	Ikkje vis klammeparentesar rundt klammeformer.
      --tekst	Vis resultatet som rein tekst (standard).
      --html	Vis resultatet som HTML.
  -h, --hjelp	Vis denne hjelpeteksten.
  -v, --versjon	Vis programversjon og lisensinformasjon.' | column -t -s"	"

echo ""
echo "Meld frå om feil til $adresse."
}

# Vis nokre eksempel på bruk av skriptet.
versjon() {
echo "Ordbanken versjon $versjon.

Programmet er Copyright © $copyar $adresse
Ordlistene er Copyright © $copyar Universitetet i Oslo

Ordbanken er fri programvare, og kjem UTAN NOKON GARANTIAR.
Du må gjerne gje programmet vidare, under visse vilkår.

Lisensvilkår: GPLv3+ – GNU GPL versjon 3 eller seinare
<http://www.gnu.org/licenses/gpl.html>.

Programmet er skrive er Karl Ove Hufthammer, og
ordlistene er utvikla av, og vert vedlikehaldne av,
Universitetet i Oslo."
}

# Vis nokre eksempel på bruk av skriptet.
eksempel() {
echo 'Her er nokre eksempel på bruk av programmet.
Merk at oppslagsordet må vera fullstendig, men
det held å bruka starten av eventuelle kodar.

Bøying av ordet «å lese» på standardspråket:
  ordbanken lese

Berre perfektum partisipp-former:
  ordbanken lese perf

Ordet «hoppe», men berre som substantiv:
  ordbanken hoppe subst

Bøying av «å finnes» på bokmål:
  ordbanken --sprak=nb finnes

Fleirtal av substantivet «hoppe» på bokmål:
  ordbanken -snb hoppe su fl

Ordet «annan», med fargekoding (som er standard):
  ordbanken --fargekod annan

Same, men no utan fargekoding, og utan klammeformer:
  ordbanken --ikkje-fargekod --ikkje-klammer annan

Same som over, berre mindre å skriva:
  ordbanken -FK annan

Lagra resultatet som HTML i fila «annan.html»:
  ordbanken --html annan > annan.html

Om ikkje anna er valt, vert nynorsk brukt som
standardspråk, men du kan òg definera standard-
språket i miljøvariabelen SPRAK_ORDBANKEN.

Legg for eksempel
  export SPRAK_ORDBANKEN=nb
til i fila ~/.bashrc for å bruka bokmål som standard.

Programmet støttar òg autofullføring via bash
completion. Viss du har installert og slått
på bash completion, kan du bruka tabulator-
tasten slik:

$ ordbanken [tab]
ordbanken --sprak
(Valet «--sprak» vart automatisk lagt til.)

$ ordbanken --sprak [tab]
nb nn
ordbanken --sprak n
(Liste med vala «nb» og «nn» vart vist,
og bokstaven «n» vart lagd til.)

$ ordbanken -[tab]
-e                --ikkje-fargekod  --parentes
--eksempel        --ikkje-klammer   -s
-F                --ikkje-parentes  -snb
-f                -K                -snn
--fargekod        -k                --sprak
-h                --klammer         --tekst
--hjelp           -P                -v
--html            -p                --versjon
(Liste over alle moglege argument vart vist.)

$ ordbanken --sprak nn ym[tab]
ym         ymislig    ymse       ymsing
ymis       ymisskap   ymsefinna  ymt
ymiskvar   ymist      ymsen      ymte
ymisleg    ymje       ymsesidig  ymting
(Liste over alle nynorskord som startar med «ym» vart vist.)

$ ordbanken --sprak nn hoppe [tab]
adj         fem         klammeform  pres        ub
appell      fl          m/f         pret        verb
bu          imp         nøyt        st-form
eint        inf         perf-part   subst
(Liste over alle filtreringskriterium (ordklassar)
ein kan bruka for nynorskordet «hoppe».)'
}

# Hent kommandolinjevala.
val=$(getopt -n "$0" --options="s:ehvkKfFpP" \
      --longoptions="sprak:,eksempel,hjelp,versjon,fargekod,ikkje-fargekod,klammer,ikkje-klammer,parentes,ikkje-parentes,tekst,html" -- "$@")
ret=$?

eval set -- "$val"

# Vis hjelpeteksten og avslutt dersom getopt avslutta med feil.
if [ $ret -ne 0 ]
then
  bruk
  exit 1;
fi

# Tolk kommandolinjevala.
while true; do
  case $1 in
    -h | --hjelp )  bruk; exit 0 ;;
    -v | --versjon )  versjon; exit 0 ;;
    -e | --eksempel )  eksempel; exit 0 ;;
    -f | --fargekod) fargekod=1;;
    -F | --ikkje-fargekod ) fargekod=0 ;;
    -k | --klammer ) klammer=1;;
    -K | --ikkje-klammer ) klammer=0 ;;
    -p | --parentes ) parentes=1 ;;
    -P | --ikkje-parentes ) parentes=0 ;;
    -s | --sprak ) shift; sprak=$1 ;;
    --tekst ) html=0;;
    --html ) html=1 ;;
    -- ) shift; break ;;
    * ) echo "Feil: Ugyldig argument: $1"; bruk; exit 1;;
  esac
  shift
done

# Ord som skal slåast opp.
ord=$1

# Må ha eit oppslagsord. Avslutt viss me ikkje har det.
if [ ! -n "$ord" ]
then
  bruk
  exit 1
fi

# Eventuelt filter for utfiltrering av klammeformer.
# Klammeformkoden kjem alltid heilt på slutten, eller
# har ein kode som startar på «<» etter seg (eksempel:
# orda «forgjeve» og «blåse»).
if [ $klammer = 1 ]
then
  klammer="#ingafiltrering#"
else
  klammer="klammeform\(	<.*\)\?$"
fi

# Eventuell utbytingstekst som legg til klammeparentes rundt klammeformer.
if [ $parentes = 1 ]
then
  partekst='\[\2\]'
else
  partekst='\2'
fi

# Intern språkkode (ordbanken brukar «bm» for bokmål, merkelig nok).
case $sprak in
  nb ) isprak=bm; spraknamn="bokmål";;
  nn ) isprak=nn; spraknamn="nynorsk";;
  * ) echo "Feil: Språkkoden «$sprak» er ikkje gyldig."; echo "Bruk «nn» (for nynorsk) eller «nb» (for bokmål)."; exit 1;;
esac

# Ordbankfilene ligg i SVN.
ordbok=$mappe/fullform_$isprak.dat

# Sjølve utveljinga.
# Forklaring på kommandoane nedanfor:
#  awk: Trekk ut oppføringar med rett grunnord.
#  grep: Filtrer vekk kommentarar (linjer som startar med «*»).
#  grep: Filtrer unormerte ord og eventuelt òg klammeformer.
#  sed: Gjer om mellomrom i siste del av linja (der kodane er) til tabulatorar.
#       (Korfor den kompliserte sed-kommandoen? Fordi kodane i utgangspunktet er
#       skilde med mellomrom i staden for med tabulatorar. Dette ville ikkje vore
#       noko problem om alle oppføringar besto av eitt ord, då «column» som
#       standard handterer mellomrom og tabulatorar likt, men ordbanken har
#       oppføringar som «på kryss og tvers», og då ville alle orda få kvar si
#       kolonne (bruk «på» som oppslagsord for å sjå oppføringa).
#  sed: Fjern kodar (på forma <kode1>) som inneheld tal (interne/uforståelige kodar).
#  sed: Fjern kodar («ord» utan <>) som startar med tal (interne/uforståelige kodar).
#  sed: Fjern talkoden på starten av linja.
#  grep: Filtrer oppføringar etter dei opptil seks kriteria.
#  grep: Filtrer oppføringar etter dei opptil seks kriteria.
#  sort: Sorter først etter ord (nyttig ved oppslag på ord som «i»),
#        og så etter ordklasse (på ein lur måte).
#  sed: Gjer om to etterfølgjande «klammeform»-kodar til éin.
#  uniq: Fjern duplikatlinjer som kjem etter kvarandre.
#  sed: Legg eventuelt til klammeparentes rundt klammeformene.
if [ $LOOK_FINST -eq 0 ]
then
  oppslag="$(LC_ALL=C $LOOK_PROG "$ord " $ordbok)
$(LC_ALL=C $LOOK_PROG "$ord	" $ordbok)"
else
  oppslag="$(awk '{ if ( $1 == '\"$ord\"') {print $0}}' $ordbok)"
fi
resultat=$(echo "$oppslag" \
| grep -v "$klammer" \
| grep "\W<\?$2" | grep "\W<\?$3" | grep "\W<\?$4" \
| grep "\W<\?$5" | grep "\W<\?$6" | grep "\W<\?$7" \
| sort -k1,1 -k3,3 -k4,4 -k6,6 -k7,7 -k8,8 -k5,5 -s "-t	" \
| sed 's/	klammeform	klammeform\b/	klammeform/' \
| uniq \
| sed '/.*	.*	.*klammeform/s/^\([^	]\+	\)\([^	]\+\)/\1'"$partekst"'/g')

# Skriv til slutt ut resultatet. Anten i HTML-format:
if [ $html = 1 ]
then
# Lag tabell av resultatet.
html=$(echo "$resultat" \
| sed \
's/</\&lt;/;'\
's/^\([^	<]\+\)/    <tr><td>\1<\/td>/;'\
's/$/<\/tr>/;'\
's/	\([^	<]\+\)/<td>\1<\/td>/g;')

# Legg til klassar for seinare fargelegging. Grunnen til
# dei litt kompliserte uttrykka er at for eksempel ordet
# «fem» ikkje skal reknast som eit hokjønnsord.
html=$(echo "$html" | sed \
'/\(<td>.*\)\{3,\}<td>mask<\/td>/s/<tr/<tr class="mask"/;'\
'/\(<td>.*\)\{3,\}<td>fem<\/td>/s/<tr/<tr class="fem"/;'\
'/\(<td>.*\)\{3,\}<td>m\/f<\/td>/s/<tr/<tr class="mf"/;'\
'/\(<td>.*\)\{3,\}<td>nøyt<\/td>/s/<tr/<tr class="noyt"/;'\
'/\(<td>.*\)\{3,\}<td>klammeform<\/td>/{
s/<tr class="\([^"]\+\)"/<tr class="klamme \1"/;
s/<tr>/<tr class="klamme">/;}')

# HTML-koden før og etter tabellen..
html=$(
echo \
'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html lang="'$sprak'" xml:lang="'$sprak'">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Fullformsordliste'" ($spraknamn): $*"'</title>
  <style type="text/css">
    body    { color: black; background: white; }
    td + td { padding-left: 2em; }
    .klamme { font-style: italic; }'
if [ $fargekod = 1 ] # Eventuelt legg til CSS-kode for fargelegging.
then
echo \
'    .mask   { color: blue; }
    .fem    { color: red; }
    .mf     { color: green; }
    .noyt   { color: orange; }'
fi
echo \
'  </style>
</head>

<body>'
if [ -n "$resultat" ] # Ikkje legg til tabell om han er tom.
then
echo '  <table>'
linjefiks='s/<td/\n      <td/g;s/<\/tr>/\n    <\/tr>/' # sed-kode for linjeskift.
echo "$html" | grep 'class="klamme' | sed "$linjefiks"    # Vis klammeformene først ...
echo "$html" | grep -v 'class="klamme' | sed "$linjefiks" # ... og so resten.
echo '  </table>'
fi
echo \
'</body>

</html>'
)
echo "$html"

else # html = 0, altso tekstvising.
resultat=$(echo "$resultat" | column -t -s"	") # Formater som ein fin tabell.

# Eventuell fargekoding. Igjen litt komplisert for å unngå
# at for eksempel grunnordet «fem» (og tilhøyrande bøying)
# skal markerast som hokjønn.
if [ $fargekod = 1 ]
then
resultat=$(echo "$resultat" \
| sed 's/\(   *[^ ]\+.*  .*\)\b\(mask\)\b\(.*\)/\1[1;34m\2[0m\3/g' \
| sed 's/\(   *[^ ]\+.*  .*\)\b\(fem\)\b\(.*\)/\1[1;35m\2[0m\3/g' \
| sed 's/\(   *[^ ]\+.*  .*\)\b\(m\/f\)\b\(.*\)/\1[1;32m\2[0m\3/g' \
| sed 's/\(   *[^ ]\+.*  .*\)\b\(nøyt\)\b\(.*\)/\1[1;33m\2[0m\3/g' \
| sed 's/\(   *[^ ]\+.*  .*\)\b\(klammeform\)\b\(.*\)/\1[0;31m\2[0m\3/g')
fi

# Skriv til slutt ut resultat, med klammeformene først..
klresultat=$(echo "$resultat" | grep -F ']')
iklresultat=$(echo "$resultat" | grep -Fv ']')
resultat=$(echo "$klresultat"; echo "$iklresultat")
echo "$resultat" | grep -v ^$
fi
