[BACK]Return to chars.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/chars.c, Revision 1.76

1.76    ! schwarze    1: /*     $Id: chars.c,v 1.75 2018/08/21 01:59:22 schwarze Exp $ */
1.1       kristaps    2: /*
1.51      schwarze    3:  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.70      schwarze    4:  * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
1.1       kristaps    5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
1.14      kristaps   18: #include "config.h"
1.59      schwarze   19:
                     20: #include <sys/types.h>
1.14      kristaps   21:
1.1       kristaps   22: #include <assert.h>
1.40      kristaps   23: #include <ctype.h>
1.68      schwarze   24: #include <stddef.h>
                     25: #include <stdint.h>
1.1       kristaps   26: #include <stdlib.h>
                     27: #include <string.h>
                     28:
1.18      kristaps   29: #include "mandoc.h"
1.56      schwarze   30: #include "mandoc_aux.h"
1.68      schwarze   31: #include "mandoc_ohash.h"
1.43      kristaps   32: #include "libmandoc.h"
1.1       kristaps   33:
                     34: struct ln {
1.68      schwarze   35:        const char        roffcode[16];
1.2       kristaps   36:        const char       *ascii;
1.21      kristaps   37:        int               unicode;
1.1       kristaps   38: };
                     39:
1.68      schwarze   40: /* Special break control characters. */
                     41: static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
                     42: static const char ascii_break[2] = { ASCII_BREAK, '\0' };
                     43:
                     44: static struct ln lines[] = {
                     45:
                     46:        /* Spacing. */
                     47:        { " ",                  ascii_nbrsp,    0x00a0  },
                     48:        { "~",                  ascii_nbrsp,    0x00a0  },
                     49:        { "0",                  " ",            0x2002  },
                     50:        { "|",                  "",             0       },
                     51:        { "^",                  "",             0       },
                     52:        { "&",                  "",             0       },
1.74      schwarze   53:        { ")",                  "",             0       },
1.68      schwarze   54:        { "%",                  "",             0       },
                     55:        { ":",                  ascii_break,    0       },
                     56:        /* XXX The following three do not really belong here. */
                     57:        { "t",                  "",             0       },
                     58:        { "c",                  "",             0       },
                     59:        { "}",                  "",             0       },
                     60:
                     61:        /* Lines. */
                     62:        { "ba",                 "|",            0x007c  },
                     63:        { "br",                 "|",            0x2502  },
                     64:        { "ul",                 "_",            0x005f  },
1.71      schwarze   65:        { "ru",                 "_",            0x005f  },
1.68      schwarze   66:        { "rn",                 "-",            0x203e  },
                     67:        { "bb",                 "|",            0x00a6  },
                     68:        { "sl",                 "/",            0x002f  },
                     69:        { "rs",                 "\\",           0x005c  },
                     70:
                     71:        /* Text markers. */
                     72:        { "ci",                 "O",            0x25cb  },
                     73:        { "bu",                 "+\bo",         0x2022  },
1.72      schwarze   74:        { "dd",                 "<**>",         0x2021  },
                     75:        { "dg",                 "<*>",          0x2020  },
1.68      schwarze   76:        { "lz",                 "<>",           0x25ca  },
                     77:        { "sq",                 "[]",           0x25a1  },
1.72      schwarze   78:        { "ps",                 "<paragraph>",  0x00b6  },
                     79:        { "sc",                 "<section>",    0x00a7  },
1.68      schwarze   80:        { "lh",                 "<=",           0x261c  },
                     81:        { "rh",                 "=>",           0x261e  },
                     82:        { "at",                 "@",            0x0040  },
                     83:        { "sh",                 "#",            0x0023  },
1.72      schwarze   84:        { "CR",                 "<cr>",         0x21b5  },
1.68      schwarze   85:        { "OK",                 "\\/",          0x2713  },
1.76    ! schwarze   86:        { "CL",                 "C",            0x2663  },
        !            87:        { "SP",                 "S",            0x2660  },
        !            88:        { "HE",                 "H",            0x2665  },
        !            89:        { "DI",                 "D",            0x2666  },
1.68      schwarze   90:
                     91:        /* Legal symbols. */
                     92:        { "co",                 "(C)",          0x00a9  },
                     93:        { "rg",                 "(R)",          0x00ae  },
                     94:        { "tm",                 "tm",           0x2122  },
                     95:
                     96:        /* Punctuation. */
                     97:        { "em",                 "--",           0x2014  },
                     98:        { "en",                 "-",            0x2013  },
                     99:        { "hy",                 "-",            0x2010  },
                    100:        { "e",                  "\\",           0x005c  },
                    101:        { ".",                  ".",            0x002e  },
                    102:        { "r!",                 "!",            0x00a1  },
                    103:        { "r?",                 "?",            0x00bf  },
                    104:
                    105:        /* Quotes. */
                    106:        { "Bq",                 ",,",           0x201e  },
                    107:        { "bq",                 ",",            0x201a  },
                    108:        { "lq",                 "\"",           0x201c  },
                    109:        { "rq",                 "\"",           0x201d  },
1.69      schwarze  110:        { "Lq",                 "\"",           0x201c  },
                    111:        { "Rq",                 "\"",           0x201d  },
1.68      schwarze  112:        { "oq",                 "`",            0x2018  },
                    113:        { "cq",                 "\'",           0x2019  },
                    114:        { "aq",                 "\'",           0x0027  },
                    115:        { "dq",                 "\"",           0x0022  },
                    116:        { "Fo",                 "<<",           0x00ab  },
                    117:        { "Fc",                 ">>",           0x00bb  },
                    118:        { "fo",                 "<",            0x2039  },
                    119:        { "fc",                 ">",            0x203a  },
                    120:
                    121:        /* Brackets. */
                    122:        { "lB",                 "[",            0x005b  },
                    123:        { "rB",                 "]",            0x005d  },
                    124:        { "lC",                 "{",            0x007b  },
                    125:        { "rC",                 "}",            0x007d  },
                    126:        { "la",                 "<",            0x27e8  },
                    127:        { "ra",                 ">",            0x27e9  },
                    128:        { "bv",                 "|",            0x23aa  },
                    129:        { "braceex",            "|",            0x23aa  },
                    130:        { "bracketlefttp",      "|",            0x23a1  },
                    131:        { "bracketleftbt",      "|",            0x23a3  },
                    132:        { "bracketleftex",      "|",            0x23a2  },
                    133:        { "bracketrighttp",     "|",            0x23a4  },
                    134:        { "bracketrightbt",     "|",            0x23a6  },
                    135:        { "bracketrightex",     "|",            0x23a5  },
                    136:        { "lt",                 ",-",           0x23a7  },
                    137:        { "bracelefttp",        ",-",           0x23a7  },
                    138:        { "lk",                 "{",            0x23a8  },
                    139:        { "braceleftmid",       "{",            0x23a8  },
                    140:        { "lb",                 "`-",           0x23a9  },
                    141:        { "braceleftbt",        "`-",           0x23a9  },
                    142:        { "braceleftex",        "|",            0x23aa  },
                    143:        { "rt",                 "-.",           0x23ab  },
                    144:        { "bracerighttp",       "-.",           0x23ab  },
                    145:        { "rk",                 "}",            0x23ac  },
                    146:        { "bracerightmid",      "}",            0x23ac  },
                    147:        { "rb",                 "-\'",          0x23ad  },
                    148:        { "bracerightbt",       "-\'",          0x23ad  },
                    149:        { "bracerightex",       "|",            0x23aa  },
                    150:        { "parenlefttp",        "/",            0x239b  },
                    151:        { "parenleftbt",        "\\",           0x239d  },
                    152:        { "parenleftex",        "|",            0x239c  },
                    153:        { "parenrighttp",       "\\",           0x239e  },
                    154:        { "parenrightbt",       "/",            0x23a0  },
                    155:        { "parenrightex",       "|",            0x239f  },
                    156:
                    157:        /* Arrows and lines. */
                    158:        { "<-",                 "<-",           0x2190  },
                    159:        { "->",                 "->",           0x2192  },
                    160:        { "<>",                 "<->",          0x2194  },
                    161:        { "da",                 "|\bv",         0x2193  },
                    162:        { "ua",                 "|\b^",         0x2191  },
                    163:        { "va",                 "^v",           0x2195  },
                    164:        { "lA",                 "<=",           0x21d0  },
                    165:        { "rA",                 "=>",           0x21d2  },
                    166:        { "hA",                 "<=>",          0x21d4  },
                    167:        { "uA",                 "=\b^",         0x21d1  },
                    168:        { "dA",                 "=\bv",         0x21d3  },
                    169:        { "vA",                 "^=v",          0x21d5  },
1.70      schwarze  170:        { "an",                 "-",            0x23af  },
1.68      schwarze  171:
                    172:        /* Logic. */
                    173:        { "AN",                 "^",            0x2227  },
                    174:        { "OR",                 "v",            0x2228  },
                    175:        { "no",                 "~",            0x00ac  },
                    176:        { "tno",                "~",            0x00ac  },
1.72      schwarze  177:        { "te",                 "<there\037exists>", 0x2203 },
                    178:        { "fa",                 "<for\037all>", 0x2200  },
                    179:        { "st",                 "<such\037that>", 0x220b },
                    180:        { "tf",                 "<therefore>",  0x2234  },
                    181:        { "3d",                 "<therefore>",  0x2234  },
1.68      schwarze  182:        { "or",                 "|",            0x007c  },
                    183:
                    184:        /* Mathematicals. */
                    185:        { "pl",                 "+",            0x002b  },
                    186:        { "mi",                 "-",            0x2212  },
                    187:        { "-",                  "-",            0x002d  },
                    188:        { "-+",                 "-+",           0x2213  },
                    189:        { "+-",                 "+-",           0x00b1  },
                    190:        { "t+-",                "+-",           0x00b1  },
                    191:        { "pc",                 ".",            0x00b7  },
                    192:        { "md",                 ".",            0x22c5  },
                    193:        { "mu",                 "x",            0x00d7  },
                    194:        { "tmu",                "x",            0x00d7  },
                    195:        { "c*",                 "O\bx",         0x2297  },
                    196:        { "c+",                 "O\b+",         0x2295  },
1.72      schwarze  197:        { "di",                 "/",            0x00f7  },
                    198:        { "tdi",                "/",            0x00f7  },
1.68      schwarze  199:        { "f/",                 "/",            0x2044  },
                    200:        { "**",                 "*",            0x2217  },
                    201:        { "<=",                 "<=",           0x2264  },
                    202:        { ">=",                 ">=",           0x2265  },
                    203:        { "<<",                 "<<",           0x226a  },
                    204:        { ">>",                 ">>",           0x226b  },
                    205:        { "eq",                 "=",            0x003d  },
                    206:        { "!=",                 "!=",           0x2260  },
                    207:        { "==",                 "==",           0x2261  },
                    208:        { "ne",                 "!==",          0x2262  },
                    209:        { "ap",                 "~",            0x223c  },
                    210:        { "|=",                 "-~",           0x2243  },
                    211:        { "=~",                 "=~",           0x2245  },
                    212:        { "~~",                 "~~",           0x2248  },
                    213:        { "~=",                 "~=",           0x2248  },
1.72      schwarze  214:        { "pt",                 "<proportional\037to>", 0x221d },
1.68      schwarze  215:        { "es",                 "{}",           0x2205  },
1.72      schwarze  216:        { "mo",                 "<element\037of>", 0x2208 },
                    217:        { "nm",                 "<not\037element\037of>", 0x2209 },
                    218:        { "sb",                 "<proper\037subset>", 0x2282 },
1.73      schwarze  219:        { "nb",                 "<not\037subset>", 0x2284 },
1.72      schwarze  220:        { "sp",                 "<proper\037superset>", 0x2283 },
1.73      schwarze  221:        { "nc",                 "<not\037superset>", 0x2285 },
1.72      schwarze  222:        { "ib",                 "<subset\037or\037equal>", 0x2286 },
                    223:        { "ip",                 "<superset\037or\037equal>", 0x2287 },
                    224:        { "ca",                 "<intersection>", 0x2229 },
                    225:        { "cu",                 "<union>",      0x222a  },
                    226:        { "/_",                 "<angle>",      0x2220  },
                    227:        { "pp",                 "<perpendicular>", 0x22a5 },
                    228:        { "is",                 "<integral>",   0x222b  },
1.73      schwarze  229:        { "integral",           "<integral>",   0x222b  },
                    230:        { "sum",                "<sum>",        0x2211  },
                    231:        { "product",            "<product>",    0x220f  },
                    232:        { "coproduct",          "<coproduct>",  0x2210  },
1.72      schwarze  233:        { "gr",                 "<nabla>",      0x2207  },
                    234:        { "sr",                 "<sqrt>",       0x221a  },
1.73      schwarze  235:        { "sqrt",               "<sqrt>",       0x221a  },
1.68      schwarze  236:        { "lc",                 "|~",           0x2308  },
                    237:        { "rc",                 "~|",           0x2309  },
                    238:        { "lf",                 "|_",           0x230a  },
                    239:        { "rf",                 "_|",           0x230b  },
1.72      schwarze  240:        { "if",                 "<infinity>",   0x221e  },
                    241:        { "Ah",                 "<Aleph>",      0x2135  },
                    242:        { "Im",                 "<Im>",         0x2111  },
                    243:        { "Re",                 "<Re>",         0x211c  },
1.75      schwarze  244:        { "wp",                 "p",            0x2118  },
1.72      schwarze  245:        { "pd",                 "<del>",        0x2202  },
1.68      schwarze  246:        { "-h",                 "/h",           0x210f  },
1.70      schwarze  247:        { "hbar",               "/h",           0x210f  },
1.68      schwarze  248:        { "12",                 "1/2",          0x00bd  },
                    249:        { "14",                 "1/4",          0x00bc  },
                    250:        { "34",                 "3/4",          0x00be  },
1.70      schwarze  251:        { "18",                 "1/8",          0x215B  },
                    252:        { "38",                 "3/8",          0x215C  },
                    253:        { "58",                 "5/8",          0x215D  },
                    254:        { "78",                 "7/8",          0x215E  },
1.72      schwarze  255:        { "S1",                 "^1",           0x00B9  },
                    256:        { "S2",                 "^2",           0x00B2  },
                    257:        { "S3",                 "^3",           0x00B3  },
1.68      schwarze  258:
                    259:        /* Ligatures. */
                    260:        { "ff",                 "ff",           0xfb00  },
                    261:        { "fi",                 "fi",           0xfb01  },
                    262:        { "fl",                 "fl",           0xfb02  },
                    263:        { "Fi",                 "ffi",          0xfb03  },
                    264:        { "Fl",                 "ffl",          0xfb04  },
                    265:        { "AE",                 "AE",           0x00c6  },
                    266:        { "ae",                 "ae",           0x00e6  },
                    267:        { "OE",                 "OE",           0x0152  },
                    268:        { "oe",                 "oe",           0x0153  },
                    269:        { "ss",                 "ss",           0x00df  },
                    270:        { "IJ",                 "IJ",           0x0132  },
                    271:        { "ij",                 "ij",           0x0133  },
                    272:
                    273:        /* Accents. */
                    274:        { "a\"",                "\"",           0x02dd  },
                    275:        { "a-",                 "-",            0x00af  },
                    276:        { "a.",                 ".",            0x02d9  },
                    277:        { "a^",                 "^",            0x005e  },
                    278:        { "aa",                 "\'",           0x00b4  },
                    279:        { "\'",                 "\'",           0x00b4  },
                    280:        { "ga",                 "`",            0x0060  },
                    281:        { "`",                  "`",            0x0060  },
                    282:        { "ab",                 "'\b`",         0x02d8  },
                    283:        { "ac",                 ",",            0x00b8  },
                    284:        { "ad",                 "\"",           0x00a8  },
                    285:        { "ah",                 "v",            0x02c7  },
                    286:        { "ao",                 "o",            0x02da  },
                    287:        { "a~",                 "~",            0x007e  },
                    288:        { "ho",                 ",",            0x02db  },
                    289:        { "ha",                 "^",            0x005e  },
                    290:        { "ti",                 "~",            0x007e  },
1.75      schwarze  291:        { "u02DC",              "~",            0x02dc  },
1.68      schwarze  292:
                    293:        /* Accented letters. */
                    294:        { "'A",                 "'\bA",         0x00c1  },
                    295:        { "'E",                 "'\bE",         0x00c9  },
                    296:        { "'I",                 "'\bI",         0x00cd  },
                    297:        { "'O",                 "'\bO",         0x00d3  },
                    298:        { "'U",                 "'\bU",         0x00da  },
1.75      schwarze  299:        { "'Y",                 "'\bY",         0x00dd  },
1.68      schwarze  300:        { "'a",                 "'\ba",         0x00e1  },
                    301:        { "'e",                 "'\be",         0x00e9  },
                    302:        { "'i",                 "'\bi",         0x00ed  },
                    303:        { "'o",                 "'\bo",         0x00f3  },
                    304:        { "'u",                 "'\bu",         0x00fa  },
1.75      schwarze  305:        { "'y",                 "'\by",         0x00fd  },
1.68      schwarze  306:        { "`A",                 "`\bA",         0x00c0  },
                    307:        { "`E",                 "`\bE",         0x00c8  },
                    308:        { "`I",                 "`\bI",         0x00cc  },
                    309:        { "`O",                 "`\bO",         0x00d2  },
                    310:        { "`U",                 "`\bU",         0x00d9  },
                    311:        { "`a",                 "`\ba",         0x00e0  },
                    312:        { "`e",                 "`\be",         0x00e8  },
                    313:        { "`i",                 "`\bi",         0x00ec  },
                    314:        { "`o",                 "`\bo",         0x00f2  },
                    315:        { "`u",                 "`\bu",         0x00f9  },
                    316:        { "~A",                 "~\bA",         0x00c3  },
                    317:        { "~N",                 "~\bN",         0x00d1  },
                    318:        { "~O",                 "~\bO",         0x00d5  },
                    319:        { "~a",                 "~\ba",         0x00e3  },
                    320:        { "~n",                 "~\bn",         0x00f1  },
                    321:        { "~o",                 "~\bo",         0x00f5  },
                    322:        { ":A",                 "\"\bA",        0x00c4  },
                    323:        { ":E",                 "\"\bE",        0x00cb  },
                    324:        { ":I",                 "\"\bI",        0x00cf  },
                    325:        { ":O",                 "\"\bO",        0x00d6  },
                    326:        { ":U",                 "\"\bU",        0x00dc  },
                    327:        { ":a",                 "\"\ba",        0x00e4  },
                    328:        { ":e",                 "\"\be",        0x00eb  },
                    329:        { ":i",                 "\"\bi",        0x00ef  },
                    330:        { ":o",                 "\"\bo",        0x00f6  },
                    331:        { ":u",                 "\"\bu",        0x00fc  },
                    332:        { ":y",                 "\"\by",        0x00ff  },
                    333:        { "^A",                 "^\bA",         0x00c2  },
                    334:        { "^E",                 "^\bE",         0x00ca  },
                    335:        { "^I",                 "^\bI",         0x00ce  },
                    336:        { "^O",                 "^\bO",         0x00d4  },
                    337:        { "^U",                 "^\bU",         0x00db  },
                    338:        { "^a",                 "^\ba",         0x00e2  },
                    339:        { "^e",                 "^\be",         0x00ea  },
                    340:        { "^i",                 "^\bi",         0x00ee  },
                    341:        { "^o",                 "^\bo",         0x00f4  },
                    342:        { "^u",                 "^\bu",         0x00fb  },
                    343:        { ",C",                 ",\bC",         0x00c7  },
                    344:        { ",c",                 ",\bc",         0x00e7  },
                    345:        { "/L",                 "/\bL",         0x0141  },
                    346:        { "/l",                 "/\bl",         0x0142  },
                    347:        { "/O",                 "/\bO",         0x00d8  },
                    348:        { "/o",                 "/\bo",         0x00f8  },
                    349:        { "oA",                 "o\bA",         0x00c5  },
                    350:        { "oa",                 "o\ba",         0x00e5  },
                    351:
                    352:        /* Special letters. */
1.72      schwarze  353:        { "-D",                 "Dh",           0x00d0  },
                    354:        { "Sd",                 "dh",           0x00f0  },
1.68      schwarze  355:        { "TP",                 "Th",           0x00de  },
                    356:        { "Tp",                 "th",           0x00fe  },
                    357:        { ".i",                 "i",            0x0131  },
                    358:        { ".j",                 "j",            0x0237  },
                    359:
                    360:        /* Currency. */
                    361:        { "Do",                 "$",            0x0024  },
                    362:        { "ct",                 "/\bc",         0x00a2  },
                    363:        { "Eu",                 "EUR",          0x20ac  },
                    364:        { "eu",                 "EUR",          0x20ac  },
                    365:        { "Ye",                 "=\bY",         0x00a5  },
1.76    ! schwarze  366:        { "Po",                 "-\bL",         0x00a3  },
1.68      schwarze  367:        { "Cs",                 "o\bx",         0x00a4  },
                    368:        { "Fn",                 ",\bf",         0x0192  },
                    369:
                    370:        /* Units. */
1.72      schwarze  371:        { "de",                 "<degree>",     0x00b0  },
                    372:        { "%0",                 "<permille>",   0x2030  },
1.68      schwarze  373:        { "fm",                 "\'",           0x2032  },
                    374:        { "sd",                 "''",           0x2033  },
1.72      schwarze  375:        { "mc",                 "<micro>",      0x00b5  },
1.70      schwarze  376:        { "Of",                 "_\ba",         0x00aa  },
                    377:        { "Om",                 "_\bo",         0x00ba  },
1.68      schwarze  378:
                    379:        /* Greek characters. */
                    380:        { "*A",                 "A",            0x0391  },
                    381:        { "*B",                 "B",            0x0392  },
1.72      schwarze  382:        { "*G",                 "<Gamma>",      0x0393  },
                    383:        { "*D",                 "<Delta>",      0x0394  },
1.68      schwarze  384:        { "*E",                 "E",            0x0395  },
                    385:        { "*Z",                 "Z",            0x0396  },
                    386:        { "*Y",                 "H",            0x0397  },
1.72      schwarze  387:        { "*H",                 "<Theta>",      0x0398  },
1.68      schwarze  388:        { "*I",                 "I",            0x0399  },
                    389:        { "*K",                 "K",            0x039a  },
1.72      schwarze  390:        { "*L",                 "<Lambda>",     0x039b  },
1.68      schwarze  391:        { "*M",                 "M",            0x039c  },
                    392:        { "*N",                 "N",            0x039d  },
1.72      schwarze  393:        { "*C",                 "<Xi>",         0x039e  },
1.68      schwarze  394:        { "*O",                 "O",            0x039f  },
1.72      schwarze  395:        { "*P",                 "<Pi>",         0x03a0  },
1.68      schwarze  396:        { "*R",                 "P",            0x03a1  },
1.72      schwarze  397:        { "*S",                 "<Sigma>",      0x03a3  },
1.68      schwarze  398:        { "*T",                 "T",            0x03a4  },
                    399:        { "*U",                 "Y",            0x03a5  },
1.72      schwarze  400:        { "*F",                 "<Phi>",        0x03a6  },
1.68      schwarze  401:        { "*X",                 "X",            0x03a7  },
1.72      schwarze  402:        { "*Q",                 "<Psi>",        0x03a8  },
                    403:        { "*W",                 "<Omega>",      0x03a9  },
                    404:        { "*a",                 "<alpha>",      0x03b1  },
                    405:        { "*b",                 "<beta>",       0x03b2  },
                    406:        { "*g",                 "<gamma>",      0x03b3  },
                    407:        { "*d",                 "<delta>",      0x03b4  },
                    408:        { "*e",                 "<epsilon>",    0x03b5  },
                    409:        { "*z",                 "<zeta>",       0x03b6  },
                    410:        { "*y",                 "<eta>",        0x03b7  },
                    411:        { "*h",                 "<theta>",      0x03b8  },
                    412:        { "*i",                 "<iota>",       0x03b9  },
                    413:        { "*k",                 "<kappa>",      0x03ba  },
                    414:        { "*l",                 "<lambda>",     0x03bb  },
                    415:        { "*m",                 "<mu>",         0x03bc  },
                    416:        { "*n",                 "<nu>",         0x03bd  },
                    417:        { "*c",                 "<xi>",         0x03be  },
1.68      schwarze  418:        { "*o",                 "o",            0x03bf  },
1.72      schwarze  419:        { "*p",                 "<pi>",         0x03c0  },
                    420:        { "*r",                 "<rho>",        0x03c1  },
                    421:        { "*s",                 "<sigma>",      0x03c3  },
                    422:        { "*t",                 "<tau>",        0x03c4  },
                    423:        { "*u",                 "<upsilon>",    0x03c5  },
                    424:        { "*f",                 "<phi>",        0x03d5  },
                    425:        { "*x",                 "<chi>",        0x03c7  },
                    426:        { "*q",                 "<psi>",        0x03c8  },
                    427:        { "*w",                 "<omega>",      0x03c9  },
                    428:        { "+h",                 "<theta>",      0x03d1  },
                    429:        { "+f",                 "<phi>",        0x03c6  },
                    430:        { "+p",                 "<pi>",         0x03d6  },
                    431:        { "+e",                 "<epsilon>",    0x03f5  },
                    432:        { "ts",                 "<sigma>",      0x03c2  },
1.1       kristaps  433: };
                    434:
