]> git.kianting.info Git - clo/blob - src/libclo/index.js
english breakline, and generate try to count the text size
[clo] / src / libclo / index.js
1 "use strict";
2 Object.defineProperty(exports, "__esModule", { value: true });
3 exports.Clo = exports.calculateTextWidthHeight = exports.hyphenTkTree = exports.filterEmptyString = exports.spacesToBreakpoint = exports.hyphenForClo = exports.splitCJKV = exports.twoReturnsToNewline = exports.ptToPx = exports.cjkvRegexPattern = exports.cjkvBlocksInRegex = exports.defaultFrameStyle = exports.defaultTextStyle = exports.A4_IN_PX = exports.Direction = void 0;
4 const canva_1 = require("../canva");
5 const jsdom_1 = require("jsdom");
6 /**
7 * TYPES
8 */
9 /**
10 * text direction
11 * LTR - left to right
12 * TTB - top to bottom
13 * etc.
14 */
15 var Direction;
16 (function (Direction) {
17 Direction[Direction["LTR"] = 0] = "LTR";
18 Direction[Direction["RTL"] = 1] = "RTL";
19 Direction[Direction["TTB"] = 2] = "TTB";
20 Direction[Direction["BTT"] = 3] = "BTT";
21 })(Direction || (exports.Direction = Direction = {}));
22 /**
23 * DEFAULT CONST PART
24 */
25 exports.A4_IN_PX = { "width": 793.7,
26 "height": 1122.5 };
27 exports.defaultTextStyle = {
28 family: "FreeSerif",
29 size: ptToPx(12),
30 textWeight: canva_1.TextWeight.REGULAR,
31 fontStyle: canva_1.FontStyle.ITALIC,
32 };
33 exports.defaultFrameStyle = {
34 directionInsideLine: Direction.LTR,
35 direction: Direction.TTB,
36 baseLineskip: ptToPx(15),
37 textStyle: exports.defaultTextStyle,
38 x: exports.A4_IN_PX.width * 0.10,
39 y: exports.A4_IN_PX.height * 0.10,
40 width: exports.A4_IN_PX.width * 0.80,
41 height: exports.A4_IN_PX.height * 0.80,
42 content: null,
43 };
44 /**
45 * definition for cjk scripts
46 * - Hani : Han Character
47 * - Hang : Hangul
48 * - Bopo : Bopomofo
49 * - Kana : Katakana
50 * - Hira : Hiragana
51 */
52 exports.cjkvBlocksInRegex = ["Hani", "Hang", "Bopo", "Kana", "Hira"];
53 exports.cjkvRegexPattern = new RegExp("((?:" +
54 exports.cjkvBlocksInRegex.map((x) => "\\p{Script_Extensions=" + x + "}").join("|") + ")+)", "gu");
55 /**
56 * FUNCTION PART
57 */
58 /**
59 * convert from ptToPx
60 * @param pt pt size value
61 * @returns the corresponding px value
62 */
63 function ptToPx(pt) {
64 return pt * 4.0 / 3.0;
65 }
66 exports.ptToPx = ptToPx;
67 /**
68 * REGISTER PART
69 */
70 /**
71 * convert '\n\n' to newline command ["nl"]
72 * @param arr the input `tkTree`
73 * @param clo the `Clo` object
74 * @returns the input tktree
75 */
76 function twoReturnsToNewline(arr, clo) {
77 var middle = [];
78 for (let i = 0; i < arr.length; i++) {
79 var item = arr[i];
80 if (!Array.isArray(item)) {
81 middle = middle.concat(item.split(/(\n\n)/g));
82 }
83 else {
84 middle.push(item);
85 }
86 }
87 var result = [];
88 for (let j = 0; j < middle.length; j++) {
89 var item = middle[j];
90 if (!Array.isArray(item) && item == "\n\n") {
91 result.push(["nl"]); // push a newline command to the result `tkTree`
92 }
93 else {
94 result.push(middle[j]);
95 }
96 }
97 return result;
98 }
99 exports.twoReturnsToNewline = twoReturnsToNewline;
100 /**
101 * split CJKV and non-CJKV
102 *
103 * @param arr : input tkTree
104 * @returns a splitted tkTree (by CJK and NonCJK)
105 * - Examples:
106 * ```
107 * [`many臺中daylight`] => [`many`, `臺中`, `dahylight`]
108 * ```
109 */
110 function splitCJKV(arr, clo) {
111 var result = [];
112 for (let i = 0; i < arr.length; i++) {
113 var item = arr[i];
114 if (!Array.isArray(item)) {
115 result = result.concat(item.split(exports.cjkvRegexPattern));
116 }
117 else {
118 result.push(item);
119 }
120 }
121 return result;
122 }
123 exports.splitCJKV = splitCJKV;
124 /**
125 * hyphenation for a clo document
126 * @param arr the array for a `tkTree`
127 * @param clo the Clo object
128 */
129 function hyphenForClo(arr, clo) {
130 let hyphenLanguage = clo.attrs["hyphenLanguage"];
131 let res = hyphenTkTree(arr, hyphenLanguage);
132 return res;
133 }
134 exports.hyphenForClo = hyphenForClo;
135 /**
136 * convert spaces to Breakpoint
137 * \s+ => ["bp" [\s+] ""]
138 * @param arr the tkTree input text stream
139 * @param clo the Clo object
140 * @returns the converted object
141 */
142 function spacesToBreakpoint(arr, clo) {
143 let spacePattern = /^([ \t]+)$/g;
144 var result = [];
145 for (let i = 0; i < arr.length; i++) {
146 var item = arr[i];
147 if (!Array.isArray(item) && item.match(spacePattern)) {
148 result.push(['bp', item, ""]); // push a newline command to the result `tkTree`
149 }
150 else {
151 result.push(item);
152 }
153 }
154 return result;
155 }
156 exports.spacesToBreakpoint = spacesToBreakpoint;
157 /**
158 * remove all the `` (empty string) in the arr
159 * @param arr the tkTree to be filtered
160 * @param clo the Clo file
161 */
162 function filterEmptyString(arr, clo) {
163 if (Array.isArray(arr)) {
164 arr.filter((x) => { return x != ``; });
165 }
166 return arr;
167 }
168 exports.filterEmptyString = filterEmptyString;
169 /**
170 * OTHER FUNCTIONS
171 */
172 /**
173 * hyphenate for a tkTree
174 * - hyphenation => ["bp", "", "-"]
175 * @param arr the tkTree array
176 * @param lang ISO 639 code for the language
177 */
178 function hyphenTkTree(arr, lang) {
179 // import corresponding hyphen language data and function
180 let hyphen = require("hyphen/" + lang);
181 let result = [];
182 for (let i = 0; i < arr.length; i++) {
183 let element = arr[i];
184 let splitter = "分"; // a CJKV
185 if (!Array.isArray(element)) {
186 let hyphenatedElement = hyphen.hyphenateSync(element, { hyphenChar: splitter });
187 let hyphenatedSplitted = hyphenatedElement.split(splitter);
188 var newSplitted = [];
189 for (var j = 0; j < hyphenatedSplitted.length - 1; j++) {
190 newSplitted.push(hyphenatedSplitted[j]);
191 // "bp" for breakpoint
192 newSplitted.push(["bp", "", "-"]); //insert a breakable point (bp) mark
193 }
194 newSplitted.push(hyphenatedSplitted[hyphenatedSplitted.length - 1]);
195 result = result.concat(newSplitted);
196 }
197 else {
198 result.push(element);
199 }
200 }
201 return result;
202 }
203 exports.hyphenTkTree = hyphenTkTree;
204 /**
205 * calculate the text width and Height with a given `TextStyle`
206 * @param preprocessed
207 * @param defaultFontStyle
208 */
209 function calculateTextWidthHeight(preprocessed, style) {
210 var dom = new jsdom_1.JSDOM(`<!DOCTYPE html><html><head></head>
211 <body><canvas id="canvas"></canvas></body></html>`);
212 try {
213 let canvas = dom.window.document.getElementById("canvas");
214 console.log(canvas);
215 /*if (!(canvas instanceof HTMLElement)){
216 throw new Error('the <canvas="canvas"> in the jsdom\'s DOM is not found.');
217
218 }*/
219 let context = canvas.getContext("2d");
220 console.log(context);
221 if (context == null) {
222 throw new Error('`canvas.getContext("2d");` can\'t be executed.');
223 }
224 context.font = `normal normal 10pt ${style.family}`;
225 console.log(context.font);
226 let txt = `Hello john`;
227 console.log(txt);
228 let measured = context.measureText(txt);
229 let width = measured.width;
230 let height = measured.actualBoundingBoxAscent;
231 let depth = measured.actualBoundingBoxDescent;
232 console.log("width: " + width);
233 console.log("height: " + height);
234 console.log("depth: " + depth);
235 }
236 catch (error) {
237 console.log("Exception " + error);
238 }
239 }
240 exports.calculateTextWidthHeight = calculateTextWidthHeight;
241 /**
242 * whole document-representing class
243 */
244 class Clo {
245 constructor() {
246 this.preprocessors = [];
247 this.mainStream = [];
248 this.attrs = {
249 "page": exports.A4_IN_PX,
250 "defaultFrameStyle": exports.defaultFrameStyle,
251 "hyphenLanguage": 'en' // hyphenated in the language (in ISO 639)
252 };
253 // register the precessor functions
254 this.preprocessorRegister(splitCJKV);
255 this.preprocessorRegister(hyphenForClo);
256 this.preprocessorRegister(twoReturnsToNewline);
257 this.preprocessorRegister(spacesToBreakpoint);
258 this.preprocessorRegister(filterEmptyString);
259 }
260 setAttr(attr, val) {
261 Object.assign(this.attrs, attr, val);
262 }
263 getAttr(attr) {
264 if (Object.keys(this.attrs).length === 0) {
265 return this.attrs[attr];
266 }
267 else {
268 return undefined;
269 }
270 }
271 /**
272 * register a function of preprocessor
273 * @param f a function
274 */
275 preprocessorRegister(f) {
276 this.preprocessors.push(f);
277 }
278 generatePdf() {
279 // preprocessed
280 var preprocessed = this.mainStream;
281 for (var i = 0; i < this.preprocessors.length; i++) {
282 preprocessed = this.preprocessors[i](preprocessed, this);
283 }
284 // generate the width and height of the stream
285 let defaultFontStyle = this.attrs["defaultFrameStyle"].textStyle;
286 calculateTextWidthHeight(preprocessed, defaultFontStyle);
287 // TODO
288 console.log(preprocessed);
289 }
290 }
291 exports.Clo = Clo;
292 /*
293 export let a = new Clo();
294 export default a; */