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
Fix translation heads/master
1 /* 2 Copyright (C) 2013 2015 2018 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 ("Please use the other script.\n"); 43 stdout.printf ("Generating sqlite database in: %s\n", (!) f.get_path ()); 44 45 try { 46 if (f.query_exists ()) { 47 f.delete (); 48 } 49 50 bool open = open_database (OPEN_READWRITE | OPEN_CREATE); 51 52 if (open) { 53 create_tables (); 54 parse_all_entries (); 55 } 56 } catch (GLib.Error e) { 57 warning (e.message); 58 } 59 } 60 61 public bool open_database (int access_mode) { 62 File f = get_database_file (); 63 int rc = Database.open_v2 ((!) f.get_path (), out database, access_mode); 64 65 db = (!) database; 66 67 if (rc != Sqlite.OK) { 68 stderr.printf ("File: %s\n", (!) f.get_path ()); 69 stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ()); 70 return false; 71 } 72 73 return true; 74 } 75 76 public void create_tables () { 77 int ec; 78 string? errmsg; 79 string description_table = """ 80 CREATE TABLE Description ( 81 unicode INTEGER PRIMARY KEY NOT NULL, 82 description TEXT NOT NULL 83 ); 84 """; 85 86 ec = db.exec (description_table, null, out errmsg); 87 if (ec != Sqlite.OK) { 88 warning ("Error: %s\n", (!) errmsg); 89 } 90 91 string index_table = """ 92 CREATE TABLE Words ( 93 unicode INTEGER NOT NULL, 94 word TEXT NOT NULL 95 ); 96 """; 97 98 ec = db.exec (index_table, null, out errmsg); 99 if (ec != Sqlite.OK) { 100 warning ("Error: %s\n", (!) errmsg); 101 } 102 103 string create_index = "CREATE INDEX word_index ON Words (word);"; 104 105 ec = db.exec (create_index, null, out errmsg); 106 if (ec != Sqlite.OK) { 107 warning ("Error: %s\n", (!) errmsg); 108 } 109 } 110 111 public void insert_lookup (int64 character, string word) { 112 string? errmsg; 113 string w = word.down (); 114 string query = """ 115 INSERT INTO Words (unicode, word) 116 VALUES (""" + @"$((int64) character)" + """, '""" + w.replace ("'", "''") + "');"; 117 int ec = db.exec (query, null, out errmsg); 118 119 if (ec != Sqlite.OK) { 120 stderr.printf (query); 121 warning ("Error: %s\n", (!) errmsg); 122 } 123 } 124 125 /** medial, isolated etc. */ 126 public string get_context_substitution (string description) { 127 string[] lines = description.split ("\n"); 128 return_val_if_fail (lines.length > 0, "NONE"); 129 130 string first_line = lines[0]; 131 string type = "NONE"; 132 133 if (first_line.has_suffix ("INITIAL FORM")) { 134 type = "INITIAL"; 135 } else if (first_line.has_suffix ("MEDIAL FORM")) { 136 type = "MEDIAL"; 137 } else if (first_line.has_suffix ("FINAL FORM")) { 138 type = "FINAL"; 139 } else if (first_line.has_suffix ("ISOLATED FORM")) { 140 type = "ISOLATED"; 141 } 142 143 return type; 144 } 145 146 public string get_name (string description) { 147 string[] lines = description.split ("\n"); 148 return_val_if_fail (lines.length > 0, "NONE"); 149 150 string first_line = lines[0]; 151 int separator = first_line.index_of ("\t"); 152 string name = first_line.substring (separator + "\t".length); 153 return name.strip (); 154 } 155 156 157 public void insert_entry (int64 character, string description) { 158 string? errmsg; 159 160 string query = """ 161 INSERT INTO Description (unicode, description) 162 VALUES (""" + @"$((int64) character)" + ", " 163 + "'" + description.replace ("'", "''") + "');"; 164 165 int ec = db.exec (query, null, out errmsg); 166 167 if (ec != Sqlite.OK) { 168 stderr.printf (query); 169 warning ("Error: %s\n", (!) errmsg); 170 warning (@"Can't insert description to: $(character)"); 171 } 172 } 173 174 private void add_entry (string data) { 175 string[] e; 176 string[] r; 177 string[] d; 178 string index_values; 179 unichar ch; 180 string unicode_hex; 181 182 if (data.has_prefix ("@")) { // ignore comments 183 return; 184 } 185 186 if (data.has_prefix (";")) { 187 return; 188 } 189 190 index_values = data.down (); 191 index_values = index_values.replace ("\n\tx", ""); 192 index_values = index_values.replace ("\n\t*", ""); 193 index_values = index_values.replace ("\n\t=", ""); 194 index_values = index_values.replace ("\n\t#", ""); 195 index_values = index_values.replace (",", " "); 196 index_values = index_values.replace (" - ", " "); 197 index_values = index_values.replace ("(", ""); 198 index_values = index_values.replace (")", ""); 199 index_values = index_values.replace ("<font>", ""); 200 index_values = index_values.replace (" a ", " "); 201 index_values = index_values.replace (" is ", " "); 202 index_values = index_values.replace (" the ", " "); 203 204 e = index_values.split ("\t"); 205 206 return_if_fail (e.length > 0); 207 208 unicode_hex = e[0].up (); 209 210 ch = Font.to_unichar ("U+" + unicode_hex.down ()); 211 insert_entry ((int64) ch, data); 212 utf8.add_single (ch); 213 214 foreach (string s in e) { 215 r = s.split ("\n"); 216 217 foreach (string t in r) { 218 if (!t.has_prefix ("\t~")) { 219 d = t.split (" "); 220 foreach (string token in d) { 221 if (token != "") { 222 insert_lookup ((int64) ch, token); 223 } 224 } 225 } 226 } 227 } 228 } 229 230 private void parse_all_entries () { 231 FileInputStream fin; 232 DataInputStream din; 233 string? line; 234 string data; 235 string description = ""; 236 File file; 237 int ec; 238 string? errmsg; 239 uint64 transaction_number = 0; 240 241 file = get_unicode_database (); 242 243 ec = db.exec ("BEGIN TRANSACTION", null, out errmsg); 244 if (ec != Sqlite.OK) { 245 warning ("Error: %s\n", (!) errmsg); 246 } 247 248 try { 249 fin = file.read (); 250 din = new DataInputStream (fin); 251 252 line = din.read_line (null); 253 while (true) { 254 data = (!) line; 255 description = data; 256 257 while ((line = din.read_line (null)) != null) { 258 data = (!) line; 259 if (data.has_prefix ("\t")) { 260 description += "\n"; 261 description += data; 262 } else { 263 if (description.index_of ("<not a character>") == -1) { 264 add_entry (description); 265 transaction_number++; 266 267 if (transaction_number >= 1000) { 268 ec = db.exec ("END TRANSACTION", null, out errmsg); 269 if (ec != Sqlite.OK) { 270 warning ("Error: %s\n", (!) errmsg); 271 } 272 273 ec = db.exec ("BEGIN TRANSACTION", null, out errmsg); 274 if (ec != Sqlite.OK) { 275 warning ("Error: %s\n", (!) errmsg); 276 } 277 278 transaction_number = 0; 279 } 280 } 281 break; 282 } 283 } 284 285 if (line == null) { 286 break; 287 } 288 } 289 290 if (description == "") { 291 warning ("no description found"); 292 } 293 294 fin.close (); 295 din.close (); 296 } catch (GLib.Error e) { 297 warning (e.message); 298 warning ("In %s", (!) get_unicode_database ().get_path ()); 299 } 300 301 ec = db.exec ("END TRANSACTION", null, out errmsg); 302 if (ec != Sqlite.OK) { 303 warning ("Error: %s\n", (!) errmsg); 304 } 305 306 stdout.printf ("Done"); 307 } 308 309 File get_unicode_database () { 310 return SearchPaths.get_char_database (); 311 } 312 } 313 314 } 315