1.68      schwarze  435: static struct ohash      mchars;
1.1       kristaps  436:
1.57      schwarze  437:
1.1       kristaps  438: void
1.68      schwarze  439: mchars_free(void)
1.1       kristaps  440: {
                    441:
1.68      schwarze  442:        ohash_delete(&mchars);
1.1       kristaps  443: }
                    444:
1.68      schwarze  445: void
1.38      kristaps  446: mchars_alloc(void)
1.1       kristaps  447: {
1.68      schwarze  448:        size_t            i;
                    449:        unsigned int      slot;
                    450:
                    451:        mandoc_ohash_init(&mchars, 9, offsetof(struct ln, roffcode));
                    452:        for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++) {
                    453:                slot = ohash_qlookup(&mchars, lines[i].roffcode);
                    454:                assert(ohash_find(&mchars, slot) == NULL);
                    455:                ohash_insert(&mchars, slot, lines + i);
1.1       kristaps  456:        }
                    457: }
                    458:
1.21      kristaps  459: int
1.68      schwarze  460: mchars_spec2cp(const char *p, size_t sz)
1.21      kristaps  461: {
                    462:        const struct ln *ln;
1.68      schwarze  463:        const char      *end;
1.21      kristaps  464:
1.68      schwarze  465:        end = p + sz;
                    466:        ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
1.67      schwarze  467:        return ln != NULL ? ln->unicode : sz == 1 ? (unsigned char)*p : -1;
1.21      kristaps  468: }
                    469:
