english breakline, and generate try to count the text size
This commit is contained in:
		
							parent
							
								
									796e0c20c7
								
							
						
					
					
						commit
						c3dc58d74a
					
				
					 80 changed files with 7617 additions and 1631 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -3,3 +3,4 @@ node_modules | |||
| /tests/*.js | ||||
| .vscode | ||||
| activate.sh | ||||
| docs/.nojekyll | ||||
|  |  | |||
							
								
								
									
										17
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								README.md
									
									
									
									
									
								
							|  | @ -1,7 +1,8 @@ | |||
| # clo | ||||
| another personal draught of a typesetting language and engine. | ||||
| website: https://kianting.info/wiki/w/Project:Clo | ||||
| License: MIT  | ||||
|  - another personal draught of a typesetting language and engine. | ||||
|  - website: https://kianting.info/wiki/w/Project:Clo | ||||
|  - license: MIT  | ||||
|  - issue tracking mailing list: `clo@kianting.info` | ||||
| 
 | ||||
| ## changing journal | ||||
|  - 20230904 建立 thenDo、matchRange的函數、refactor harfbuzzjs 以及libpdf 等測試界面 | ||||
|  | @ -31,6 +32,7 @@ License: MIT | |||
|  - 20231023-24:fix .ttc bug. | ||||
|  - 20231026-27 : clo basic interface, preprocessor of stream of text, | ||||
|   add cjk-english splitter, etc. | ||||
|  - 20231029: hyphenating for english. | ||||
| 
 | ||||
|  ## 之後的做法 | ||||
|   - 先做一個前處理註冊器,註冊下列的前處理 | ||||
|  | @ -43,15 +45,20 @@ License: MIT | |||
|     - 然後算出每個Box的x, y, page | ||||
|     - 最後納入排版 | ||||
| 
 | ||||
| ## 排版語法: | ||||
| ## 排版語法 | ||||
| 
 | ||||
| 使用lisp表示,但其實是陣列 | ||||
| ```lisp | ||||
|   (hglue 寬度 伸展值) | ||||
|   (vglue 高度 伸展值) | ||||
|   (breakpoint 原始模式 斷行模式) | ||||
|   (bp 原始模式 斷行模式) ; breakpoint | ||||
|   (nl) ; newline | ||||
|   (em 數字) | ||||
|   (ex 數字) | ||||
|   (span {"font-family" : "Noto Sans" , "font-size" : 16 }) | ||||
|   (vbox 高度 內容) | ||||
| ``` | ||||
| 
 | ||||
| ## How to generate documents | ||||
|  - `typedoc /path/to/index.js [/path/to/index2.js ...]` | ||||
| the generated page will be stored in `/src`. | ||||
							
								
								
									
										12
									
								
								b.clo
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								b.clo
									
									
									
									
									
								
							|  | @ -1,4 +1,12 @@ | |||
| --- | ||||
| many臺中daylight | ||||
| The  book of the generation of Jesus Christ, the son of David, the son of Abraham.  | ||||
| 
 | ||||
| aaa collee | ||||
| Abraham begat Isaac; and Isaac begat Jacob; and Jacob begat Judas and his brethren;  And Judas begat Phares and Zara of Thamar; and Phares begat Esrom; and Esrom begat Aram;  And Aram begat Aminadab; and Aminadab begat Naasson; and Naasson begat Salmon;  And Salmon begat Booz of Rachab; and Booz begat Obed of Ruth; and Obed begat Jesse;  And Jesse begat David the king; | ||||
| 
 | ||||
| and David the king begat Solomon of her that had been the wife of Urias;  And Solomon begat Roboam; and Roboam begat Abia; and Abia begat Asa;  And Asa begat Josaphat; and Josaphat begat Joram; and Joram begat Ozias;  And Ozias begat Joatham; and Joatham begat Achaz; and Achaz begat Ezekias;  And Ezekias begat Manasses; and Manasses begat Amon; and Amon begat Josias;  And Josias begat Jechonias and his brethren, about the time they were carried away to Babylon:  And after they were brought to Babylon, Jechonias begat Salathiel; and Salathiel begat Zorobabel;  And Zorobabel begat Abiud; and Abiud begat Eliakim; and Eliakim begat Azor;  And Azor begat Sadoc; and Sadoc begat Achim; and Achim begat Eliud;  And Eliud begat Eleazar; and Eleazar begat Matthan; and Matthan begat Jacob;  And Jacob begat Joseph the husband of Mary, of whom was born Jesus, who is called Christ. | ||||
| 
 | ||||
| So all the generations from Abraham to David are fourteen generations; and from David until the carrying away into Babylon are fourteen generations; and from the carrying away into Babylon unto Christ are fourteen generations. | ||||
|    | ||||
| Now the birth of Jesus Christ was on this wise: When as his mother Mary was espoused to Joseph, before they came together, she was found with child of the Holy Ghost.  Then Joseph her husband, being a just man, and not willing to make her a publick example, was minded to put her away privily.  But while he thought on these things, behold, the angel of the Lord appeared unto him in a dream, saying, Joseph, thou son of David, fear not to take unto thee Mary thy wife: for that which is conceived in her is of the Holy Ghost.  And she shall bring forth a son, and thou shalt call his name JESUS: for he shall save his people from their sins.  Now all this was done, that it might be fulfilled which was spoken of the Lord by the prophet, saying,  Behold, a virgin shall be with child, and shall bring forth a son, and they shall call his name Emmanuel, which being interpreted is, God with us. | ||||
| 
 | ||||
| Then Joseph being raised from sleep did as the angel of the Lord had bidden him, and took unto him his wife:  And knew her not till she had brought forth her firstborn son: and he called his name JESUS.   Now when Jesus was born in Bethlehem of Judaea in the days of Herod the king, behold, there came wise men from the east to Jerusalem,  Saying, Where is he that is born King of the Jews?  | ||||
							
								
								
									
										13
									
								
								b.js
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								b.js
									
									
									
									
									
								
							|  | @ -9,10 +9,17 @@ let clo = new cloLib.Clo(); | |||
| 
 | ||||
| /* CLO:  beginning of middle part*/ | ||||
| clo.mainStream = /* CLO: end of middle part*/ | ||||
| [` | ||||
| `, `many臺中daylight`, ` | ||||
| [`The`, `  `, `book`, ` `, `of`, ` `, `the`, ` `, `generation`, ` `, `of`, ` `, `Jesus`, ` `, `Christ,`, ` `, `the`, ` `, `son`, ` `, `of`, ` `, `David,`, ` `, `the`, ` `, `son`, ` `, `of`, ` `, `Abraham.`, ` 
 | ||||
| 
 | ||||
| `, `aaa`, ` `, `collee`];
 | ||||
| `, `Abraham`, ` `, `begat`, ` `, `Isaac`, `;`, ` `, `and`, ` `, `Isaac`, ` `, `begat`, ` `, `Jacob`, `;`, ` `, `and`, ` `, `Jacob`, ` `, `begat`, ` `, `Judas`, ` `, `and`, ` `, `his`, ` `, `brethren`, `;`, `  `, `And`, ` `, `Judas`, ` `, `begat`, ` `, `Phares`, ` `, `and`, ` `, `Zara`, ` `, `of`, ` `, `Thamar`, `;`, ` `, `and`, ` `, `Phares`, ` `, `begat`, ` `, `Esrom`, `;`, ` `, `and`, ` `, `Esrom`, ` `, `begat`, ` `, `Aram`, `;`, `  `, `And`, ` `, `Aram`, ` `, `begat`, ` `, `Aminadab`, `;`, ` `, `and`, ` `, `Aminadab`, ` `, `begat`, ` `, `Naasson`, `;`, ` `, `and`, ` `, `Naasson`, ` `, `begat`, ` `, `Salmon`, `;`, `  `, `And`, ` `, `Salmon`, ` `, `begat`, ` `, `Booz`, ` `, `of`, ` `, `Rachab`, `;`, ` `, `and`, ` `, `Booz`, ` `, `begat`, ` `, `Obed`, ` `, `of`, ` `, `Ruth`, `;`, ` `, `and`, ` `, `Obed`, ` `, `begat`, ` `, `Jesse`, `;`, `  `, `And`, ` `, `Jesse`, ` `, `begat`, ` `, `David`, ` `, `the`, ` `, `king`, `;`, ` | ||||
| 
 | ||||
| `, `and`, ` `, `David`, ` `, `the`, ` `, `king`, ` `, `begat`, ` `, `Solomon`, ` `, `of`, ` `, `her`, ` `, `that`, ` `, `had`, ` `, `been`, ` `, `the`, ` `, `wife`, ` `, `of`, ` `, `Urias`, `;`, `  `, `And`, ` `, `Solomon`, ` `, `begat`, ` `, `Roboam`, `;`, ` `, `and`, ` `, `Roboam`, ` `, `begat`, ` `, `Abia`, `;`, ` `, `and`, ` `, `Abia`, ` `, `begat`, ` `, `Asa`, `;`, `  `, `And`, ` `, `Asa`, ` `, `begat`, ` `, `Josaphat`, `;`, ` `, `and`, ` `, `Josaphat`, ` `, `begat`, ` `, `Joram`, `;`, ` `, `and`, ` `, `Joram`, ` `, `begat`, ` `, `Ozias`, `;`, `  `, `And`, ` `, `Ozias`, ` `, `begat`, ` `, `Joatham`, `;`, ` `, `and`, ` `, `Joatham`, ` `, `begat`, ` `, `Achaz`, `;`, ` `, `and`, ` `, `Achaz`, ` `, `begat`, ` `, `Ezekias`, `;`, `  `, `And`, ` `, `Ezekias`, ` `, `begat`, ` `, `Manasses`, `;`, ` `, `and`, ` `, `Manasses`, ` `, `begat`, ` `, `Amon`, `;`, ` `, `and`, ` `, `Amon`, ` `, `begat`, ` `, `Josias`, `;`, `  `, `And`, ` `, `Josias`, ` `, `begat`, ` `, `Jechonias`, ` `, `and`, ` `, `his`, ` `, `brethren,`, ` `, `about`, ` `, `the`, ` `, `time`, ` `, `they`, ` `, `were`, ` `, `carried`, ` `, `away`, ` `, `to`, ` `, `Babylon:`, `  `, `And`, ` `, `after`, ` `, `they`, ` `, `were`, ` `, `brought`, ` `, `to`, ` `, `Babylon,`, ` `, `Jechonias`, ` `, `begat`, ` `, `Salathiel`, `;`, ` `, `and`, ` `, `Salathiel`, ` `, `begat`, ` `, `Zorobabel`, `;`, `  `, `And`, ` `, `Zorobabel`, ` `, `begat`, ` `, `Abiud`, `;`, ` `, `and`, ` `, `Abiud`, ` `, `begat`, ` `, `Eliakim`, `;`, ` `, `and`, ` `, `Eliakim`, ` `, `begat`, ` `, `Azor`, `;`, `  `, `And`, ` `, `Azor`, ` `, `begat`, ` `, `Sadoc`, `;`, ` `, `and`, ` `, `Sadoc`, ` `, `begat`, ` `, `Achim`, `;`, ` `, `and`, ` `, `Achim`, ` `, `begat`, ` `, `Eliud`, `;`, `  `, `And`, ` `, `Eliud`, ` `, `begat`, ` `, `Eleazar`, `;`, ` `, `and`, ` `, `Eleazar`, ` `, `begat`, ` `, `Matthan`, `;`, ` `, `and`, ` `, `Matthan`, ` `, `begat`, ` `, `Jacob`, `;`, `  `, `And`, ` `, `Jacob`, ` `, `begat`, ` `, `Joseph`, ` `, `the`, ` `, `husband`, ` `, `of`, ` `, `Mary,`, ` `, `of`, ` `, `whom`, ` `, `was`, ` `, `born`, ` `, `Jesus,`, ` `, `who`, ` `, `is`, ` `, `called`, ` `, `Christ.`, ` | ||||
| 
 | ||||
| `, `So`, ` `, `all`, ` `, `the`, ` `, `generations`, ` `, `from`, ` `, `Abraham`, ` `, `to`, ` `, `David`, ` `, `are`, ` `, `fourteen`, ` `, `generations`, `;`, ` `, `and`, ` `, `from`, ` `, `David`, ` `, `until`, ` `, `the`, ` `, `carrying`, ` `, `away`, ` `, `into`, ` `, `Babylon`, ` `, `are`, ` `, `fourteen`, ` `, `generations`, `;`, ` `, `and`, ` `, `from`, ` `, `the`, ` `, `carrying`, ` `, `away`, ` `, `into`, ` `, `Babylon`, ` `, `unto`, ` `, `Christ`, ` `, `are`, ` `, `fourteen`, ` `, `generations.`, ` | ||||
|    | ||||
| `, `Now`, ` `, `the`, ` `, `birth`, ` `, `of`, ` `, `Jesus`, ` `, `Christ`, ` `, `was`, ` `, `on`, ` `, `this`, ` `, `wise:`, ` `, `When`, ` `, `as`, ` `, `his`, ` `, `mother`, ` `, `Mary`, ` `, `was`, ` `, `espoused`, ` `, `to`, ` `, `Joseph,`, ` `, `before`, ` `, `they`, ` `, `came`, ` `, `together,`, ` `, `she`, ` `, `was`, ` `, `found`, ` `, `with`, ` `, `child`, ` `, `of`, ` `, `the`, ` `, `Holy`, ` `, `Ghost.`, `  `, `Then`, ` `, `Joseph`, ` `, `her`, ` `, `husband,`, ` `, `being`, ` `, `a`, ` `, `just`, ` `, `man,`, ` `, `and`, ` `, `not`, ` `, `willing`, ` `, `to`, ` `, `make`, ` `, `her`, ` `, `a`, ` `, `publick`, ` `, `example,`, ` `, `was`, ` `, `minded`, ` `, `to`, ` `, `put`, ` `, `her`, ` `, `away`, ` `, `privily.`, `  `, `But`, ` `, `while`, ` `, `he`, ` `, `thought`, ` `, `on`, ` `, `these`, ` `, `things,`, ` `, `behold,`, ` `, `the`, ` `, `angel`, ` `, `of`, ` `, `the`, ` `, `Lord`, ` `, `appeared`, ` `, `unto`, ` `, `him`, ` `, `in`, ` `, `a`, ` `, `dream,`, ` `, `saying,`, ` `, `Joseph,`, ` `, `thou`, ` `, `son`, ` `, `of`, ` `, `David,`, ` `, `fear`, ` `, `not`, ` `, `to`, ` `, `take`, ` `, `unto`, ` `, `thee`, ` `, `Mary`, ` `, `thy`, ` `, `wife:`, ` `, `for`, ` `, `that`, ` `, `which`, ` `, `is`, ` `, `conceived`, ` `, `in`, ` `, `her`, ` `, `is`, ` `, `of`, ` `, `the`, ` `, `Holy`, ` `, `Ghost.`, `  `, `And`, ` `, `she`, ` `, `shall`, ` `, `bring`, ` `, `forth`, ` `, `a`, ` `, `son,`, ` `, `and`, ` `, `thou`, ` `, `shalt`, ` `, `call`, ` `, `his`, ` `, `name`, ` `, `JESUS:`, ` `, `for`, ` `, `he`, ` `, `shall`, ` `, `save`, ` `, `his`, ` `, `people`, ` `, `from`, ` `, `their`, ` `, `sins.`, `  `, `Now`, ` `, `all`, ` `, `this`, ` `, `was`, ` `, `done,`, ` `, `that`, ` `, `it`, ` `, `might`, ` `, `be`, ` `, `fulfilled`, ` `, `which`, ` `, `was`, ` `, `spoken`, ` `, `of`, ` `, `the`, ` `, `Lord`, ` `, `by`, ` `, `the`, ` `, `prophet,`, ` `, `saying,`, `  `, `Behold,`, ` `, `a`, ` `, `virgin`, ` `, `shall`, ` `, `be`, ` `, `with`, ` `, `child,`, ` `, `and`, ` `, `shall`, ` `, `bring`, ` `, `forth`, ` `, `a`, ` `, `son,`, ` `, `and`, ` `, `they`, ` `, `shall`, ` `, `call`, ` `, `his`, ` `, `name`, ` `, `Emmanuel,`, ` `, `which`, ` `, `being`, ` `, `interpreted`, ` `, `is,`, ` `, `God`, ` `, `with`, ` `, `us.`, ` | ||||
| 
 | ||||
| `, `Then`, ` `, `Joseph`, ` `, `being`, ` `, `raised`, ` `, `from`, ` `, `sleep`, ` `, `did`, ` `, `as`, ` `, `the`, ` `, `angel`, ` `, `of`, ` `, `the`, ` `, `Lord`, ` `, `had`, ` `, `bidden`, ` `, `him,`, ` `, `and`, ` `, `took`, ` `, `unto`, ` `, `him`, ` `, `his`, ` `, `wife:`, `  `, `And`, ` `, `knew`, ` `, `her`, ` `, `not`, ` `, `till`, ` `, `she`, ` `, `had`, ` `, `brought`, ` `, `forth`, ` `, `her`, ` `, `firstborn`, ` `, `son:`, ` `, `and`, ` `, `he`, ` `, `called`, ` `, `his`, ` `, `name`, ` `, `JESUS.`, `   `, `Now`, ` `, `when`, ` `, `Jesus`, ` `, `was`, ` `, `born`, ` `, `in`, ` `, `Bethlehem`, ` `, `of`, ` `, `Judaea`, ` `, `in`, ` `, `the`, ` `, `days`, ` `, `of`, ` `, `Herod`, ` `, `the`, ` `, `king,`, ` `, `behold,`, ` `, `there`, ` `, `came`, ` `, `wise`, ` `, `men`, ` `, `from`, ` `, `the`, ` `, `east`, ` `, `to`, ` `, `Jerusalem,`, `  `, `Saying,`, ` `, `Where`, ` `, `is`, ` `, `he`, ` `, `that`, ` `, `is`, ` `, `born`, ` `, `King`, ` `, `of`, ` `, `the`, ` `, `Jews?`, ` `];
 | ||||
