:- use_module(library(dcgs)).
:- use_module(library(lists)).
:- use_module(library(dif)).

% util
peek(T), [T] --> [T].

% eof is only true at the end of the string, but does not consume anything.
% A sprinkle of state may be needed to avoid matching multiple times.
eof_([], []).
eof --> call(eof_).

% csv rules
rows([])       --> rows_end.
rows([R | Rs]) --> row(R),rows(Rs).

rows_end --> [eof], eof. % --> [eof-the-atom], eof-the-dcgrule

row([F])      --> field(F),row_end.
row([F | Fs]) --> field(F),row(Fs).

row_end        --> [eol], peek(_).
row_end, [eof] --> [eol], eof.

field([])       --> field_end.
field([C | Cs]) --> [C], {maplist(dif(C), [eof,eol | "\n;"])}, field(Cs).

field_end        --> ";".
field_end, [eol] --> "\n".
field_end, [eol] --> eof.

data("0000;<control>;Cc;0;BN;;;;;N;NULL;;;;\n0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;\n0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;\n0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;\n0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;\n0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;\n0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;\n0007;<control>;Cc;0;BN;;;;;N;BELL;;;;\n0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;\n0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;\n000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;\n000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;\n000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;\n0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;\n0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;\n0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;\n0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;\n0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;\n0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;\n0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;\n0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;\n0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;\n0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;\n001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;\n001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;\n001C;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;;\n001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;\n001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;\n001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;\n0020;SPACE;Zs;0;WS;;;;;N;;;;;\n0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;\n0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;\n0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;\n0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;\n0026;AMPERSAND;Po;0;ON;;;;;N;;;;;\n0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;\n0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;\n0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;\n002A;ASTERISK;Po;0;ON;;;;;N;;;;;\n002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;;\n002C;COMMA;Po;0;CS;;;;;N;;;;;\n002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;\n002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;\n002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;;\n0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;\n0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;\n0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;\n0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;\n0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;\n0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;\n0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;\n0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;\n0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;\n0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;\n003A;COLON;Po;0;CS;;;;;N;;;;;\n003B;SEMICOLON;Po;0;ON;;;;;N;;;;;\n003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;\n003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;\n003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;\n003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;\n0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;\n0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;\n0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;\n0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;\n0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;\n0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;\n0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;\n0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;\n0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;\n0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;\n004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;\n004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;\n004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;\n004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;\n004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;\n004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;\n0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;\n0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;\n0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;\n0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;\n0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;\n0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;\n0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;\n0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;\n0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;\n0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;\n005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;\n005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;\n005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;\n005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;\n005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;\n005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;\n0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;\n0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041\n0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042\n0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043\n0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044\n0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045\n0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046\n0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047\n0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048\n0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049\n006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A\n006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B\n006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C\n006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D\n006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E\n006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F\n0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050\n0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051\n0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052\n0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053\n0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054\n0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055\n0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056\n0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057\n0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058\n0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059\n007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A\n007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;\n007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;\n007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;\n007E;TILDE;Sm;0;ON;;;;;N;;;;;\n007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;\n0080;<control>;Cc;0;BN;;;;;N;;;;;\n0081;<control>;Cc;0;BN;;;;;N;;;;;\n0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;\n0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;\n0084;<control>;Cc;0;BN;;;;;N;;;;;\n0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;\n0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;\n0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;\n0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;\n0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;\n008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;\n008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;;\n008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;;\n008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;\n008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;\n008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;\n0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;\n0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;\n0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;\n0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;\n0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;\n0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;\n0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;\n0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;\n0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;\n0099;<control>;Cc;0;BN;;;;;N;;;;;\n009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;\n009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;\n009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;\n009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;\n009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;\n009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;\n00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;\n00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;\n00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;\n00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;\n00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;\n00A7;SECTION SIGN;Po;0;ON;;;;;N;;;;;\n00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;\n00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;\n00AA;FEMININE ORDINAL INDICATOR;Lo;0;L;<super> 0061;;;;N;;;;;\n00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;;\n00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;\n00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;\n00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;\n00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;\n00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;\n00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;\n00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;;\n00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;\n00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;\n00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C\n00B6;PILCROW SIGN;Po;0;ON;;;;;N;PARAGRAPH SIGN;;;;\n00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;\n00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;\n00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;\n00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L;<super> 006F;;;;N;;;;;\n00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;\n00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;\n00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;\n00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;\n00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;\n00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;\n00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;\n00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;\n00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;\n00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;\n00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;\n00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6;\n00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;\n00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;\n00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;\n00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;\n00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;\n00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;\n00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;\n00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;\n00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;\n00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0;\n00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;\n00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;\n00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;\n00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;\n00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;\n00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;\n00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;\n00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;\n00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;\n00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;\n00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;\n00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;\n00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;\n00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE;\n00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;;\n00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0\n00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1\n00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2\n00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3\n00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4\n00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5\n00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6\n00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7\n00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8\n00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9\n00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA\n00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB\n00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC\n00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD\n00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE\n00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF\n00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0\n00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1\n00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2\n00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3\n00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4\n00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5\n00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6").

codename(Codepoint, Codename) :-
    data(Data),
    phrase(rows(Rows), Data),
    member(Row, Rows),
    Row = [Codepoint, Codename | _].

% work around weird parsing behavior with extraneous choicepoints
get_codename(Codepoint, Codename) :- findall(Name, codename(Codepoint,Name), Names), Names = [Codename | _].