1.65      schwarze  470: int
1.36      kristaps  471: mchars_num2char(const char *p, size_t sz)
1.32      schwarze  472: {
1.57      schwarze  473:        int       i;
1.32      schwarze  474:
1.65      schwarze  475:        i = mandoc_strntoi(p, sz, 10);
1.67      schwarze  476:        return i >= 0 && i < 256 ? i : -1;
1.44      kristaps  477: }
                    478:
                    479: int
                    480: mchars_num2uc(const char *p, size_t sz)
                    481: {
1.57      schwarze  482:        int      i;
1.39      kristaps  483:
1.63      schwarze  484:        i = mandoc_strntoi(p, sz, 16);
                    485:        assert(i >= 0 && i <= 0x10FFFF);
1.67      schwarze  486:        return i;
1.21      kristaps  487: }
                    488:
1.1       kristaps  489: const char *
1.68      schwarze  490: mchars_spec2str(const char *p, size_t sz, size_t *rsz)
1.1       kristaps  491: {
1.21      kristaps  492:        const struct ln *ln;
1.68      schwarze  493:        const char      *end;
1.1       kristaps  494:
1.68      schwarze  495:        end = p + sz;
                    496:        ln = ohash_find(&mchars, ohash_qlookupi(&mchars, p, &end));
1.60      schwarze  497:        if (ln == NULL) {
1.50      schwarze  498:                *rsz = 1;
1.67      schwarze  499:                return sz == 1 ? p : NULL;
1.50      schwarze  500:        }
1.21      kristaps  501:
1.24      kristaps  502:        *rsz = strlen(ln->ascii);
1.67      schwarze  503:        return ln->ascii;
1.61      schwarze  504: }
                    505:
                    506: const char *
                    507: mchars_uc2str(int uc)
                    508: {
1.68      schwarze  509:        size_t    i;
1.61      schwarze  510:
1.68      schwarze  511:        for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++)
1.61      schwarze  512:                if (uc == lines[i].unicode)
1.67      schwarze  513:                        return lines[i].ascii;
                    514:        return "<?>";
1.1       kristaps  515: }

CVSweb