#! /usr/bin/awk -f #---------------------------------------------- # normtext.awk v. 0.5á [01-Jul-1996] by Pior Kłosowski # (pklos@press.umcs.lublin.pl) # (for UNIX operating system and iso-latin-2 polish letters) # Convert bad typed text files to better form suitable for TeX. # Usage: # awk -f normtext infile > outfile #---------------------------------------------- # Na bazie pomysłów Tomasz Przechlewskiego i Marka Ryćki spóbowałem # skonstruować bardziej uniwersalne rzędzie do filtrowania kiepskich # plików tekstowych w~postać strawną dla TeX-a. Piotr Kłosowski, maj 1996~r. # Założenia: # tekst z akapitami odzielonymi wierszami "blanklines" o początkach # pasujących do wzorca "parbeg", # język polski - iso-latin-2; # teksty spoza nauk ścisłych; # ignoruję tabelki, przypisy... # Plan: #A. Usunięcie podziału na strony wraz z paginowaniem. #B. Usunięcie przeniesień wyrazów (w trakcie budowania "para"). #C. Niełamliwe spacje przy spójnikach, inicjałach i skrótach. #D. Konstrukcja odpowiednich kresek, cudzysłowów, wielokropków, nawiasów. #E. Kropki, przecinki, odstępy w liczbach. #F. Uporządkowanie spacji przy znakach przestankowych. #G. Symbole spotykane w tekstach niematematycznych: %, $, <, >. #---------------------------------------------- BEGIN { stdio = "/dev/null"; digit = "[0-9]"; rdigit = "[IVXLCM]"; capletter = "[A-ZĄĘĆŁŃÓŚŹŻ]"; lowletter = "[a-ząęćłńóśźż]"; nonlowletter = "[^a-ząęćłńóśźż]"; letter = "[A-ZĄĘĆŁŃÓŚŹŻa-ząęćłńóśźż]"; spojnik = "[AIOUWZaiouwz]"; wspaces = "[\\ \\t\\n]+"; nonwspace = "[^\\ \\t\\n]"; wspacesornot = "[\\ \\t\\n]*"; # wzorzec wiersza międzyakapitowego (dopasowany do konwersji z TAG-a) blanklines = "^[\\ \\t]*(- [0-9]+ -)*[\\ \\t]*$"; nbl = 0; # licznik wierszy międzyakapitowych # wzorzec początku akapitu parbeg = "^[\\ \\t]*[^\\t\\ a-ząćęłńóśżź].*$"; # parbeg = "^[\\ \\t]*[A-ZĄĆĘŁÓŃŚŹŻ0-9].*$"; } # wymień _co_ w kontekście _bef_ _aft_ na _na_ (kontekst jednoznakowy) # _bef_, _co_ i _aft_ są łańcuchami interpetowanymi jako wyrażenia regularne # (uwaga na podwójne wtyłciachy); _na_ jest łańcuchem # pomysł: Marek Ryćko function exch (bef, co, aft, na) { while (match(para, bef co aft) > 0) { match(para, bef co aft); nowy = substr(para, 1, RSTART) na substr(para, RSTART+RLENGTH-1); para = nowy; } } # koniec funkcji exch(bef, co, aft, na) # wymień _co_ w kontekście _bef_ _aft_ na _na_ (kontekst wieloznakowy) # _bef_, _co_ i _aft_ są łańcuchami interpetowanymi jako wyrażenia regularne # (uwaga na podwójne wtyłciachy); _na_ jest łańcuchem # pomysł: Marek Ryćko function xexch (bef, co, aft, na) { while (match(para, bef co aft) > 0) { match(para, bef co aft); R1 = RSTART; L1 = RLENGTH; test = substr(para,RSTART,RLENGTH); test1 = match(test,bef); R2 = RSTART; L2 = RLENGTH; test2 = match(test,aft); R3 = RSTART; L3 = RLENGTH; nowy = substr(para, 1, R1 + L2 - 1) na substr(para, R1 + L1 - L3); para = nowy; } } # koniec funkcji xech(bef, co, aft, na) # formatuje akapit na rozsądną szerokość <= 72 zn. function print_para() { words = split(para, paralist, " "); len = length(paralist[1]); printf "%s", paralist[1]; for (i=2; i<=words; i++) { len += length(paralist[i]); ###print len, paralist[i] >> stdio; if (++len>72) { printf "\n%s", paralist[i]; len = length(paralist[i]); } else printf " %s", paralist[i]; } if (len) printf "\n\n"; else printf "\n"; } # koniec funkcji print_para() # główna funkcja dokonująca analizy i przekształceń akapitu # pomysł: T. Przechlewski function process_para() { print "Paragraph: ", length(para), "bytes" >> stdio; #spójniki# gsub(/[ \t\n]+a[ \t\n]+/, " a~", para); gsub(/\~a /, "~a~", para); gsub(/[ \t\n]+i[ \t\n]+/, " i~", para); gsub(/\~i /, "~i~", para); gsub(/[ \t\n]+o[ \t\n]+/, " o~", para); gsub(/\~o /, "~o~", para); gsub(/[ \t\n]+u[ \t\n]+/, " u~", para); gsub(/\~u /, "~u~", para); gsub(/[ \t\n]+w[ \t\n]+/, " w~", para); gsub(/\~w /, "~w~", para); gsub(/[ \t\n]+z[ \t\n]+/, " z~", para); gsub(/\~z /, "~z~", para); gsub(/[ \t\n]+A[ \t\n]+/, " A~", para); gsub(/\~A /, "~A~", para); #ryzykowne - cyfry rzymskie# gsub(/[ \t\n]+I[ \t\n]+/, " I~", para); gsub(/\~I /, "~I~", para); gsub(/[ \t\n]+O[ \t\n]+/, " O~", para); gsub(/\~O /, "~O~", para); gsub(/[ \t\n]+U[ \t\n]+/, " U~", para); gsub(/\~U /, "~U~", para); gsub(/[ \t\n]+W[ \t\n]+/, " W~", para); gsub(/\~W /, "~W~", para); gsub(/[ \t\n]+Z[ \t\n]+/, " Z~", para); gsub(/\~Z /, "~Z~", para); #inicjały# xexch(capletter, "\\." wspacesornot, capletter lowletter, "\.\~"); xexch(capletter, "\\." wspacesornot, capletter "\\.\\~", "\.\~"); #skróty - daty# exch(digit, wspacesornot "r", "\\.", "~r"); exch("r", "\\." wspacesornot, digit, ".~"); exch(digit, wspacesornot "w", "\\.", "~w"); exch(rdigit, wspaces "w", "\\.", "~w"); #skróty - bibliografia# exch(nonlowletter, "s\\." wspacesornot, digit, "s.~"); exch(nonlowletter, "ss\\." wspacesornot, digit, "s.~"); exch(nonlowletter, "t\\." wspacesornot, digit, "t.~"); exch(nonlowletter, "t\\." wspacesornot, rdigit, "t.~"); exch(nonlowletter, "z\\." wspacesornot, digit, "z.~"); exch(nonlowletter, "art\\." wspacesornot, digit, "art.~"); #skróty - inne# exch(nonlowletter, "[Tt]ab\\." wspacesornot, digit, "tab.~"); exch(nonlowletter, "[Tt]abl\\." wspacesornot, digit, "tabl.~"); exch(nonlowletter, "[Rr]yc\\." wspacesornot, digit, "ryc.~"); exch(nonlowletter, "[Rr]ys\\." wspacesornot, digit, "ryc.~");# ! exch(nonlowletter, "[Rr]ozdz\\." wspacesornot, digit, "rozdz.~"); exch(nonlowletter, "nr" wspacesornot, digit, "nr~"); #skróty - lokalne# exch(nonlowletter, "stan\\." wspaces, digit, "stan.~"); exch(nonlowletter, "w\\." wspaces, digit, "w.~"); exch(nonlowletter, "Mi" wspaces, digit, "Mi~"); exch(nonlowletter, "Jr" wspaces, digit, "Jr~"); exch(nonlowletter, "Ez" wspaces, digit, "Ez~"); exch(nonlowletter, "Za" wspaces, digit, "Za~"); exch(nonlowletter, "J" wspaces, digit, "J~"); exch(nonlowletter, "Oz" wspaces, digit, "Oz~"); exch(nonlowletter, "Jl" wspaces, digit, "Jl~"); exch(nonlowletter, "Ps" wspaces, digit, "Ps~"); exch(nonlowletter, "Wj" wspaces, digit, "Wj~"); #liczby, jednostki# exch(digit, wspacesornot "tys", nonlowletter, "~tys"); exch(digit, wspacesornot "mln", nonlowletter, "~mln"); exch(digit, wspacesornot "zł", nonlowletter, "~zł"); exch(digit, wspacesornot "ha", nonlowletter, "~ha"); xexch(digit, wspacesornot, "[kcm][glms]" nonlowletter, "~"); #endashes# exch(digit, wspacesornot "-" wspacesornot, digit, "--"); #emdashes# gsub(wspaces "-" wspaces, " --- ", para); #cudzysłowy# exch("[^\\a-ząęćłńóśźż]", "\"", letter, ",,"); exch(wspaces, "\"", nonwspace, ",,"); #gsub("Ž", "<<", para); #gsub("Ż", ">>", para); #nawiasy ukośne - ryzykowne (łamane przez)# #exch(wspaces, "/", nonwspace, "("); #exch(nonwspace, "/", wspaces, ")"); #wielokropek# gsub(/\.\.\.\.+/, "\\dotfill{}", para); gsub(/\.\.\./, "\\ldots{}", para); gsub(/\(\\ldots\{\}\)/, "[\\ldots{}]", para); #pisownia liczb - ryzykowne (psuje dziesiętną numerację rozdz., wzorów, itp. #dziesiętną klasyfikację biblioteczną, klasyfikację chorób itp #exch(digit, "\\.", digit, ",") xexch("[0-9]", "", "[0-9][0-9][0-9][^0-9]", "\\,"); xexch("[^0-9][0-9]", "\\\\,", "[0-9][0-9][0-9][^0-9\\\\]", ""); #spacje przy znakach przestankowych - być może ryzykowne# exch(nonwspace, wspaces "\\,", "[^\\,]", ","); exch("[^\\,]", ",", letter, ", "); exch(nonwspace, wspaces "\\.", "[^\\.]", "."); exch(".", "\\.", letter, ". "); xexch(".", "\\.", ",,", ". "); #wyjątki# gsub(/p\. n\. e\./, "p.n.e.", para); gsub(/n\. e\./, "n.e.", para); gsub(/m\. in\./, "m.in.", para); exch(nonwspace, wspaces ";", ".", ";"); exch(".", ";", nonwspace , "; "); exch(nonwspace, wspaces ":", ".", ":"); exch(".", ":", nonwspace, ": "); #wyjątki# gsub(/\[w: \]/,"[w:]",para); exch(nonwspace, wspaces "\\?", ".", "?"); exch(".", "\\?", letter, "? "); exch(nonwspace, wspaces "!", ".", "!"); exch(".", "!", letter, "! "); exch(".", "\\(" wspaces, nonwspace, "("); exch(letter, "\\(", ".", " ("); exch(nonwspace, wspaces "\\)", ".", ")"); exch(".", "\\)", letter, ") "); #spacje przy nawiasach klamrowych (wyróżnienia) xexch(nonwspace, "\\{", "\\\\((bf)|(em)|(it))", " {"); xexch("(\\~|\\(|(,,)|(>>)|(<<))", "\\ \\{", "\\\\((bf)|(em)|(it))", "{"); exch(nonwspace, wspaces "\\}", ".", "} "); #ryzykowne (np. kropki od dziesiętnej numeracji rozdz., wzorów, tabel...) gsub(/\.\}/, "}.", para); gsub(/\}\.\./, ".}.", para); gsub(/\,\}/, "},", para); #symbole niematematyczne# exch(digit, wspacesornot "\\%", ".", "\\%"); exch(digit, wspacesornot "\\$", "[^\\^\\\\]", "\\$"); gsub("&","\\&") exch("[^<\\$]", "<", "[^<\\$]", "$<$"); exch("[^>\\$]", ">", "[^>\\$]", "$>$"); #lokalne - litery akcentowe zagraniczne (TAG)# # gsub(//, "\\\"u", para); # gsub(/Ÿ/, "\\v{c}", para); # gsub(/Ź/, "\\v{C}", para); # gsub(/í/, "\\oo{}", para); #formatowanie akapitu# print_para(); para = ""; } # koniec funkcji process_para() # pominięcie wierszy pasujących do "blanklines" $0~blanklines { nbl++ } # po pominięciu wierszy pasujących do "blanklines"... $0!~blanklines { # sprawdzenie czy następujący tekst jest początkiem nowego # akapitu i przetwarzanie poprzedniego akapitu if (nbl>0 && $0~parbeg) {process_para()}; # tworzenie łańcucha "para" zawierającego akapit z~usuniętymi # przeniesieniami wyrazów i odstępami lewego marginesu # ryzykowne - łączniki, przyrostki na końcu wiersza sub(/^[\ \t\n]+/,""); if (match(para, lowletter "-" wspacesornot "$")==0) para = para " " $0 else para = substr(para, 1, RSTART) $0; nbl = 0 } END {process_para();}