| /* CLO: beginning of end part*/ | ||||
| clo.generatePdf(); | ||||
| /*CLO : end of end part*/ | ||||
|  |  | |||
							
								
								
									
										78
									
								
								docs/assets/highlight.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								docs/assets/highlight.css
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,78 @@ | |||
| :root { | ||||
|     --light-hl-0: #000000; | ||||
|     --dark-hl-0: #C8C8C8; | ||||
|     --light-hl-1: #000000; | ||||
|     --dark-hl-1: #D4D4D4; | ||||
|     --light-hl-2: #001080; | ||||
|     --dark-hl-2: #9CDCFE; | ||||
|     --light-hl-3: #A31515; | ||||
|     --dark-hl-3: #CE9178; | ||||
|     --light-hl-4: #0070C1; | ||||
|     --dark-hl-4: #4FC1FF; | ||||
|     --light-hl-5: #008000; | ||||
|     --dark-hl-5: #6A9955; | ||||
|     --light-hl-6: #0000FF; | ||||
|     --dark-hl-6: #569CD6; | ||||
|     --light-hl-7: #098658; | ||||
|     --dark-hl-7: #B5CEA8; | ||||
|     --light-code-background: #FFFFFF; | ||||
|     --dark-code-background: #1E1E1E; | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: light) { :root { | ||||
|     --hl-0: var(--light-hl-0); | ||||
|     --hl-1: var(--light-hl-1); | ||||
|     --hl-2: var(--light-hl-2); | ||||
|     --hl-3: var(--light-hl-3); | ||||
|     --hl-4: var(--light-hl-4); | ||||
|     --hl-5: var(--light-hl-5); | ||||
|     --hl-6: var(--light-hl-6); | ||||
|     --hl-7: var(--light-hl-7); | ||||
|     --code-background: var(--light-code-background); | ||||
| } } | ||||
| 
 | ||||
| @media (prefers-color-scheme: dark) { :root { | ||||
|     --hl-0: var(--dark-hl-0); | ||||
|     --hl-1: var(--dark-hl-1); | ||||
|     --hl-2: var(--dark-hl-2); | ||||
|     --hl-3: var(--dark-hl-3); | ||||
|     --hl-4: var(--dark-hl-4); | ||||
|     --hl-5: var(--dark-hl-5); | ||||
|     --hl-6: var(--dark-hl-6); | ||||
|     --hl-7: var(--dark-hl-7); | ||||
|     --code-background: var(--dark-code-background); | ||||
| } } | ||||
| 
 | ||||
