diff options
author | sgeerke <devnull@localhost> | 2012-06-24 12:06:15 +0200 |
---|---|---|
committer | sgeerke <devnull@localhost> | 2012-06-24 12:06:15 +0200 |
commit | 39985d2c5158742fc9e00e7dd90559f9f5c8c75f (patch) | |
tree | 1950c633fd73c1b7ef5056ed18b9dcd527552d3b /test | |
parent | e02ec1bd1405715f050a71d40a9e3c212dd43123 (diff) |
First part of hyphenation! And some minor changes in "lout".
Diffstat (limited to 'test')
-rw-r--r-- | test/KHM1.html | 56 | ||||
-rw-r--r-- | test/KHM1b.html | 14 | ||||
-rw-r--r-- | test/KHM1c.html | 10 | ||||
-rw-r--r-- | test/Makefile.am | 7 | ||||
-rw-r--r-- | test/liang.cc | 184 |
5 files changed, 270 insertions, 1 deletions
diff --git a/test/KHM1.html b/test/KHM1.html new file mode 100644 index 00000000..b3924409 --- /dev/null +++ b/test/KHM1.html @@ -0,0 +1,56 @@ +<div style="text-align: justify"> +<p>In den al­ten Zei­ten, wo das Wün­schen noch +ge­hol­fen hat, leb­te ein Kö­nig, des­sen +Töch­ter wa­ren al­le schön, aber die jüng­ste war so +schön, daß die Son­ne sel­ber, die doch so vie­les +ge­se­hen hat, sich ver­wun­der­te so oft sie ihr +ins Ge­sicht schien. Na­he bei dem Schlos­se des +Kö­nigs lag ein gro­ßer dunk­ler Wald, und in dem +Wal­de un­ter ei­ner al­ten Lin­de war ein +Brun­nen: wenn nun der Tag recht heiß war, so ging das +Kö­nigs­kind hin­aus in den Wald und setz­te sich an +den Rand des küh­len Brun­nens: und wenn sie +Lan­ge­wei­le hat­te, so nahm sie eine +gol­de­ne Ku­gel, warf sie in die Hö­he und fieng sie +wie­der; und das war ihr liebs­tes Spiel­werk.</p> +<p>Nun trug es sich ein­mal zu, daß die gol­de­ne +Ku­gel der Kön­igs­toch­ter nicht in ihr Händ­chen +fiel, das sie in die Hö­he ge­hal­ten hat­te, +son­dern vor­bei auf die Er­de schlug und +ge­ra­de­zu ins Was­ser hin­ein roll­te. Die +Kö­nigs­toch­ter folg­te ihr mit den Aug­en nach, +aber die Ku­gel ver­schwand, und der Brun­nen war tief, so +tief daß man kei­nen Grund sah. Da fieng sie an zu wei­nen und +wein­te im­mer lau­ter und konn­te sich gar nicht +trös­ten. Und wie sie so klag­te, rief ihr je­mand zu „was +hast du vor, Kö­nigs­toch­ter, du schreist ja daß sich ein +Stein er­bar­men möchte.“ Sie sah sich um, wo­her die +Stim­me kä­me, da er­blick­te sie einen Frosch, der +sei­nen di­cken häß­li­chen Kopf aus dem Was­ser +streck­te. „Ach, du bists, al­ter +Was­ser­pat­scher,“ sag­te sie, „ich wei­ne über +mei­ne gol­de­ne Ku­gel, die mir in den Brun­nen +hin­ab ge­fal­len ist.“ „Sei still und wei­ne nicht,“ +ant­wor­te­te der Frosch, „ich kann wohl Rath +schaf­fen, aber was gibst du mir, wenn ich dein Spiel­werk +wie­der her­auf­ho­le?“ „Was du ha­ben willst, +lie­ber Frosch,“ sag­te sie, „mei­ne Klei­der, +mei­ne Per­len und Edel­stei­ne, auch noch die +gol­de­ne Kro­ne, die ich tra­ge.“ Der Frosch +ant­wor­te­te „dei­ne Klei­der, dei­ne +Per­len und Edel­stei­ne, und dei­ne gol­de­ne +Kro­ne, die mag ich nicht: aber wenn du mich lieb ha­ben +willst, und ich soll dein Ge­sel­le und +Spiel­ka­me­rad sein, an dei­nem Tisch­lein +ne­ben dir si­tzen, von dei­nem gol­de­nen +Tel­ler­lein es­sen, aus dei­nem Be­cher­lein +trin­ken, in dei­nem Bett­lein schla­fen: wenn du mir +das ver­sprichst, so will ich hin­un­ter stei­gen und +dir die gol­de­ne Ku­gel wie­der her­auf +ho­len.“ „Ach ja,“ sag­te sie, „ich ver­spre­che dir +alles, was du willst, wenn du mir nur die Ku­gel wie­der +bringst.“ Sie dach­te aber „was der ein­fäl­ti­ge +Frosch schwätzt, der sitzt im Was­ser bei sei­nes +Glei­chen und quackt, und kann kei­nes Men­schen +Ge­sel­le sein.“</p> +</div> diff --git a/test/KHM1b.html b/test/KHM1b.html new file mode 100644 index 00000000..adefc1ef --- /dev/null +++ b/test/KHM1b.html @@ -0,0 +1,14 @@ +<p style="text-align: justify">In den al­ten Zei­ten, wo das +Wün­schen noch ge­hol­fen hat, leb­te ein Kö­nig, +des­sen Töch­ter wa­ren al­le schön, aber die +jüng­ste war so schön, daß die Son­ne sel­ber, die doch so +vie­les ge­se­hen hat, sich ver­wun­der­te so +oft sie ihr ins Ge­sicht schien. Na­he bei dem Schlos­se +des Kö­nigs lag ein gro­ßer dunk­ler Wald, und in dem +Wal­de un­ter ei­ner al­ten Lin­de war ein +Brun­nen: wenn nun der Tag recht heiß war, so ging das +Kö­nigs­kind hin­aus in den Wald und setz­te sich an +den Rand des küh­len Brun­nens: und wenn sie +Lan­ge­wei­le hat­te, so nahm sie eine +gol­de­ne Ku­gel, warf sie in die Hö­he und fieng sie +wie­der; und das war ihr liebs­tes Spiel­werk.</p> diff --git a/test/KHM1c.html b/test/KHM1c.html new file mode 100644 index 00000000..3f3271fc --- /dev/null +++ b/test/KHM1c.html @@ -0,0 +1,10 @@ +<p style="text-align: justify">In den alten Zeiten, wo das Wünschen +noch geholfen hat, lebte ein König, dessen Töchter waren alle schön, +aber die jüngste war so schön, daß die Sonne selber, die doch so +vieles gesehen hat, sich verwunderte so oft sie ihr ins Gesicht +schien. Nahe bei dem Schlosse des Königs lag ein großer dunkler Wald, +und in dem Walde unter einer alten Linde war ein Brunnen: wenn nun der +Tag recht heiß war, so ging das Königskind hinaus in den Wald und +setzte sich an den Rand des kühlen Brunnens: und wenn sie Langeweile +hatte, so nahm sie eine goldene Kugel, warf sie in die Höhe und fieng +sie wieder; und das war ihr liebstes Spielwerk.</p> diff --git a/test/Makefile.am b/test/Makefile.am index a0a23c6a..daa2cef5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -21,7 +21,8 @@ noinst_PROGRAMS = \ dw-ui-test \ fltk-browser \ shapes \ - cookies + cookies \ + liang dw_anchors_test_SOURCES = dw_anchors_test.cc dw_anchors_test_LDADD = \ @@ -159,3 +160,7 @@ cookies_SOURCES = cookies.c cookies_LDADD = \ $(top_builddir)/dpip/libDpip.a \ $(top_builddir)/dlib/libDlib.a + +liang_SOURCES = liang.cc + +liang_LDADD = $(top_builddir)/lout/liblout.a diff --git a/test/liang.cc b/test/liang.cc new file mode 100644 index 00000000..3c402e6f --- /dev/null +++ b/test/liang.cc @@ -0,0 +1,184 @@ +#include "../lout/misc.hh" +#include "../lout/object.hh" +#include "../lout/container.hh" +#include <stdio.h> +#include <string.h> + +#define LEN 1000 + +/* + * This is a direct translation of the Python implementation by Ned + * Batchelder. + */ + +class Hyphenator +{ +private: + lout::container::typed::HashTable <lout::object::Integer, + lout::container::typed::Collection + <lout::object::Integer> > *tree; + void insertPattern (char *s); + +public: + Hyphenator (const char *filename); + + lout::container::typed::Vector <lout::object::String> + *hyphenateWord(const char *word); +}; + +using namespace lout::object; +using namespace lout::container::typed; + +Hyphenator::Hyphenator (const char *filename) +{ + tree = new HashTable <Integer, Collection <Integer> > (true, true); + + FILE *file = fopen (filename, "r"); + while (!feof (file)) { + char buf[LEN + 1]; + char *s = fgets (buf, LEN, file); + if (s) { + int l = strlen (s); + if (s[l - 1] == '\n') + s[l - 1] = 0; + insertPattern (s); + } + } + fclose (file); +} + +void Hyphenator::insertPattern (char *s) +{ + // Convert the a pattern like 'a1bc3d4' into a string of chars 'abcd' + // and a list of points [ 0, 1, 0, 3, 4 ]. + int l = strlen (s); + char chars [l + 1]; + Vector <Integer> *points = new Vector <Integer> (1, true); + + // TODO numbers consisting of multiple digits? + // TODO Encoding: This implementation works exactly like the Python + // implementation, based on UTF-8. Does this always work? + int numChars = 0; + for (int i = 0; s[i]; i++) + if (s[i] >= '0' && s[i] <= '9') + points->put (new Integer (s[i] - '0'), numChars); + else + chars[numChars++] = s[i]; + chars[numChars] = 0; + + for (int i = 0; i < numChars + 1; i++) { + Integer *val = points->get (i); + if (val == NULL) + points->put (new Integer (0), i); + } + + // Insert the pattern into the tree. Each character finds a dict + // another level down in the tree, and leaf nodes have the list of + // points. + + HashTable <Integer, Collection <Integer> > *t = tree; + for (int i = 0; chars[i]; i++) { + Integer c (chars[i]); + if (!t->contains(&c)) + t->put (new Integer (chars[i]), + new HashTable <Integer, Collection <Integer> > (true, true)); + t = (HashTable <Integer, Collection <Integer> >*) t->get (&c); + } + + t->put (new Integer (0), points); +} + +/** + * Given a word, returns a list of pieces, broken at the possible + * hyphenation points. + */ +Vector <String> *Hyphenator::hyphenateWord(const char *word) +{ + // Short words aren't hyphenated. + if (strlen (word) <= 4) // TODO UTF-8 + return NULL; // TODO + + // If the word is an exception, get the stored points. + // TODO + + char work[strlen (word) + 3]; + strcpy (work, "."); + strcat (work, word); // TODO tolower + strcat (work, "."); + + int l = strlen (work); + Vector <Integer> points (l + 1, true); + for (int i = 0; i < l + 1; i++) + points.put (new Integer (0), i); + + Integer null (0); + + for (int i = 0; i < l; i++) { + HashTable <Integer, Collection <Integer> > *t = tree; + for (int j = i; j < l; j++) { + Integer c (work[j]); + if (t->contains (&c)) { + t = (HashTable <Integer, Collection <Integer> >*) t->get (&c); + if (t->contains (&null)) { + Vector <Integer> *p = (Vector <Integer>*) t->get (&null); + + for (int k = 0; k < p->size (); k++) { + Integer *v1 = points.get (i + k); + Integer *v2 = p->get (k); + // TODO Not very efficient, especially here: too much + // calls of "new" + points.put(new Integer (lout::misc::max (v1->getValue (), + v2->getValue ())), + i + k); + } + } + } else + break; + } + } + + // No hyphens in the first two chars or the last two. + points.put (new Integer (0), 1); + points.put (new Integer (0), 2); + points.put (new Integer (0), points.size () - 2); + points.put (new Integer (0), points.size () - 3); + + // Examine the points to build the pieces list. + Vector <String> *pieces = new Vector <String> (1, true); + char temp[strlen (word) + 1], *ptemp = temp; + + int n = lout::misc::min ((int)strlen (word), points.size () - 2); + for (int i = 0; i < n; i++) { + char c = word[i]; + int p = points.get(i + 2)->getValue (); + + *(ptemp++) = c; + if (p % 2) { + *ptemp = 0; + printf ("'%s'\n", temp); + ptemp = temp; + } + } + + *ptemp = 0; + printf ("'%s'\n", temp); + + return pieces; +} + +int main (int argc, char *argv[]) +{ + Hyphenator h ("test/hyph-de-1996.pat"); + h.hyphenateWord ("jahrhundertroman"); + puts ("---"); + h.hyphenateWord ("währenddessen"); + puts ("---"); + h.hyphenateWord ("ückerdorf"); + puts ("---"); + h.hyphenateWord ("über"); + puts ("---"); + h.hyphenateWord ("aber"); + puts ("---"); + + return 0; +} |