Support for the FreeMonoTengwar font and ConScript encoding
[tengwarjs.git] / tengwar-parmaite.js
1
2 var Alphabet = require("./alphabet");
3 var Bindings = require("./dan-smith");
4 var makeFontColumn = require("./column");
5
6 var tengwar = exports.tengwar = Bindings.tengwar;
7 var tehtar = exports.tehtar = Bindings.tehtar;
8
9 var positions = exports.positions = {
10
11 "tinco": 2,
12 "parma": 2,
13 "calma": {
14 "y": 1,
15 "o-below": 1,
16 "others": 2
17 },
18 "quesse": {
19 "y": 1,
20 "o-below": 1,
21 "others": 2
22 },
23
24 "ando": {
25 "wide": true,
26 "others": 0
27 },
28 "umbar": {
29 "wide": true,
30 "others": 0
31 },
32 "anga": {
33 "wide": true,
34 "others": 0
35 },
36 "ungwe": {
37 "wide": true,
38 "others": 0
39 },
40
41 "thule": {
42 "a": 3,
43 "w": 3,
44 "others": 2
45 },
46 "formen": {
47 "a": 3,
48 "w": 3,
49 "í": 3,
50 "others": 2
51 },
52 "harma": {
53 "a": 0,
54 "e": 0,
55 "i": 1,
56 "o": 1,
57 "u": 1,
58 "w": 0,
59 "í": 0,
60 "others": 1
61 },
62 "hwesta": {
63 "a": 0,
64 "e": 0,
65 "i": 1,
66 "o": 1,
67 "u": 1,
68 "w": 0,
69 "others": 1
70 },
71
72 "anto": {
73 "wide": true,
74 "others": 0
75 },
76 "ampa": {
77 "wide": true,
78 "others": 0
79 },
80 "anca": {
81 "wide": true,
82 "others": 0
83 },
84 "unque": {
85 "wide": true,
86 "others": 0
87 },
88
89 "numen": {
90 "wide": true,
91 "others": 0
92 },
93 "malta": {
94 "wide": true,
95 "others": 0
96 },
97 "noldo": {
98 "wide": true,
99 "others": 0
100 },
101 "nwalme": {
102 "wide": true,
103 "others": 0
104 },
105
106 "ore": {
107 "a": 1,
108 "e": 2,
109 "i": 1,
110 "o": 2,
111 "u": 3,
112 "others": 1
113 },
114 "vala": {
115 "a": 1,
116 "e": 2,
117 "i": 2,
118 "o": 2,
119 "w": 1,
120 "y": 1,
121 "í": 2,
122 "i-below": 1,
123 "others": 3
124 },
125 "anna": {
126 "a": 1,
127 "w": 3,
128 "others": 2
129 },
130 "wilya": {
131 "i": 2,
132 "í": 2,
133 "others": 1
134 },
135
136 "romen": {
137 "a": 1,
138 "e": 1,
139 "i": 2,
140 "o": 1,
141 "u": 1,
142 "y": 3,
143 "o-below": null,
144 "i-below": 3,
145 "others": 1
146 },
147 "arda": {
148 "a": 1,
149 "e": 1,
150 "i": 2,
151 "o": 1,
152 "u": 1,
153 "w": 1,
154 "í": 2,
155 "y": 3,
156 "o-below": null,
157 "i-below": 3,
158 "others": 0
159 },
160 "lambe": {
161 "wide": true,
162 "e": 1,
163 "y": 4,
164 "w": 0,
165 "o-below": null,
166 "i-below": 4,
167 "others": 0
168 },
169 "alda": {
170 "wide": true,
171 "w": 0,
172 "y": null,
173 "o-below": null,
174 "i-below": null,
175 "others": 1
176 },
177
178 "silme": {
179 "y": 2,
180 "o-below": 2,
181 "i-below": 2,
182 "others": null
183 },
184 "silme-nuquerna": {
185 "e": 2,
186 "y": null,
187 "o-below": null,
188 "i-below": null,
189 "others": 1
190 },
191 "esse": {
192 "others": null
193 },
194 "esse-nuquerna": {
195 "e": 2,
196 "y": null,
197 "o-below": null,
198 "i-below": null,
199 "others": 1
200 },
201
202 "hyarmen": {
203 "y": 1,
204 "o-below": 1,
205 "i-below": 1,
206 "others": 3
207 },
208 "hwesta-sindarinwa": {
209 "w": 1,
210 "y": 1,
211 "o-below": 1,
212 "i-below": 1,
213 "others": 0
214 },
215 "yanta": {
216 "a": 1,
217 "others": 2
218 },
219 "ure": {
220 "a": 1,
221 "others": 2
222 },
223
224 "halla": {
225 "i-below": 3,
226 "o-below": 3,
227 "others": null
228 },
229 "short-carrier": {
230 "y": null,
231 "others": 3
232 },
233 "long-carrier": {
234 "y": null,
235 "o-below": null,
236 "i-below": null,
237 "others": 3
238 },
239 "round-carrier": 2,
240
241 "tinco-extended": {
242 "a": 3,
243 "w": 3,
244 "y": 3,
245 "í": 3,
246 "o-below": 3,
247 "others": 2
248 },
249 "parma-extended": {
250 "a": 3,
251 "w": 3,
252 "y": 3,
253 "í": 3,
254 "o-below": 3,
255 "others": 2
256 },
257 "calma-extended": {
258 "i": 1,
259 "w": 1,
260 "y": 0,
261 "í": 0,
262 "i-below": 1,
263 "o-below": 1,
264 "others": 0
265 },
266 "quesse-extended": {
267 "i": 1,
268 "w": 1,
269 "y": 0,
270 "í": 0,
271 "i-below": 1,
272 "o-below": 1,
273 "others": 0
274 },
275
276 "ando-extended": {
277 "wide": true,
278 "others": 0
279 },
280 "umbar-extended": {
281 "wide": true,
282 "others": 0
283 },
284 "anga-extended": {
285 "wide": true,
286 "others": 0
287 },
288 "ungwe-extended": {
289 "wide": true,
290 "others": 0
291 }
292
293 };
294
295 exports.transcribe = transcribe;
296 function transcribe(sections, options) {
297 options = options || {};
298 var block = options.block || false;
299 var beginParagraph = block ? "<p>" : "";
300 var delimitParagraph = "<br>";
301 var endParagraph = block ? "</p>" : "";
302 return sections.map(function (section) {
303 return section.map(function (paragraph) {
304 return beginParagraph + paragraph.map(function (line) {
305 return line.map(function (word) {
306 return word.map(function (column) {
307 return transcribeColumn(column, options);
308 }).join("");
309 }).join(" ");;
310 }).join(delimitParagraph + "\n") + endParagraph;
311 }).join("\n\n");
312 }).join("\n\n\n");
313 }
314
315 exports.transcribeColumn = transcribeColumn;
316 function transcribeColumn(column, options) {
317 options = options || {};
318 var plain = options.plain || false;
319 var tengwa = column.tengwa || "anna";
320 var tehtar = [];
321 if (column.above) tehtar.push(column.above);
322 if (column.below) tehtar.push(column.below);
323 if (column.tildeBelow) tehtar.push("tilde-below");
324 if (column.tildeAbove) tehtar.push("tilde-above");
325 if (column.following) tehtar.push(column.following);
326 var html = tengwar[tengwa] + tehtar.map(function (tehta) {
327 return tehtaForTengwa(tengwa, tehta);
328 }).join("");
329 if (column.errors && !plain) {
330 html = "<abbr class=\"error\" title=\"" + column.errors.join("\n").replace(/"/g, "&quot;") + "\">" + html + "</abbr>";
331 }
332 return html;
333 }
334
335 exports.tehtaForTengwa = tehtaForTengwa;
336 function tehtaForTengwa(tengwa, tehta) {
337 var tehtaKey = tehtaKeyForTengwa(tengwa, tehta);
338 if (tehtaKey == null)
339 return null;
340 return (
341 tehtar[tehta][tengwa] ||
342 tehtar[tehta][tehtaKey] ||
343 null
344 );
345 }
346
347 var longVowels = "áéóú";
348 function tehtaKeyForTengwa(tengwa, tehta) {
349 if (!tehtar[tehta])
350 return null;
351 if (longVowels.indexOf(tehta) !== -1)
352 return null;
353 if (tehtar[tehta].special)
354 return tehtar[tehta][tengwa] || null;
355 if (Alphabet.barsAndTildes.indexOf(tehta) !== -1) {
356 if (tengwa === "lambe" || tengwa === "alda" && tehtar[tehta].length >= 2)
357 return 2;
358 return positions[tengwa].wide ? 0 : 1;
359 }
360 if (positions[tengwa] == null)
361 return null;
362 if (positions[tengwa][tehta] === null)
363 return null;
364 if (positions[tengwa][tehta] != null)
365 return positions[tengwa][tehta];
366 if (positions[tengwa].others != null)
367 return positions[tengwa].others;
368 return positions[tengwa];
369 }
370
371 exports.makeColumn = makeColumn;
372 function makeColumn(tengwa, tengwarFrom) {
373 return makeFontColumn(exports, tengwa, tengwarFrom);
374 }
375