The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

CharDatabaseParser.vala in /libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
Circle boundaries heads/master
1 /* 2 Copyright (C) 2013 2015 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Gee; 16 using Sqlite; 17 18 namespace BirdFont { 19 20 public class CharDatabaseParser : GLib.Object { 21 static unowned Database db; 22 static Database? database = null; 23 24 GlyphRange utf8 = new GlyphRange (); 25 26 public CharDatabaseParser () { 27 } 28 29 public File get_database_file () { 30 string? fn = BirdFont.get_argument ("--parse-ucd"); 31 32 if (fn != null && ((!) fn) != "") { 33 return File.new_for_path ((!) fn); 34 } 35 36 return File.new_for_path ("ucd.sqlite"); 37 } 38 39 public void regenerate_database () { 40 File f = get_database_file (); 41 42 stdout.printf ("Generating sqlite database in: %s\n", (!) f.get_path ()); 43 44 try { 45 if (f.query_exists ()) { 46 f.delete (); 47 } 48 49 open_database (OPEN_READWRITE); 50 create_tables (); 51 parse_all_entries (); 52 } catch (GLib.Error e) { 53 warning (e.message); 54 } 55 } 56 57 public void open_database (int access_mode) { 58 File f = get_database_file (); 59 int rc = Database.open_v2 ((!) f.get_path (), out database, access_mode); 60 61 db = (!) database; 62 63 if (rc != Sqlite.OK) { 64 stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ()); 65 } 66 } 67 68 public void create_tables () { 69 int ec; 70 string? errmsg; 71 string description_table = """ 72 CREATE TABLE Description ( 73 unicode INTEGER PRIMARY KEY NOT NULL, 74 description TEXT NOT NULL 75 ); 76 """; 77 78 ec = db.exec (description_table, null, out errmsg); 79 if (ec != Sqlite.OK) { 80 warning ("Error: %s\n", (!) errmsg); 81 } 82 83 string index_table = """ 84 CREATE TABLE Words ( 85 unicode INTEGER NOT NULL, 86 word TEXT NOT NULL 87 ); 88 """; 89 90 ec = db.exec (index_table, null, out errmsg); 91 if (ec != Sqlite.OK) { 92 warning ("Error: %s\n", (!) errmsg); 93 } 94 95 string create_index = "CREATE INDEX word_index ON Words (word);"; 96 97 ec = db.exec (create_index, null, out errmsg); 98 if (ec != Sqlite.OK) { 99 warning ("Error: %s\n", (!) errmsg); 100 } 101 } 102 103 public void insert_lookup (int64 character, string word) { 104 string? errmsg; 105 string w = word.down (); 106 string query = """ 107 INSERT INTO Words (unicode, word) 108 VALUES (""" + @"$((int64) character)" + """, '""" + w.replace ("'", "''") + "');"; 109 int ec = db.exec (query, null, out errmsg); 110 if (ec != Sqlite.OK) { 111 stderr.printf (query); 112 warning ("Error: %s\n", (!) errmsg); 113 } 114 } 115 116 public void insert_entry (int64 character, string description) { 117 string? errmsg; 118 string query = """ 119 INSERT INTO Description (unicode, description) 120 VALUES (""" + @"$((int64) character)" + """, '""" + description.replace ("'", "''") + "');"; 121 122 int ec = db.exec (query, null, out errmsg); 123 124 if (ec != Sqlite.OK) { 125 stderr.printf (query); 126 warning ("Error: %s\n", (!) errmsg); 127 warning (@"Can't insert description to: $(character)"); 128 } 129 } 130 131 private void add_entry (string data) { 132 string[] e; 133 string[] r; 134 string[] d; 135 string index_values; 136 unichar ch; 137 string unicode_hex; 138 139 if (data.has_prefix ("@")) { // ignore comments 140 return; 141 } 142 143 if (data.has_prefix (";")) { 144 return; 145 } 146 147 index_values = data.down (); 148 index_values = index_values.replace ("\n\tx", ""); 149 index_values = index_values.replace ("\n\t*", ""); 150 index_values = index_values.replace ("\n\t=", ""); 151 index_values = index_values.replace ("\n\t#", ""); 152 index_values = index_values.replace (" - ", " "); 153 index_values = index_values.replace ("(", ""); 154 index_values = index_values.replace (")", ""); 155 index_values = index_values.replace ("<font>", ""); 156 index_values = index_values.replace (" a ", " "); 157 index_values = index_values.replace (" is ", " "); 158 index_values = index_values.replace (" the ", " "); 159 160 e = index_values.split ("\t"); 161 162 return_if_fail (e.length > 0); 163 164 unicode_hex = e[0].up (); 165 166 ch = Font.to_unichar ("U+" + unicode_hex.down ()); 167 insert_entry ((int64) ch, data); 168 utf8.add_single (ch); 169 170 foreach (string s in e) { 171 r = s.split ("\n"); 172 foreach (string t in r) { 173 d = t.split (" "); 174 foreach (string token in d) { 175 if (token != "") { 176 insert_lookup ((int64) ch, token); 177 } 178 } 179 } 180 } 181 } 182 183 private void parse_all_entries () { 184 FileInputStream fin; 185 DataInputStream din; 186 string? line; 187 string data; 188 string description = ""; 189 File file; 190 int ec; 191 string? errmsg; 192 uint64 transaction_number = 0; 193 194 file = get_unicode_database (); 195 196 ec = db.exec ("BEGIN TRANSACTION", null, out errmsg); 197 if (ec != Sqlite.OK) { 198 warning ("Error: %s\n", (!) errmsg); 199 } 200 201 try { 202 fin = file.read (); 203 din = new DataInputStream (fin); 204 205 line = din.read_line (null); 206 while (true) { 207 data = (!) line; 208 description = data; 209 210 while ((line = din.read_line (null)) != null) { 211 data = (!) line; 212 if (data.has_prefix ("\t")) { 213 description += "\n"; 214 description += data; 215 } else { 216 if (description.index_of ("<not a character>") == -1) { 217 add_entry (description); 218 transaction_number++; 219 220 if (transaction_number >= 1000) { 221 ec = db.exec ("END TRANSACTION", null, out errmsg); 222 if (ec != Sqlite.OK) { 223 warning ("Error: %s\n", (!) errmsg); 224 } 225 226 ec = db.exec ("BEGIN TRANSACTION", null, out errmsg); 227 if (ec != Sqlite.OK) { 228 warning ("Error: %s\n", (!) errmsg); 229 } 230 231 transaction_number = 0; 232 } 233 } 234 break; 235 } 236 } 237 238 if (line == null) { 239 break; 240 } 241 } 242 243 if (description == "") { 244 warning ("no description found"); 245 } 246 247 fin.close (); 248 din.close (); 249 } catch (GLib.Error e) { 250 warning (e.message); 251 warning ("In %s", (!) get_unicode_database ().get_path ()); 252 } 253 254 ec = db.exec ("END TRANSACTION", null, out errmsg); 255 if (ec != Sqlite.OK) { 256 warning ("Error: %s\n", (!) errmsg); 257 } 258 259 stdout.printf ("Done"); 260 } 261 262 File get_unicode_database () { 263 return SearchPaths.get_char_database (); 264 } 265 } 266 267 } 268