| :root[data-theme='light'] { | ||||
|     --hl-0: var(--light-hl-0); | ||||
|     --hl-1: var(--light-hl-1); | ||||
|     --hl-2: var(--light-hl-2); | ||||
|     --hl-3: var(--light-hl-3); | ||||
|     --hl-4: var(--light-hl-4); | ||||
|     --hl-5: var(--light-hl-5); | ||||
|     --hl-6: var(--light-hl-6); | ||||
|     --hl-7: var(--light-hl-7); | ||||
|     --code-background: var(--light-code-background); | ||||
| } | ||||
| 
 | ||||
| :root[data-theme='dark'] { | ||||
|     --hl-0: var(--dark-hl-0); | ||||
|     --hl-1: var(--dark-hl-1); | ||||
|     --hl-2: var(--dark-hl-2); | ||||
|     --hl-3: var(--dark-hl-3); | ||||
|     --hl-4: var(--dark-hl-4); | ||||
|     --hl-5: var(--dark-hl-5); | ||||
|     --hl-6: var(--dark-hl-6); | ||||
|     --hl-7: var(--dark-hl-7); | ||||
|     --code-background: var(--dark-code-background); | ||||
| } | ||||
| 
 | ||||
| .hl-0 { color: var(--hl-0); } | ||||
| .hl-1 { color: var(--hl-1); } | ||||
| .hl-2 { color: var(--hl-2); } | ||||
| .hl-3 { color: var(--hl-3); } | ||||
| .hl-4 { color: var(--hl-4); } | ||||
| .hl-5 { color: var(--hl-5); } | ||||
| .hl-6 { color: var(--hl-6); } | ||||
| .hl-7 { color: var(--hl-7); } | ||||
| pre, code { background: var(--code-background); } | ||||
							
								
								
									
										59
									
								
								docs/assets/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								docs/assets/main.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								docs/assets/navigation.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/assets/navigation.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA42XW0/bMBSA/0ue0TYYsI230gZWoGnUZAMJocqkbuPVsaPEKa2m/fe5iZM6t+M8leZ8/hpfzvHh9a8l8F5YN1aA2A5ZZ1aMRCi/RnyVUZx+zh9/CkVEZWxL2Mq6uTizgpDQVYKZdfNaCXz54YkDxScJZllUKqpwXfb931nN8IzJJhT9iiLe7xhTfhpMmMDJGgXVPGS0MZer6/rgMY8iJCOgQ0GQ6o6z5mq0TBUDidYScqXA9RwUYReRBDC2YUjtTu4mPMgizLQFF4e40mlAw/Plx7fzq4vG3nkiwSj6xUiPrs6YjOtydXx+/POkXGcsEIQzfdIaWPdeX2rKOBPHd+hXKaCleNMk8hnetxMlfzwoUUJM4wlOg5NjhxKC3jWLIuq6r/rqxAmX256Oks2uazqFR4PAKVHyHuh5U86peD5oUhOS4Py3m6mrHFV8YOoGFKXp6RVaiXt+oQ+95fvOrFCjZRjM1UQmi0FRMpBndLmcOkv3pWtjlaZEgJ0N/mx3t5QH23TKFnijn7WWrsUavDkjC4ScHTNodRSwrvAaZVTky9Oody1tizV7Oy6VPm3PBVOzhoc4xOyOJ7Wzdkqb8sBrGFBOCszf+gnGRluBQcVJ+NzdA54CAAxpTIkYPzz+BiQVA3jEB19gkSUs9bmDPyhh0PQ6aLDYxChJcdIuNsXzYa0G32L2SPRruig2ylHF+4uNaOxacU+p8aJjr9oX1Hju+Lbjd51M5VEEcCCnM3e+gBQFYDTYttFh20aLZ5R4gMOZ+8sRNJcCMBqWvv1i1uQU4HIX83tAcgwDoz37fgbvrSJAx2w6nj/NHdCiGMBD8V7Pl5YjjwPjeSZkX2Pr2dJyVIzR8xMjs+gIGU0zslp1F/aaq8AAG4pjeji25Li7S1Q2HQOKn8JkAzDElmMm2zSKeWKUFdQwVzpMlppsDhej3pZY91WgyeiiAW+XQ4NMz0SE8hgMW8H2CNNveHgz5NQozGyLyJhTvQfu8ynQaIxlD+o8GX0FZrIN2WjDHhOm/kXyeV/Xo2wNEmo3ZNjnDx4gK5GOxuLtPxjWUt7DEAAA" | ||||
							
								
								
									
										1
									
								
								docs/assets/search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/assets/search.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1383
									
								
								docs/assets/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1383
									
								
								docs/assets/style.css
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										185
									
								
								docs/classes/libclo.Clo.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								docs/classes/libclo.Clo.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										80
									
								
								docs/enums/canva.TextStyle.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								docs/enums/canva.TextStyle.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										73
									
								
								docs/enums/canva.TextWeight.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								docs/enums/canva.TextWeight.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										94
									
								
								docs/enums/libclo.Direction.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								docs/enums/libclo.Direction.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										136
									
								
								docs/enums/parser.TokenKind.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								docs/enums/parser.TokenKind.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										62
									
								
								docs/functions/canva.fontStyleTofont.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								docs/functions/canva.fontStyleTofont.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										84
									
								
								docs/functions/canva.putText.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								docs/functions/canva.putText.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										60
									
								
								docs/functions/index.processArgv.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								docs/functions/index.processArgv.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										66
									
								
								docs/functions/libclo.hyphenForClo.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								docs/functions/libclo.hyphenForClo.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										66
									
								
								docs/functions/libclo.hyphenTkTree.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								docs/functions/libclo.hyphenTkTree.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										62
									
								
								docs/functions/libclo.ptToPx.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								docs/functions/libclo.ptToPx.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										69
									
								
								docs/functions/libclo.splitCJKV.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								docs/functions/libclo.splitCJKV.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										60
									
								
								docs/functions/libclo.twoReturnsToNewline.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								docs/functions/libclo.twoReturnsToNewline.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyComment.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyComment.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyContent.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyContent.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyImport.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyImport.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyImports.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyImports.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyNotAtText.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyNotAtText.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										57
									
								
								docs/functions/parser.applyParts.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								docs/functions/parser.applyParts.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyPartsWithoutImport.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyPartsWithoutImport.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applySegment.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applySegment.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applySemiColon.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applySemiColon.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applySpaceNL.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applySpaceNL.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/functions/parser.applyText.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/functions/parser.applyText.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										58
									
								
								docs/functions/parser.inputTextToTree.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								docs/functions/parser.inputTextToTree.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										58
									
								
								docs/functions/parser.treeToJS.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								docs/functions/parser.treeToJS.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										109
									
								
								docs/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								docs/index.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										88
									
								
								docs/interfaces/canva.Clo.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								docs/interfaces/canva.Clo.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										77
									
								
								docs/interfaces/canva.CloCommand.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								docs/interfaces/canva.CloCommand.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										106
									
								
								docs/interfaces/canva.FontStyle.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								docs/interfaces/canva.FontStyle.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										77
									
								
								docs/interfaces/canva.fontPathPSNamePair.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								docs/interfaces/canva.fontPathPSNamePair.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										118
									
								
								docs/interfaces/libclo.Box.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								docs/interfaces/libclo.Box.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										143
									
								
								docs/interfaces/libclo.FrameBox.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								docs/interfaces/libclo.FrameBox.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										69
									
								
								docs/modules/canva.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								docs/modules/canva.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/modules/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/modules/index.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										76
									
								
								docs/modules/libclo.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								docs/modules/libclo.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										87
									
								
								docs/modules/parser.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								docs/modules/parser.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/types/canva.PDFDocument.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/types/canva.PDFDocument.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/types/canva.TextStreamUnit.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/types/canva.TextStreamUnit.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										67
									
								
								docs/types/parser.tkTree.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								docs/types/parser.tkTree.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										49
									
								
								docs/variables/index.helpDesc.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/variables/index.helpDesc.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										56
									
								
								docs/variables/libclo.A4_IN_PX.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docs/variables/libclo.A4_IN_PX.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										56
									
								
								docs/variables/libclo.cjkvBlocksInRegex.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docs/variables/libclo.cjkvBlocksInRegex.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/libclo.cjkvRegexPattern.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/libclo.cjkvRegexPattern.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/libclo.defaultFrameStyle.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/libclo.defaultFrameStyle.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/libclo.defaultTextStyle.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/libclo.defaultTextStyle.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.CONTENT.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.CONTENT.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.IMPORT.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.IMPORT.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										49
									
								
								docs/variables/parser.IMPORTEE.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/variables/parser.IMPORTEE.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.IMPORTS.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.IMPORTS.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.NOT_AT.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.NOT_AT.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.NOT_AT_TEXT.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.NOT_AT_TEXT.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								docs/variables/parser.PROG.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/variables/parser.PROG.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.SEGMENT.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.SEGMENT.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										46
									
								
								docs/variables/parser.SEMICOLON.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/variables/parser.SEMICOLON.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										49
									
								
								docs/variables/parser.lexer.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/variables/parser.lexer.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										49
									
								
								docs/variables/parser.outputEnd.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/variables/parser.outputEnd.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										49
									
								
								docs/variables/parser.outputHead.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/variables/parser.outputHead.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										49
									
								
								docs/variables/parser.outputMiddle.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/variables/parser.outputMiddle.html
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3043
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3043
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										12
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								package.json
									
									
									
									
									
								
							|  | @ -9,7 +9,7 @@ | |||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "git+https://github.com/Yoxem/clo.git" | ||||
|     "url": "git+https://git.kianting.info/src/clo" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "typesetting" | ||||
|  | @ -17,11 +17,12 @@ | |||
|   "author": "Tan Kian-ting", | ||||
|   "license": "MIT", | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/Yoxem/clo/issues" | ||||
|     "url": "https://kianting.info/wiki/w/Project:Clo#Discussion" | ||||
|   }, | ||||
|   "homepage": "https://github.com/Yoxem/clo#readme", | ||||
|   "homepage": "https://kianting.info/wiki/w/Project:Clo", | ||||
|   "devDependencies": { | ||||
|     "@types/chai": "^4.3.5", | ||||
|     "@types/jsdom": "^21.1.4", | ||||
|     "@types/mocha": "^10.0.1", | ||||
|     "@types/node": "^20.8.4", | ||||
|     "@types/pdfkit": "^0.13.1", | ||||
|  | @ -36,10 +37,13 @@ | |||
|     "nyc": "^15.1.0", | ||||
|     "ts-node": "^10.9.1", | ||||
|     "tslint": "^6.1.3", | ||||
|     "typedoc": "^0.25.2", | ||||
|     "typescript": "^5.2.2" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "harfbuzzjs": "^0.3.3", | ||||
|     "canvas": "^2.11.2", | ||||
|     "hyphen": "^1.7.0", | ||||
|     "jsdom": "^22.1.0", | ||||
|     "minimist": "^1.2.8", | ||||
|     "npx": "^10.2.2", | ||||
|     "pdfkit": "^0.13.0", | ||||
|  |  | |||
							
								
								
									
										20
									
								
								src/canva.ts
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/canva.ts
									
									
									
									
									
								
							|  | @ -23,16 +23,16 @@ export interface Clo{ | |||
| 
 | ||||
| /** | ||||
|  * Font Style Interface | ||||
|  * family : eg. "FreeSans" | ||||
|  * size : in px, not in pt. | ||||
|  * textWeight : TextWeight.REGULAR ,etc | ||||
|  * textWeight : TextStyle.ITALIC ,etc | ||||
|  * - family : eg. "FreeSans" | ||||
|  * - size : in px, not in pt. | ||||
|  * - textWeight : TextWeight.REGULAR ,etc | ||||
|  * - fontStyle : FontStyle.ITALIC ,etc | ||||
|  */ | ||||
| export interface FontStyle{ | ||||
| export interface TextStyle{ | ||||
|     family : string, | ||||
|     size : number,  | ||||
|     textWeight : TextWeight, | ||||
|     textStyle : TextStyle, | ||||
|     fontStyle : FontStyle, | ||||
|     color? : string, | ||||
| }; | ||||
| 
 | ||||
|  | @ -41,7 +41,7 @@ export enum TextWeight { | |||
|     BOLD, | ||||
|   }; | ||||
| 
 | ||||
| export enum TextStyle{ | ||||
| export enum FontStyle{ | ||||
|     NORMAL, | ||||
|     ITALIC, | ||||
|     OBLIQUE, | ||||
|  | @ -57,10 +57,10 @@ export interface fontPathPSNamePair{ | |||
|  * @param style the font style | ||||
|  * @returns pair of the font path and postscript name. | ||||
|  */ | ||||
| export function fontStyleTofont(style : FontStyle) : fontPathPSNamePair{ | ||||
| export function fontStyleTofont(style : TextStyle) : fontPathPSNamePair{ | ||||
|     try { | ||||
|         let fcMatchCommand = `fc-match "${style.family}":${TextWeight[style.textWeight]}:`+ | ||||
|         `${TextStyle[style.textStyle]}` +` postscriptname file`; | ||||
|         `${FontStyle[style.fontStyle]}` +` postscriptname file`; | ||||
| 
 | ||||
|         let fcMatchOut = execSync(fcMatchCommand); | ||||
|         let matched = fcMatchOut | ||||
|  | @ -93,7 +93,7 @@ export function fontStyleTofont(style : FontStyle) : fontPathPSNamePair{ | |||
|  * @param y base y-point from top | ||||
|  * @returns a new updated clo object | ||||
|  */ | ||||
| export async function putText(clo : Clo, str : string, sty : FontStyle, | ||||
| export async function putText(clo : Clo, str : string, sty : TextStyle, | ||||
|     pageNo : number, x : number, y : number): Promise<Clo>{ | ||||
| 
 | ||||
|     let fontInfo = fontStyleTofont(sty); | ||||
|  |  | |||
|  | @ -23,10 +23,14 @@ var __importStar = (this && this.__importStar) || function (mod) { | |||
|     return result; | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.processArgv = exports.helpDesc = void 0; | ||||
| var fs = require('fs'); | ||||
| var argv = require('minimist')(process.argv.slice(2)); | ||||
| const parser = __importStar(require("./parser.js")); | ||||
| let helpDesc = ` | ||||
| /** | ||||
|  * help for inputing `--help` parameter. | ||||
|  */ | ||||
| exports.helpDesc = ` | ||||
| clo: clo INPUT_FILE --output-js OUTPUT_JS_FILE | ||||
| 
 | ||||
| \ta little typesetter powered by TypeScript/Javascript. | ||||
|  | @ -42,7 +46,7 @@ INPUT_FILE\tan input .clo file | |||
| Report bugs to: clo@kianting.info | ||||
| clo home page: <https://kianting.info/wiki/w/Project:Clo>
 | ||||
| `;
 | ||||
| processArgv(argv, helpDesc); | ||||
| processArgv(argv, exports.helpDesc); | ||||
| /** | ||||
|  * processing the passed `argv` (arguments) | ||||
|  */ | ||||
|  | @ -72,3 +76,4 @@ function processArgv(argv, helpDesc) { | |||
|         }); | ||||
|     } | ||||
| } | ||||
| exports.processArgv = processArgv; | ||||
|  |  | |||
|  | @ -3,8 +3,10 @@ var argv : any = require('minimist')(process.argv.slice(2)); | |||
| 
 | ||||
| import * as parser from "./parser.js"; | ||||
| 
 | ||||
| 
 | ||||
| let helpDesc = | ||||
| /** | ||||
|  * help for inputing `--help` parameter. | ||||
|  */ | ||||
| export let helpDesc = | ||||
| ` | ||||
| clo: clo INPUT_FILE --output-js OUTPUT_JS_FILE | ||||
| 
 | ||||
|  | @ -28,7 +30,7 @@ processArgv(argv, helpDesc); | |||
|  * processing the passed `argv` (arguments) | ||||
|  */ | ||||
| 
 | ||||
| function processArgv(argv : any, helpDesc : string){ | ||||
| export function processArgv(argv : any, helpDesc : string){ | ||||
|     let inputFile : string[] = argv['_']; | ||||
|     let outputJSFile : string | true = argv['output-js']; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.a = exports.Clo = void 0; | ||||
| 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; | ||||
| const canva_1 = require("../canva"); | ||||
| const jsdom_1 = require("jsdom"); | ||||
| /** | ||||
|  * TYPES | ||||
|  */ | ||||
|  | @ -17,32 +18,40 @@ var Direction; | |||
|     Direction[Direction["RTL"] = 1] = "RTL"; | ||||
|     Direction[Direction["TTB"] = 2] = "TTB"; | ||||
|     Direction[Direction["BTT"] = 3] = "BTT"; | ||||
| })(Direction || (Direction = {})); | ||||
| })(Direction || (exports.Direction = Direction = {})); | ||||
| /** | ||||
|  * DEFAULT CONST PART | ||||
|  */ | ||||
| const A4_IN_PX = { "width": 793.7, | ||||
| exports.A4_IN_PX = { "width": 793.7, | ||||
|     "height": 1122.5 }; | ||||
| const defaultTextStyle = { | ||||
|     family: "FreeSans", | ||||
|     size: 12, | ||||
| exports.defaultTextStyle = { | ||||
|     family: "FreeSerif", | ||||
|     size: ptToPx(12), | ||||
|     textWeight: canva_1.TextWeight.REGULAR, | ||||
|     textStyle: canva_1.TextStyle.ITALIC, | ||||
|     fontStyle: canva_1.FontStyle.ITALIC, | ||||
| }; | ||||
| const defaultFrameStyle = { | ||||
| exports.defaultFrameStyle = { | ||||
|     directionInsideLine: Direction.LTR, | ||||
|     direction: Direction.TTB, | ||||
|     baseLineskip: ptToPx(15), | ||||
|     fontStyle: defaultTextStyle, | ||||
|     x: A4_IN_PX.width * 0.10, | ||||
|     y: A4_IN_PX.height * 0.10, | ||||
|     width: A4_IN_PX.width * 0.80, | ||||
|     height: A4_IN_PX.height * 0.80, | ||||
|     textStyle: exports.defaultTextStyle, | ||||
|     x: exports.A4_IN_PX.width * 0.10, | ||||
|     y: exports.A4_IN_PX.height * 0.10, | ||||
|     width: exports.A4_IN_PX.width * 0.80, | ||||
|     height: exports.A4_IN_PX.height * 0.80, | ||||
|     content: null, | ||||
| }; | ||||
| const cjkvBlocksInRegex = ["Hani"]; | ||||
| const cjkvRegexPattern = new RegExp("((?:" + | ||||
|     cjkvBlocksInRegex.map((x) => "\\p{Script_Extensions=" + x + "}").join("|") + ")+)", "gu"); | ||||
| /** | ||||
|  * definition for cjk scripts | ||||
|  *  - Hani : Han Character | ||||
|  *  - Hang : Hangul | ||||
|  *  - Bopo : Bopomofo | ||||
|  *  - Kana : Katakana | ||||
|  *  - Hira : Hiragana | ||||
| */ | ||||
| exports.cjkvBlocksInRegex = ["Hani", "Hang", "Bopo", "Kana", "Hira"]; | ||||
| exports.cjkvRegexPattern = new RegExp("((?:" + | ||||
|     exports.cjkvBlocksInRegex.map((x) => "\\p{Script_Extensions=" + x + "}").join("|") + ")+)", "gu"); | ||||
| /** | ||||
|  * FUNCTION PART | ||||
|  */ | ||||
|  | @ -52,47 +61,208 @@ const cjkvRegexPattern = new RegExp("((?:" + | |||
|  * @returns the corresponding px value | ||||
|  */ | ||||
| function ptToPx(pt) { | ||||
|     return pt * 4 / 3.0; | ||||
|     return pt * 4.0 / 3.0; | ||||
| } | ||||
| exports.ptToPx = ptToPx; | ||||
| /** | ||||
|  *  REGISTER PART | ||||
|  */ | ||||
| /** | ||||
|  * convert '\n\n' to newline command ["nl"] | ||||
|  * @param arr the input `tkTree` | ||||
|  * @param clo the `Clo` object | ||||
|  * @returns the input tktree | ||||
|  */ | ||||
| function twoReturnsToNewline(arr, clo) { | ||||
|     var middle = []; | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         var item = arr[i]; | ||||
|         if (!Array.isArray(item)) { | ||||
|             middle = middle.concat(item.split(/(\n\n)/g)); | ||||
|         } | ||||
|         else { | ||||
|             middle.push(item); | ||||
|         } | ||||
|     } | ||||
|     var result = []; | ||||
|     for (let j = 0; j < middle.length; j++) { | ||||
|         var item = middle[j]; | ||||
|         if (!Array.isArray(item) && item == "\n\n") { | ||||
|             result.push(["nl"]); // push a newline command to the result `tkTree`
 | ||||
|         } | ||||
|         else { | ||||
|             result.push(middle[j]); | ||||
|         } | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| exports.twoReturnsToNewline = twoReturnsToNewline; | ||||
| /** | ||||
|  * split CJKV and non-CJKV | ||||
|  * | ||||
|  * @param arr : input tkTree | ||||
|  * @returns | ||||
|  * @returns a splitted tkTree (by CJK and NonCJK) | ||||
|  * - Examples: | ||||
|  *  ``` | ||||
|  *  [`many臺中daylight`] => [`many`, `臺中`, `dahylight`] | ||||
|  *  ``` | ||||
|  */ | ||||
| function splitCJKV(arr) { | ||||
|     console.log(arr); | ||||
| function splitCJKV(arr, clo) { | ||||
|     var result = []; | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         var item = arr[i]; | ||||
|         if (!Array.isArray(item)) { | ||||
|             console.log(item.split(cjkvRegexPattern)); | ||||
|             result = result.concat(item.split(cjkvRegexPattern)); | ||||
|             result = result.concat(item.split(exports.cjkvRegexPattern)); | ||||
|         } | ||||
|         else { | ||||
|             result.push(item); | ||||
|         } | ||||
|     } | ||||
|     console.log(result); | ||||
|     return result; | ||||
| } | ||||
| exports.splitCJKV = splitCJKV; | ||||
| /** | ||||
|  * hyphenation for a clo document | ||||
|  * @param arr the array for a `tkTree` | ||||
|  * @param clo the Clo object | ||||
|  */ | ||||
| function hyphenForClo(arr, clo) { | ||||
|     let hyphenLanguage = clo.attrs["hyphenLanguage"]; | ||||
|     let res = hyphenTkTree(arr, hyphenLanguage); | ||||
|     return res; | ||||
| } | ||||
| exports.hyphenForClo = hyphenForClo; | ||||
| /** | ||||
|  * convert spaces to Breakpoint | ||||
|  * \s+ => ["bp" [\s+] ""] | ||||
|  * @param arr the tkTree input text stream | ||||
|  * @param clo the Clo object | ||||
|  * @returns the converted object | ||||
|  */ | ||||
| function spacesToBreakpoint(arr, clo) { | ||||
|     let spacePattern = /^([ \t]+)$/g; | ||||
|     var result = []; | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         var item = arr[i]; | ||||
|         if (!Array.isArray(item) && item.match(spacePattern)) { | ||||
|             result.push(['bp', item, ""]); // push a newline command to the result `tkTree`
 | ||||
|         } | ||||
|         else { | ||||
|             result.push(item); | ||||
|         } | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| exports.spacesToBreakpoint = spacesToBreakpoint; | ||||
| /** | ||||
|  * remove all the `` (empty string) in the arr | ||||
|  * @param arr the tkTree to be filtered | ||||
|  * @param clo the Clo file | ||||
|  */ | ||||
| function filterEmptyString(arr, clo) { | ||||
|     if (Array.isArray(arr)) { | ||||
|         arr.filter((x) => { return x != ``; }); | ||||
|     } | ||||
|     return arr; | ||||
| } | ||||
| exports.filterEmptyString = filterEmptyString; | ||||
| /** | ||||
|  * OTHER FUNCTIONS | ||||
|  */ | ||||
| /** | ||||
|  * hyphenate for a tkTree | ||||
|  *  - hyphenation => ["bp", "", "-"] | ||||
|  * @param arr the tkTree array | ||||
|  * @param lang ISO 639 code for the language | ||||
|  */ | ||||
| function hyphenTkTree(arr, lang) { | ||||
|     // import corresponding hyphen language data and function
 | ||||
|     let hyphen = require("hyphen/" + lang); | ||||
|     let result = []; | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         let element = arr[i]; | ||||
|         let splitter = "分"; // a CJKV
 | ||||
|         if (!Array.isArray(element)) { | ||||
|             let hyphenatedElement = hyphen.hyphenateSync(element, { hyphenChar: splitter }); | ||||
|             let hyphenatedSplitted = hyphenatedElement.split(splitter); | ||||
|             var newSplitted = []; | ||||
|             for (var j = 0; j < hyphenatedSplitted.length - 1; j++) { | ||||
|                 newSplitted.push(hyphenatedSplitted[j]); | ||||
|                 // "bp" for breakpoint
 | ||||
|                 newSplitted.push(["bp", "", "-"]); //insert a breakable point (bp) mark
 | ||||
|             } | ||||
|             newSplitted.push(hyphenatedSplitted[hyphenatedSplitted.length - 1]); | ||||
|             result = result.concat(newSplitted); | ||||
|         } | ||||
|         else { | ||||
|             result.push(element); | ||||
|         } | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| exports.hyphenTkTree = hyphenTkTree; | ||||
| /** | ||||
|  * calculate the text width and Height with a given `TextStyle` | ||||
|  * @param preprocessed | ||||
|  * @param defaultFontStyle | ||||
|  */ | ||||
| function calculateTextWidthHeight(preprocessed, style) { | ||||
|     var dom = new jsdom_1.JSDOM(`<!DOCTYPE html><html><head></head>
 | ||||
|     <body><canvas id="canvas"></canvas></body></html>`); | ||||
|     try { | ||||
|         let canvas = dom.window.document.getElementById("canvas"); | ||||
|         console.log(canvas); | ||||
|         /*if (!(canvas instanceof HTMLElement)){ | ||||
|             throw new Error('the <canvas="canvas"> in the jsdom\'s DOM is not found.'); | ||||
|              | ||||
|         }*/ | ||||
|         let context = canvas.getContext("2d"); | ||||
|         console.log(context); | ||||
|         if (context == null) { | ||||
|             throw new Error('`canvas.getContext("2d");` can\'t be executed.'); | ||||
|         } | ||||
|         context.font = `normal normal 10pt ${style.family}`; | ||||
|         console.log(context.font); | ||||
|         let txt = `Hello john`; | ||||
|         console.log(txt); | ||||
|         let measured = context.measureText(txt); | ||||
|         let width = measured.width; | ||||
|         let height = measured.actualBoundingBoxAscent; | ||||
|         let depth = measured.actualBoundingBoxDescent; | ||||
|         console.log("width: " + width); | ||||
|         console.log("height: " + height); | ||||
|         console.log("depth: " + depth); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log("Exception " + error); | ||||
|     } | ||||
| } | ||||
| exports.calculateTextWidthHeight = calculateTextWidthHeight; | ||||
| /** | ||||
|  * whole document-representing class | ||||
|  */ | ||||
| class Clo { | ||||
|     constructor() { | ||||
|         this.preprocessors = []; | ||||
|         this.mainStream = []; | ||||
|         this.attributes = { "page": A4_IN_PX }; | ||||
|         this.attrs = { | ||||
|             "page": exports.A4_IN_PX, | ||||
|             "defaultFrameStyle": exports.defaultFrameStyle, | ||||
|             "hyphenLanguage": 'en' // hyphenated in the language (in ISO 639)
 | ||||
|         }; | ||||
|         // register the precessor functions
 | ||||
|         this.preprocessorRegister(splitCJKV); | ||||
|         this.preprocessorRegister(hyphenForClo); | ||||
|         this.preprocessorRegister(twoReturnsToNewline); | ||||
|         this.preprocessorRegister(spacesToBreakpoint); | ||||
|         this.preprocessorRegister(filterEmptyString); | ||||
|     } | ||||
|     setAttr(attr, val) { | ||||
|         Object.assign(this.attributes, attr, val); | ||||
|         Object.assign(this.attrs, attr, val); | ||||
|     } | ||||
|     getAttr(attr) { | ||||
|         if (Object.keys(this.attributes).length === 0) { | ||||
|             return this.attributes[attr]; | ||||
|         if (Object.keys(this.attrs).length === 0) { | ||||
|             return this.attrs[attr]; | ||||
|         } | ||||
|         else { | ||||
|             return undefined; | ||||
|  | @ -107,14 +277,18 @@ class Clo { | |||
|     } | ||||
|     generatePdf() { | ||||
|         // preprocessed
 | ||||
|         var prepro = this.mainStream; | ||||
|         var preprocessed = this.mainStream; | ||||
|         for (var i = 0; i < this.preprocessors.length; i++) { | ||||
|             prepro = this.preprocessors[i](prepro); | ||||
|             preprocessed = this.preprocessors[i](preprocessed, this); | ||||
|         } | ||||
|         // generate the width and height of the stream
 | ||||
|         let defaultFontStyle = this.attrs["defaultFrameStyle"].textStyle; | ||||
|         calculateTextWidthHeight(preprocessed, defaultFontStyle); | ||||
|         // TODO
 | ||||
|         console.log("test" + prepro); | ||||
|         console.log(preprocessed); | ||||
|     } | ||||
| } | ||||
| exports.Clo = Clo; | ||||
| exports.a = new Clo(); | ||||
| exports.default = exports.a; | ||||
| /* | ||||
| export let a = new Clo(); | ||||
| export default a; */  | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { isKeyObject, isStringObject } from "util/types"; | ||||
| import {tkTree} from "../parser"; | ||||
| import {TextStyle, FontStyle, TextWeight} from "../canva"; | ||||
| import { isString } from "util"; | ||||
| import {FontStyle, TextStyle, TextWeight} from "../canva"; | ||||
| import { JSDOM } from "jsdom"; | ||||
| 
 | ||||
| /** | ||||
|  * TYPES | ||||
|  | @ -13,7 +13,7 @@ import { isString } from "util"; | |||
|  * TTB - top to bottom | ||||
|  * etc. | ||||
|  */ | ||||
| enum Direction{ | ||||
| export enum Direction{ | ||||
|     LTR, | ||||
|     RTL, | ||||
|     TTB, | ||||
|  | @ -25,18 +25,24 @@ enum Direction{ | |||
|  * - directionInsideLine : text direction inside a line | ||||
|  * - baselineskip : the distance between baselines in px | ||||
|  */ | ||||
| interface FrameBox extends Box{ | ||||
| export interface FrameBox extends Box{ | ||||
|     directionInsideLine : Direction, | ||||
|     baseLineskip : number | null, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * a basic Box | ||||
|  * - x : | ||||
|  * - y :  | ||||
|  * - textStyle : | ||||
|  * - direction : | ||||
|  * - width : | ||||
|  * - content : | ||||
|  */ | ||||
| interface Box{ | ||||
| export interface Box{ | ||||
|     x : number | null, | ||||
|     y : number | null, | ||||
|     fontStyle : FontStyle | null, | ||||
|     textStyle : TextStyle | null, | ||||
|     direction : Direction, | ||||
|     width : number, | ||||
|     height : number, | ||||
|  | @ -47,21 +53,21 @@ interface Box{ | |||
| /** | ||||
|  * DEFAULT CONST PART | ||||
|  */ | ||||
| const A4_IN_PX = {"width" : 793.7, | ||||
| export const A4_IN_PX = {"width" : 793.7, | ||||
|                   "height" : 1122.5}; | ||||
| 
 | ||||
| const defaultTextStyle : FontStyle = { | ||||
|         family : "FreeSans", | ||||
|         size : 12, | ||||
| export const defaultTextStyle : TextStyle = { | ||||
|         family : "FreeSerif", | ||||
|         size : ptToPx(12), | ||||
|         textWeight : TextWeight.REGULAR, | ||||
|         textStyle : TextStyle.ITALIC, | ||||
|         fontStyle : FontStyle.ITALIC, | ||||
| } | ||||
| 
 | ||||
| const defaultFrameStyle : FrameBox = { | ||||
| export const defaultFrameStyle : FrameBox = { | ||||
|     directionInsideLine : Direction.LTR, | ||||
|     direction : Direction.TTB, | ||||
|     baseLineskip : ptToPx(15), | ||||
|     fontStyle : defaultTextStyle, | ||||
|     textStyle : defaultTextStyle, | ||||
|     x : A4_IN_PX.width * 0.10, | ||||
|     y : A4_IN_PX.height * 0.10, | ||||
|     width : A4_IN_PX.width * 0.80, | ||||
|  | @ -69,9 +75,17 @@ const defaultFrameStyle : FrameBox = { | |||
|     content : null, | ||||
| }; | ||||
| 
 | ||||
| const cjkvBlocksInRegex = ["Hani"]; | ||||
| /** | ||||
|  * definition for cjk scripts | ||||
|  *  - Hani : Han Character | ||||
|  *  - Hang : Hangul | ||||
|  *  - Bopo : Bopomofo | ||||
|  *  - Kana : Katakana | ||||
|  *  - Hira : Hiragana | ||||
| */ | ||||
| export const cjkvBlocksInRegex = ["Hani", "Hang", "Bopo", "Kana", "Hira"]; | ||||
| 
 | ||||
| const cjkvRegexPattern = new RegExp("((?:" + | ||||
| export const cjkvRegexPattern = new RegExp("((?:" + | ||||
|     cjkvBlocksInRegex.map((x)=>"\\p{Script_Extensions="+x+"}").join("|") + ")+)", "gu"); | ||||
| /** | ||||
|  * FUNCTION PART | ||||
|  | @ -81,8 +95,8 @@ const cjkvRegexPattern = new RegExp("((?:" + | |||
|  * @param pt pt size value | ||||
|  * @returns the corresponding px value | ||||
|  */ | ||||
| function ptToPx(pt : number) : number{ | ||||
|     return pt * 4 / 3.0; | ||||
| export function ptToPx(pt : number) : number{ | ||||
|     return pt * 4.0 / 3.0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -91,19 +105,54 @@ function ptToPx(pt : number) : number{ | |||
|  *  REGISTER PART | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * convert '\n\n' to newline command ["nl"] | ||||
|  * @param arr the input `tkTree` | ||||
|  * @param clo the `Clo` object | ||||
|  * @returns the input tktree | ||||
|  */ | ||||
| export function twoReturnsToNewline(arr : tkTree, clo : Clo): tkTree{ | ||||
|     var middle : tkTree = []; | ||||
| 
 | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         var item = arr[i]; | ||||
|         if (!Array.isArray(item)){ | ||||
|             middle = middle.concat(item.split(/(\n\n)/g)); | ||||
|         } | ||||
|         else{ | ||||
|             middle.push(item); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     var result : tkTree = []; | ||||
|     for (let j = 0; j < middle.length; j++){ | ||||
|         var item = middle[j]; | ||||
|         if (!Array.isArray(item) && item == "\n\n"){ | ||||
|             result.push(["nl"]); // push a newline command to the result `tkTree`
 | ||||
|         } | ||||
|         else{ | ||||
|             result.push(middle[j]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * split CJKV and non-CJKV | ||||
|  * | ||||
|  * @param arr : input tkTree | ||||
|  * @returns  | ||||
|  * @returns a splitted tkTree (by CJK and NonCJK) | ||||
|  * - Examples: | ||||
|  *  ``` | ||||
|  *  [`many臺中daylight`] => [`many`, `臺中`, `dahylight`] | ||||
|  *  ``` | ||||
|  */  | ||||
| function splitCJKV(arr : tkTree): tkTree{ | ||||
| export function splitCJKV(arr : tkTree, clo : Clo): tkTree{ | ||||
|     var result : tkTree = []; | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         var item = arr[i]; | ||||
|         if (!Array.isArray(item)){ | ||||
|             console.log(item.split(cjkvRegexPattern)); | ||||
|             result = result.concat(item.split(cjkvRegexPattern)); | ||||
|         } | ||||
|         else{ | ||||
|  | @ -114,30 +163,182 @@ function splitCJKV(arr : tkTree): tkTree{ | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * hyphenation for a clo document | ||||
|  * @param arr the array for a `tkTree` | ||||
|  * @param clo the Clo object | ||||
|  */ | ||||
| export function hyphenForClo(arr : tkTree, clo : Clo): tkTree{ | ||||
|     let hyphenLanguage : string = clo.attrs["hyphenLanguage"]; | ||||
|     let res =  hyphenTkTree(arr, hyphenLanguage); | ||||
|     return res; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * convert spaces to Breakpoint | ||||
|  * \s+ => ["bp" [\s+] ""] | ||||
|  * @param arr the tkTree input text stream | ||||
|  * @param clo the Clo object  | ||||
|  * @returns the converted object | ||||
|  */ | ||||
| export function spacesToBreakpoint(arr : tkTree, clo : Clo) : tkTree{ | ||||
|     let spacePattern = /^([ \t]+)$/g; | ||||
|     var result : tkTree = []; | ||||
|     for (let i = 0; i < arr.length; i++){ | ||||
|         var item = arr[i]; | ||||
|         if (!Array.isArray(item) && item.match(spacePattern)){ | ||||
|             result.push([ 'bp', item, "" ]); // push a newline command to the result `tkTree`
 | ||||
|         } | ||||
|         else{ | ||||
|             result.push(item); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * remove all the `` (empty string) in the arr | ||||
|  * @param arr the tkTree to be filtered | ||||
|  * @param clo the Clo file  | ||||
|  */ | ||||
| export function filterEmptyString(arr : tkTree, clo : Clo) : tkTree{ | ||||
|     if (Array.isArray(arr)){ | ||||
|         arr.filter((x)=>{return x != ``;}); | ||||
|     } | ||||
| 
 | ||||
|     return arr; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * OTHER FUNCTIONS | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * hyphenate for a tkTree | ||||
|  *  - hyphenation => ["bp", "", "-"] | ||||
|  * @param arr the tkTree array | ||||
|  * @param lang ISO 639 code for the language | ||||
|  */ | ||||
| export function hyphenTkTree(arr : tkTree, lang: string) : tkTree{ | ||||
|     // import corresponding hyphen language data and function
 | ||||
|     let hyphen = require("hyphen/"+lang); | ||||
| 
 | ||||
|     let result :tkTree[] = []; | ||||
|     for (let i = 0; i < arr.length; i++) { | ||||
|         let element = arr[i]; | ||||
|         let splitter = "分"; // a CJKV
 | ||||
|         if (!Array.isArray(element)){ | ||||
|             let hyphenatedElement : string = hyphen.hyphenateSync(element, {hyphenChar :splitter}); | ||||
|             let hyphenatedSplitted : tkTree = hyphenatedElement.split(splitter); | ||||
|             var newSplitted : tkTree = []; | ||||
|             for (var j=0; j<hyphenatedSplitted.length-1;j++){ | ||||
|                 newSplitted.push(hyphenatedSplitted[j]); | ||||
|                 // "bp" for breakpoint
 | ||||
|                 newSplitted.push(["bp", "", "-"]); //insert a breakable point (bp) mark
 | ||||
|             } | ||||
|             newSplitted.push(hyphenatedSplitted[hyphenatedSplitted.length-1]); | ||||
| 
 | ||||
|             result = result.concat(newSplitted); | ||||
| 
 | ||||
|         }else{ | ||||
|             result.push(element); | ||||
|         } | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * calculate the text width and Height with a given `TextStyle`  | ||||
|  * @param preprocessed  | ||||
|  * @param defaultFontStyle  | ||||
|  */ | ||||
| export function calculateTextWidthHeight(preprocessed : tkTree, style : TextStyle): void { | ||||
|     var dom = new JSDOM(`<!DOCTYPE html><html><head></head>
 | ||||
|     <body><canvas id="canvas"></canvas></body></html>`);
 | ||||
|      | ||||
|     try { | ||||
|         let canvas  = dom.window.document.getElementById("canvas"); | ||||
|         console.log(canvas); | ||||
| 
 | ||||
|         /*if (!(canvas instanceof HTMLElement)){ | ||||
|             throw new Error('the <canvas="canvas"> in the jsdom\'s DOM is not found.'); | ||||
|              | ||||
|         }*/ | ||||
| 
 | ||||
|         let context = (<HTMLCanvasElement>canvas).getContext("2d"); | ||||
|         console.log(context); | ||||
|         if (context == null){ | ||||
|             throw new Error('`canvas.getContext("2d");` can\'t be executed.'); | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         context.font = `normal normal ${style.size}px ${style.family}`; | ||||
|         console.log(context.font); | ||||
|         let txt = `Hello john`; | ||||
|         console.log(txt); | ||||
|         let measured = context.measureText(txt); | ||||
|         let width = measured.width; | ||||
|         let height = measured.actualBoundingBoxAscent; | ||||
|         let depth = measured.actualBoundingBoxDescent; | ||||
| 
 | ||||
|         console.log("width: "+width); | ||||
|         console.log("height: "+height); | ||||
|         console.log("depth: "+depth); | ||||
| 
 | ||||
| 
 | ||||
|     } catch (error) { | ||||
|         console.log("Exception "+error); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * whole document-representing class | ||||
|  */ | ||||
| export class Clo{ | ||||
|     /** storing the text string into the main frame */ | ||||
|     mainStream : Array<string>; | ||||
|     /** array of preprocessor functions to preprocess the `mainStream` */ | ||||
|     preprocessors : Array<Function>; | ||||
|     attributes: {[index: string]:any} ; // a4 size(x,y)
 | ||||
|     /** the attributes for the Clo */ | ||||
|     attrs: {[index: string]:any} ; // a4 size(x,y)
 | ||||
| 
 | ||||
|      | ||||
|     constructor(){ | ||||
|         this.preprocessors = []; | ||||
|         this.mainStream = []; | ||||
|         this.attributes = {"page" : A4_IN_PX}; | ||||
|         this.attrs = { | ||||
|             "page" : A4_IN_PX, // default for a4. in px of [x, y]
 | ||||
|             "defaultFrameStyle" : defaultFrameStyle, // defaultFrameStyle
 | ||||
|             "hyphenLanguage" : 'en' // hyphenated in the language (in ISO 639)
 | ||||
|         }; | ||||
| 
 | ||||
|          | ||||
| 
 | ||||
|         // register the precessor functions
 | ||||
|         this.preprocessorRegister(splitCJKV); | ||||
|         this.preprocessorRegister(hyphenForClo); | ||||
|         this.preprocessorRegister(twoReturnsToNewline); | ||||
|         this.preprocessorRegister(spacesToBreakpoint); | ||||
|         this.preprocessorRegister(filterEmptyString); | ||||
|     } | ||||
| 
 | ||||
|     public setAttr(attr : string, val : any):void{ | ||||
|         Object.assign(this.attributes, attr, val); | ||||
|         Object.assign(this.attrs, attr, val); | ||||
|     } | ||||
| 
 | ||||
|     public getAttr(attr:string) : any{ | ||||
|         if (Object.keys(this.attributes).length === 0){ | ||||
|             return this.attributes[attr]; | ||||
|         if (Object.keys(this.attrs).length === 0){ | ||||
|             return this.attrs[attr]; | ||||
|         }else{ | ||||
|             return undefined; | ||||
|         } | ||||
|  | @ -154,16 +355,22 @@ export class Clo{ | |||
| 
 | ||||
|     public generatePdf(){ | ||||
|         // preprocessed
 | ||||
|         var prepro = this.mainStream; | ||||
|         var preprocessed = this.mainStream; | ||||
|         for (var i = 0; i<this.preprocessors.length; i++){ | ||||
|             prepro = this.preprocessors[i](prepro); | ||||
|             preprocessed = this.preprocessors[i](preprocessed, this); | ||||
|         } | ||||
|         // generate the width and height of the stream
 | ||||
| 
 | ||||
|         let defaultFontStyle : TextStyle = this.attrs["defaultFrameStyle"].textStyle; | ||||
|         calculateTextWidthHeight(preprocessed, defaultFontStyle); | ||||
| 
 | ||||
|         // TODO
 | ||||
|         console.log("test"+prepro); | ||||
|         console.log(preprocessed); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| export let a = new Clo(); | ||||
| export default a; | ||||
| export default a; */ | ||||
|  | @ -33,7 +33,7 @@ export function tkTreeToSExp(t: tkTree): string{ | |||
| 
 | ||||
| export type tkTree = string | tkTree[]; | ||||
| 
 | ||||
| enum TokenKind { | ||||
| export enum TokenKind { | ||||
|     Seperator, // ---
 | ||||
|     Semicolon, // ;
 | ||||
|     Number, | ||||
|  | @ -50,7 +50,7 @@ enum TokenKind { | |||
| /** | ||||
|  * Parsing | ||||
|  */ | ||||
| const lexer = p.buildLexer([ | ||||
| export const lexer = p.buildLexer([ | ||||
|     [true, /^\d+(\.\d+)?/g, TokenKind.Number], | ||||
|     [true, /^[\\][\\]/g, TokenKind.Op], | ||||
|     [true, /^\\\@/g, TokenKind.ExcapeAt], | ||||
|  | @ -75,41 +75,42 @@ const lexer = p.buildLexer([ | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| const PROG = p.rule<TokenKind, tkTree>(); | ||||
| const SEGMENT = p.rule<TokenKind, tkTree>(); | ||||
| const IMPORT = p.rule<TokenKind, tkTree>(); | ||||
| const IMPORTS = p.rule<TokenKind, tkTree>(); | ||||
| const SEMICOLON = p.rule<TokenKind, tkTree>(); | ||||
| const NOT_AT_TEXT = p.rule<TokenKind, tkTree>(); | ||||
| const CONTENT = p.rule<TokenKind, tkTree>(); | ||||
| export const PROG = p.rule<TokenKind, tkTree>(); | ||||
| export const SEGMENT = p.rule<TokenKind, tkTree>(); | ||||
| export const IMPORT = p.rule<TokenKind, tkTree>(); | ||||
| export const IMPORTS = p.rule<TokenKind, tkTree>(); | ||||
| export const SEMICOLON = p.rule<TokenKind, tkTree>(); | ||||
| export const NOT_AT_TEXT = p.rule<TokenKind, tkTree>(); | ||||
| export const CONTENT = p.rule<TokenKind, tkTree>(); | ||||
| 
 | ||||
| 
 | ||||
| function applySegment(input: [Token<TokenKind>, Token<TokenKind>[], | ||||
| export function applySegment(input: [Token<TokenKind>, Token<TokenKind>[], | ||||
|         Token<TokenKind>]): tkTree[]{ | ||||
|     let unpackedInnerExprs = input[1].map((x)=>{return x.text}); | ||||
|     return ["%exprs", unpackedInnerExprs]; | ||||
| } | ||||
| 
 | ||||
| function applySemiColon(value: Token<TokenKind.Semicolon>): tkTree{ | ||||
| export function applySemiColon(value: Token<TokenKind.Semicolon>): tkTree{ | ||||
|     return value.text; | ||||
| } | ||||
| 
 | ||||
| function applyParts(first: tkTree, | ||||
|                     second: [Token<TokenKind>, tkTree]):tkTree { | ||||
|     return ["%clo", first , second[1]]; | ||||
| export function applyParts(first: tkTree,  | ||||
|                     second: [Token<TokenKind>, Token<TokenKind>, tkTree]):tkTree { | ||||
|     return ["%clo", first , second[2]]; | ||||
| } | ||||
| 
 | ||||
| function applyPartsWithoutImport(parsed: [Token<TokenKind>, tkTree]):tkTree { | ||||
| return ["%clo", "" , parsed[1]]; | ||||
| export function applyPartsWithoutImport( | ||||
|         parsed: [Token<TokenKind>, Token<TokenKind>, tkTree]):tkTree { | ||||
| return ["%clo", "" , parsed[2]]; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function applyComment(value: Token<TokenKind.Comment>): tkTree[]{ | ||||
| export function applyComment(value: Token<TokenKind.Comment>): tkTree[]{ | ||||
|     return [value.text]; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function applyImport(input: [Token<TokenKind>,Token<TokenKind>[], tkTree]) : tkTree{ | ||||
| export function applyImport(input: [Token<TokenKind>,Token<TokenKind>[], tkTree]) : tkTree{ | ||||
|     let importTail = input[1].map(x=>x.text); | ||||
|     return ["import"].concat(importTail); | ||||
| }; | ||||
|  | @ -123,7 +124,7 @@ function applyImportComment(input: [Token<TokenKind>,Token<TokenKind>[], | |||
|     return ["import"].concat(importTail).concat(comment); | ||||
| };*/ | ||||
| 
 | ||||
| function applyImports(input : [tkTree, tkTree[]]): tkTree{ | ||||
| export function applyImports(input : [tkTree, tkTree[]]): tkTree{ | ||||
|     let resultBody = [input[0]].concat(input[1]); | ||||
|     let resultWrapper = ["%import", resultBody]; | ||||
|     return resultWrapper; | ||||
|  | @ -132,29 +133,29 @@ function applyImports(input : [tkTree, tkTree[]]): tkTree{ | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function applyNotAtText(value : Token<TokenKind>): tkTree{ | ||||
| export function applyNotAtText(value : Token<TokenKind>): tkTree{ | ||||
|     if (value.text == "\\\@"){ | ||||
|         return '@'; | ||||
|     } | ||||
|     else{return value.text;} | ||||
| }; | ||||
| 
 | ||||
| function applyText (input : tkTree): tkTree[]{ | ||||
| export function applyText (input : tkTree): tkTree[]{ | ||||
|     return ["%text", input]; | ||||
| }; | ||||
| 
 | ||||
| function applyContent(input : tkTree[]): tkTree[]{ | ||||
| export function applyContent(input : tkTree[]): tkTree[]{ | ||||
|     return ["%content", input]; | ||||
| }; | ||||
| 
 | ||||
| function applySpaceNL(value : Token<TokenKind.SpaceNL>): tkTree{ | ||||
| export function applySpaceNL(value : Token<TokenKind.SpaceNL>): tkTree{ | ||||
|     return value.text; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * IMPORTEE:  Number, Op, Paren, Id, Str, Comment, | ||||
|  */ | ||||
| let IMPORTEE = p.alt(p.tok(TokenKind.Number), | ||||
| export let IMPORTEE = p.alt(p.tok(TokenKind.Number), | ||||
|     p.tok(TokenKind.Op), | ||||
|     p.tok(TokenKind.Paren), | ||||
|     p.tok(TokenKind.Id), | ||||
|  | @ -162,7 +163,7 @@ let IMPORTEE = p.alt(p.tok(TokenKind.Number), | |||
|     p.tok(TokenKind.SpaceNL), | ||||
|     p.tok(TokenKind.Comment)); | ||||
| 
 | ||||
| let NOT_AT = p.alt(p.tok(TokenKind.Seperator), | ||||
| export let NOT_AT = p.alt(p.tok(TokenKind.Seperator), | ||||
|     p.tok(TokenKind.Semicolon), | ||||
|     p.tok(TokenKind.Number), | ||||
|     p.tok(TokenKind.ExcapeAt), | ||||
|  | @ -175,12 +176,12 @@ let NOT_AT = p.alt(p.tok(TokenKind.Seperator), | |||
|     ); | ||||
| 
 | ||||
| /** | ||||
|  * PROG : IMPORTS '---' CONTENT | '---' CONTNENT | ||||
|  * PROG : IMPORTS '---' NEWLINE CONTENT | '---' NEWLINE CONTNENT | ||||
|  */ | ||||
| PROG.setPattern( | ||||
|     p.alt( | ||||
|         p.lrec_sc(IMPORTS, p.seq(p.str('---'), CONTENT), applyParts), | ||||
|         p.apply(p.seq(p.str('---'), CONTENT), applyPartsWithoutImport)) | ||||
|         p.lrec_sc(IMPORTS, p.seq(p.str('---'), p.str("\n"), CONTENT), applyParts), | ||||
|         p.apply(p.seq(p.str('---'), p.str("\n"), CONTENT), applyPartsWithoutImport)) | ||||
| 
 | ||||
| ) | ||||
| 
 | ||||
|  | @ -242,7 +243,7 @@ CONTENT.setPattern( | |||
| /** | ||||
|  * the head part of the output JS code : before import | ||||
|  */ | ||||
| let outputHead = ` | ||||
| export let outputHead = ` | ||||
| /* clo, a typesetting engine, generated JS file*/ | ||||
| /* CLO:  beginning of head*/ | ||||
| 
 | ||||
|  | @ -254,11 +255,15 @@ let clo = new cloLib.Clo(); | |||
| /** | ||||
|  * the middle part of the output JS code : between import part and content part | ||||
|  */ | ||||
| let outputMiddle =` | ||||
| export let outputMiddle =` | ||||
| /* CLO:  beginning of middle part*/ | ||||
| clo.mainStream = /* CLO: end of middle part*/ | ||||
| ` | ||||
| let outputEnd =` | ||||
| 
 | ||||
| /** | ||||
|  * the end part of the output JS code : after content part | ||||
|  */ | ||||
| export let outputEnd =` | ||||
| /* CLO: beginning of end part*/ | ||||
| clo.generatePdf(); | ||||
| /*CLO : end of end part*/ | ||||
|  | @ -346,6 +351,9 @@ export function treeToJS(tree : tkTree): string{ | |||
|  * `inputText` to `tkTree` (ASTTree)  | ||||
|  */ | ||||
| export function inputTextToTree(inputText : string){ | ||||
| return p.expectSingleResult( | ||||
|     p.expectEOF(PROG.parse(lexer.parse(inputText)))); | ||||
|     // force convert Windows newline to Linux newline
 | ||||
|     inputText = inputText.replace("\r\n", "\n"); | ||||
| 
 | ||||
|     return p.expectSingleResult( | ||||
|         p.expectEOF(PROG.parse(lexer.parse(inputText)))); | ||||
| } | ||||
|  | @ -1,33 +1,30 @@ | |||
| "use strict"; | ||||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||
|     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||
|     return new (P || (P = Promise))(function (resolve, reject) { | ||||
|         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||
|         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||
|         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||
|         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||
|     }); | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.pdfGenerate = void 0; | ||||
| const fs_1 = require("fs"); | ||||
| const pdf_lib_1 = require("pdf-lib"); | ||||
| /*import { readFileSync, writeFileSync } from "fs"; | ||||
| import { PDFDocument } from "pdfkit"; | ||||
| var fontkit = require('pdf-fontkit'); | ||||
| function pdfGenerate() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const pdfDoc = yield pdf_lib_1.PDFDocument.create(); | ||||
|         const page = pdfDoc.addPage(); | ||||
|         pdfDoc.registerFontkit(fontkit); | ||||
|         const fontBytes = (0, fs_1.readFileSync)("/usr/share/fonts/uming.ttf"); | ||||
|         const font2 = yield pdfDoc.embedFont(fontBytes, { subset: true }); | ||||
|         const fontBytes2 = (0, fs_1.readFileSync)("/usr/share/fonts/truetype/noto/NotoSansArabic-Light.ttf"); | ||||
|         const font3 = yield pdfDoc.embedFont(fontBytes2, { subset: true }); | ||||
|         page.drawText("x=20, y=20", { x: 20, y: 20 }); | ||||
|         page.drawText("x:20, y:100 天地人", { x: 20, y: 100, font: font2 }); | ||||
|         page.drawText("عربي", { x: 50, y: 150, font: font3 }); | ||||
|         const pdfBytes = yield pdfDoc.save(); | ||||
|         (0, fs_1.writeFileSync)('/tmp/test2.pdf', pdfBytes); | ||||
|     }); | ||||
| 
 | ||||
| export async function pdfGenerate(){ | ||||
| 
 | ||||
|     const pdfDoc = await PDFDocument.create() | ||||
|     const page = pdfDoc.addPage() | ||||
| 
 | ||||
|     pdfDoc.registerFontkit(fontkit); | ||||
|     const fontBytes = readFileSync("/usr/share/fonts/uming.ttf"); | ||||
|     const font2 = await pdfDoc.embedFont(fontBytes, {subset:true}) | ||||
| 
 | ||||
|     const fontBytes2 = readFileSync("/usr/share/fonts/truetype/noto/NotoSansArabic-Light.ttf") | ||||
| 
 | ||||
|     const font3 = await pdfDoc.embedFont(fontBytes2, {subset:true}) | ||||
| 
 | ||||
|     page.drawText("x=20, y=20", {x : 20, y : 20}) | ||||
|     page.drawText("x:20, y:100 天地人", {x : 20, y : 100, font: font2}) | ||||
|     page.drawText("عربي", {x : 50, y : 150, font: font3}) | ||||
| 
 | ||||
|     const pdfBytes = await pdfDoc.save(); | ||||
| 
 | ||||
|     writeFileSync('/tmp/test2.pdf', pdfBytes); | ||||
| } | ||||
| exports.pdfGenerate = pdfGenerate; | ||||
| 
 | ||||
| pdfGenerate(); | ||||
| 
 | ||||
| */  | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { readFileSync, writeFileSync } from "fs"; | ||||
| import { PDFDocument } from "pdf-lib"; | ||||
| /*import { readFileSync, writeFileSync } from "fs"; | ||||
| import { PDFDocument } from "pdfkit"; | ||||
| var fontkit = require('pdf-fontkit'); | ||||
| 
 | ||||
| export async function pdfGenerate(){ | ||||
|  | @ -25,3 +25,5 @@ export async function pdfGenerate(){ | |||
| } | ||||
| 
 | ||||
| pdfGenerate(); | ||||
| 
 | ||||
| */ | ||||
|  | @ -6,21 +6,21 @@ let hanziFont = { | |||
|     family : "Noto Sans CJK TC", | ||||
|     size : 12, | ||||
|     textWeight : canva.TextWeight.REGULAR, | ||||
|     textStyle : canva.TextStyle.ITALIC, | ||||
|     fontStyle : canva.FontStyle.ITALIC, | ||||
| } | ||||
| 
 | ||||
| let romanFont = { | ||||
|     family : "FreeSans", | ||||
|     size : 15, | ||||
|     textWeight : canva.TextWeight.BOLD, | ||||
|     textStyle : canva.TextStyle.ITALIC, | ||||
|     fontStyle : canva.FontStyle.ITALIC, | ||||
| } | ||||
| 
 | ||||
| let arabicFont = { | ||||
|     family : "noto sans arabic", | ||||
|     size : 16, | ||||
|     textWeight : canva.TextWeight.REGULAR, | ||||
|     textStyle : canva.TextStyle.NORMAL, | ||||
|     fontStyle : canva.FontStyle.NORMAL, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -32,7 +32,7 @@ async function foo (){ | |||
| 
 | ||||
|     let clo =  await { | ||||
|         mainText : ["123 一隻貓跑過來"], | ||||
|         mainFontStyle : hanziFont, | ||||
|         mainTextStyle : hanziFont, | ||||
|         PDFCanvas : doc, | ||||
| 
 | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										34
									
								
								參考資料-Harfbuzz如何使用.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								參考資料-Harfbuzz如何使用.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| import sys | ||||
| 
 | ||||
| import uharfbuzz as hb | ||||
| 
 | ||||
| 
 | ||||
| fontfile = sys.argv[1] | ||||
| text = sys.argv[2] | ||||
| 
 | ||||
| blob = hb.Blob.from_file_path(fontfile) | ||||
| face = hb.Face(blob) | ||||
| font = hb.Font(face) | ||||
| 
 | ||||
| px = 96 | ||||
| scale = 1000000.0/952997 | ||||
| font.scale = (px *scale* 1024, px*scale * 1024) | ||||
| 
 | ||||
| buf = hb.Buffer() | ||||
| buf.add_str(text) | ||||
| buf.guess_segment_properties() | ||||
| 
 | ||||
| features = {"kern": True, "liga": True} | ||||
| hb.shape(font, buf, features) | ||||
| 
 | ||||
| infos = buf.glyph_infos | ||||
| positions = buf.glyph_positions | ||||
| 
 | ||||
| for info, pos in zip(infos, positions): | ||||
|     gid = info.codepoint | ||||
|     cluster = info.cluster | ||||
|     x_advance = pos.x_advance / 1024 | ||||
|     y_advance = pos.y_advance / 1024 | ||||
|     x_offset = pos.x_offset / 1024 | ||||
|     y_offset = pos.y_offset /1024 | ||||
|     print(f"gid{gid}={cluster}@{x_advance},{y_offset}+{x_advance},{y_advance}") | ||||
		Loading…
	
		Reference in a new issue