]> git.kianting.info Git - anotherTypesetter/commitdiff
加上量字功能
authorTan Kian-ting <chenjt30@gmail.com>
Sun, 21 Apr 2024 11:09:52 +0000 (19:09 +0800)
committerTan Kian-ting <chenjt30@gmail.com>
Sun, 21 Apr 2024 11:09:52 +0000 (19:09 +0800)
src/index.js
src/index.ts
text.lisp
text.lisp.pdf

index dae4421b0389d28f0d616d49add0a6cb063a71e6..2c6488f927ace0119eaff32c2490eb8ff12d5e36 100644 (file)
@@ -44,7 +44,8 @@ var TokenKind;
     TokenKind[TokenKind["SpaceNL"] = 9] = "SpaceNL";
     TokenKind[TokenKind["BSlash"] = 10] = "BSlash";
     TokenKind[TokenKind["Apos"] = 11] = "Apos";
-    TokenKind[TokenKind["Other"] = 12] = "Other";
+    TokenKind[TokenKind["Cmt"] = 12] = "Cmt";
+    TokenKind[TokenKind["Other"] = 13] = "Other";
 })(TokenKind || (TokenKind = {}));
 var ItemType;
 (function (ItemType) {
@@ -71,16 +72,16 @@ const tokenizer = (0, typescript_parsec_1.buildLexer)([
     [true, /^'/g, TokenKind.Apos],
     [true, /^(\s|\t|\r?\n)+/g, TokenKind.SpaceNL],
     [true, /^\\/g, TokenKind.BSlash],
+    [false, /^\/\/[^\/\r\n]+(\r?\n)/g, TokenKind.Cmt],
     [true, /^([^+\-*/a-zA-Z_0-9\[\]()'\s\t\r\n\\]+)/g, TokenKind.Other],
 ]);
 /*
  * ## BNF
-LISP = UNIT | LISPS | CON_STR
+LISP = SINGLE | LISPS | CON_STR
 LISPS = "(" LISP ")" | "'" "(" LISP ")"
-SINGLE = "{" CONSTR_INNR | LISP "}"
-UNIT = INT | NUMBER | STRING | ID
-CONSTR = "[" (CONSTR_INNER "]"
-CONSTR_INNER = ([^\\\[\][]] | [\\][{}\[\]]) | LISPS)*
+SINGLE  = INT | NUMBER | STRING | ID
+CON_STR = "[" CONSTR_INNER "]"
+CONSTR_INNER = ([^\\\[\]{}] | [\\][{}\[\]]) | LISPS)*
  */
 const SINGLE = (0, typescript_parsec_1.rule)();
 const LISPS = (0, typescript_parsec_1.rule)();
@@ -151,7 +152,7 @@ function applyStrings(value) {
     return merged;
 }
 /** for convinence to omit the spaces and newlines */
-const __ = (0, typescript_parsec_2.opt)((0, typescript_parsec_2.tok)(TokenKind.SpaceNL));
+const __ = (0, typescript_parsec_2.rep_sc)((0, typescript_parsec_2.tok)(TokenKind.SpaceNL));
 LISP.setPattern((0, typescript_parsec_2.alt)((0, typescript_parsec_2.kleft)(SINGLE, __), (0, typescript_parsec_2.kleft)(LISPS, __), (0, typescript_parsec_2.kleft)(CON_STR, __)));
 SINGLE.setPattern((0, typescript_parsec_2.alt)((0, typescript_parsec_2.apply)((0, typescript_parsec_2.tok)(TokenKind.Id), applyId), (0, typescript_parsec_2.apply)((0, typescript_parsec_2.tok)(TokenKind.Int), applyInt), (0, typescript_parsec_2.apply)((0, typescript_parsec_2.tok)(TokenKind.Flo), applyFlo), (0, typescript_parsec_2.apply)((0, typescript_parsec_2.tok)(TokenKind.Str), applyStr), (0, typescript_parsec_2.apply)((0, typescript_parsec_2.tok)(TokenKind.Bool), applyBool)));
 LISPS.setPattern((0, typescript_parsec_2.alt)((0, typescript_parsec_2.apply)((0, typescript_parsec_2.kmid)((0, typescript_parsec_2.seq)((0, typescript_parsec_2.str)("("), __), (0, typescript_parsec_2.rep_sc)(LISP), (0, typescript_parsec_2.str)(")")), applyList), (0, typescript_parsec_2.apply)((0, typescript_parsec_2.kright)((0, typescript_parsec_2.str)("'"), (0, typescript_parsec_2.kmid)((0, typescript_parsec_2.seq)((0, typescript_parsec_2.str)("("), __), (0, typescript_parsec_2.rep_sc)(LISP), (0, typescript_parsec_2.str)(")"))), applyQuoted)));
@@ -175,7 +176,7 @@ async function measureWidthPx(inputString, fontFamily, fontSizePt) {
         var blob = hb.createBlob(fontdata); // Load the font data into something Harfbuzz can use
         var face = hb.createFace(blob, 0); // Select the first font in the file (there's normally only one!)
         var font = hb.createFont(face); // Create a Harfbuzz font object from the face
-        font.setScale(fontSizePt * 4 / 3 * 1000, fontSizePt * 4 / 3 * 1000);
+        font.setScale(fontSizePt * 1000, fontSizePt * 1000);
         var buffer = hb.createBuffer(); // Make a buffer to hold some text
         buffer.addText(inputString); // Fill it with some stuff
         buffer.guessSegmentProperties(); // Set script, language and direction
@@ -401,21 +402,21 @@ function cons(h, t) {
 }
 /* PDF manipulation */
 async function drawText(pageIndex, fontFamily, textSize, color, x, y, text) {
-    let currentPage = pdfDoc.getPages()[0];
+    let pdfPages = pdfDoc.getPages();
+    let currentPage = pdfPages[pageIndex];
     const fcMatch = await (0, child_process_1.spawnSync)('fc-match', ['--format=%{file}', fontFamily]);
     const path = fcMatch.stdout.toString();
     pdfDoc.registerFontkit(fontkit_1.default);
     const fontBytes = fs.readFileSync(path);
     const customFont = await pdfDoc.embedFont(fontBytes);
     const rgbColor = await hexColorToRGB(color);
-    let a = await pdfDoc.getPage(0).drawText(text, {
+    let _ = await currentPage.drawText(text, {
         x: x,
         y: y,
         size: textSize,
         font: customFont,
         color: rgbColor,
     });
-    await pdfDoc.save();
 }
 async function hexColorToRGB(hex) {
     let rgbHex = /[#]?([\dA-Fa-f]{2})([\dA-Fa-f]{2})([\dA-Fa-f]{2})/.exec(hex);
@@ -825,7 +826,7 @@ async function interp(prog, env) {
                             throw new Error("the type of replace and variable should be the same.");
                         }
                         else {
-                            env[vari.id][0].value = prog[2];
+                            env[vari.id][0].value = replacer;
                             return { type: ItemType.Unit };
                         }
                     }
@@ -850,7 +851,7 @@ async function interp(prog, env) {
                         }
                         else {
                             const fontFamily = argsMapped[0].str;
-                            const textSize = argsMapped[1].int;
+                            const textSize = argsMapped[1].flo;
                             const color = argsMapped[2].str;
                             const x = argsMapped[3].flo;
                             const y = argsMapped[4].flo;
@@ -861,6 +862,26 @@ async function interp(prog, env) {
                             };
                         }
                     }
+                    // print to the console
+                    else if (op.id === "print") {
+                        if (prog.length !== 2) {
+                            throw invalidLengthException('print', 1);
+                        }
+                        else {
+                            let data = argsMapped[0];
+                            let dataString;
+                            if (data.hasOwnProperty("list")) {
+                                dataString = astToString(data, true);
+                            }
+                            else {
+                                dataString = astToString(data, false);
+                            }
+                            console.log(dataString);
+                            return {
+                                type: ItemType.Unit,
+                            };
+                        }
+                    }
                     // procedures returning the last called command
                     else if (op.id === "begin") {
                         const rtn = argsMapped[argsMapped.length - 1];
index 9260f7f9e12467d2eb3cf58efc6e2e8be1e3dbae..cfb1c1dc5c84703c344a2abaa56684fc50f1015f 100644 (file)
@@ -39,7 +39,8 @@ enum TokenKind {
   RBrack,
   SpaceNL,
   BSlash,
-  Apos,
+  Apos,  // Apostrophe
+  Cmt, // comment
   Other,
 }
 
@@ -124,17 +125,17 @@ const tokenizer = buildLexer([
   [true, /^'/g, TokenKind.Apos],
   [true, /^(\s|\t|\r?\n)+/g, TokenKind.SpaceNL],
   [true, /^\\/g, TokenKind.BSlash],
+  [false, /^\/\/[^\/\r\n]+(\r?\n)/g, TokenKind.Cmt], // omit the comment
   [true, /^([^+\-*/a-zA-Z_0-9\[\]()'\s\t\r\n\\]+)/g, TokenKind.Other],
 ]);
 
 /*
  * ## BNF
-LISP = UNIT | LISPS | CON_STR
+LISP = SINGLE | LISPS | CON_STR
 LISPS = "(" LISP ")" | "'" "(" LISP ")"
-SINGLE = "{" CONSTR_INNR | LISP "}"
-UNIT = INT | NUMBER | STRING | ID
-CONSTR = "[" (CONSTR_INNER "]"
-CONSTR_INNER = ([^\\\[\][]] | [\\][{}\[\]]) | LISPS)*
+SINGLE  = INT | NUMBER | STRING | ID
+CON_STR = "[" CONSTR_INNER "]"
+CONSTR_INNER = ([^\\\[\]{}] | [\\][{}\[\]]) | LISPS)*
  */
 
 const SINGLE = rule<TokenKind, AST>();
@@ -216,7 +217,7 @@ function applyStrings(value: AST[]): AST {
 }
 
 /** for convinence to omit the spaces and newlines */
-const __ = opt(tok(TokenKind.SpaceNL));
+const __ = rep_sc(tok(TokenKind.SpaceNL));
 
 LISP.setPattern(alt(kleft(SINGLE, __), kleft(LISPS, __), kleft(CON_STR, __)));
 
@@ -286,7 +287,7 @@ async function measureWidthPx(inputString: string, fontFamily : string, fontSize
           var blob = hb.createBlob(fontdata); // Load the font data into something Harfbuzz can use
           var face = hb.createFace(blob, 0);  // Select the first font in the file (there's normally only one!)
           var font = hb.createFont(face);     // Create a Harfbuzz font object from the face
-          font.setScale(fontSizePt * 4/3* 1000 , fontSizePt*4/3 * 1000 );
+          font.setScale(fontSizePt  * 1000 , fontSizePt * 1000 );
           var buffer = hb.createBuffer();     // Make a buffer to hold some text
           buffer.addText(inputString);              // Fill it with some stuff
           buffer.guessSegmentProperties();    // Set script, language and direction
@@ -309,7 +310,7 @@ async function measureWidthPx(inputString: string, fontFamily : string, fontSize
           face.destroy();
           blob.destroy(); 
 
-          return totalX / 1000;
+          return totalX  / 1000;
   });
 }
 
@@ -523,7 +524,8 @@ async function drawText(pageIndex : number,
                 x : number,
                 y : number,
                 text : string){
-  let currentPage = pdfDoc.getPages()[0];
+  let pdfPages = pdfDoc.getPages();
+  let currentPage = pdfPages[pageIndex];
 
 const fcMatch = await spawnSync('fc-match', ['--format=%{file}', fontFamily]);
 const path = fcMatch.stdout.toString();
@@ -534,14 +536,14 @@ const path = fcMatch.stdout.toString();
 
   const rgbColor = await hexColorToRGB(color);
 
-  let a = await pdfDoc.getPage(0).drawText(text, {
+  let _ = await currentPage.drawText(text, {
     x: x,
     y: y,
     size: textSize,
     font: customFont,
     color: rgbColor,
   });
-  await pdfDoc.save();
+  
   
 }
 
@@ -918,7 +920,7 @@ async function interp(prog: AST, env: Env): Promise<AST> {
           || (env[vari.id][0].value as Item).type !=  replacer.type ){
             throw new Error("the type of replace and variable should be the same.")
           }else{
-            env[vari.id][0].value = prog[2];
+            env[vari.id][0].value = replacer;
             return {type:ItemType.Unit};
           }
         }
@@ -940,7 +942,7 @@ async function interp(prog: AST, env: Env): Promise<AST> {
             throw invalidLengthException('drawText', 6);
           }else{
             const fontFamily = (argsMapped[0] as ItemStr).str;
-            const textSize = (argsMapped[1] as ItemInt).int;
+            const textSize = (argsMapped[1] as ItemFlo).flo;
             const color = (argsMapped[2] as ItemStr).str;
             const x = (argsMapped[3] as ItemFlo).flo;
             const y = (argsMapped[4] as ItemFlo).flo;
@@ -958,6 +960,24 @@ async function interp(prog: AST, env: Env): Promise<AST> {
             }
           }
         }
+        // print to the console
+        else if (op.id === "print"){
+          if (prog.length !== 2){
+            throw invalidLengthException('print', 1);
+          }else{
+            let data = argsMapped[0];
+            let dataString;
+            if (data.hasOwnProperty("list")){
+              dataString = astToString(data, true);
+            }else{
+              dataString = astToString(data, false);
+            }
+            console.log(dataString);
+            return {
+              type:ItemType.Unit,
+            }
+          }
+        }
         // procedures returning the last called command
         else if (op.id === "begin"){
           const rtn = argsMapped[argsMapped.length-1];
index 3023dbdafb52eebf83c7799f7284e16c47706589..f0e1b2e50106c5789cec0cff5a4f53e6d6fbc71d 100644 (file)
--- a/text.lisp
+++ b/text.lisp
@@ -1,8 +1,8 @@
 (begin
 (define defaultFontFormat
-    '(("fontFamily" "Gentium")
+    '(("fontFamily" "FreeSerif")
       ("color" "#ff0000")
-      ("fontSize" 12)        
+      ("fontSize" 12.0)        
     )
 )
 
         (setDictItemAux dict '() key data)
 )))
 
+(define addDictItem (lambda (dict key data)
+    (if (= (dictRef dict key) false)
+        (extendDict dict key data)
+        dict
+    )
+))
+
 (define setDictItemAux (lambda (oldDict newDict key data)
 (if (= oldDict '()) newDict
 (if (= (car(car oldDict)) key)
     (setDictItemAux (cdr oldDict) (cons (car oldDict) newDict) key data)
 ))))
 
+
 (addPDFPage '())
 (addPDFPage '())
 (define text2boxAux2 (lambda (format text)
     (if (isList text)
+        // set font size
         (if (= (listRef text 0) "fontSize")
             (let ((newFormat (setDictItem format "fontSize" (listRef text 1)))) (text2boxAux1 newFormat (listRef text 2)))
             text)
-        (cons format (cons text '())))
+        (cons (cons "content" (cons text '())) format)
+    )
 ))
 
 (define text2boxAux1 (lambda (format txt) 
 (if (isList txt)
 (map (lambda (x) (text2boxAux2 format x)) txt)
-(cons format (cons txt '()))
+(cons  (cons "content" (cons txt '())) format)
+)))
+
+// (measureWidthPx "1314abc" "Gentium" 12.0)
+
+(define measureBoxItem (lambda (boxList) (map measureBoxItemAux boxList)))
+(define measureBoxItemAux (lambda (boxDict)
+   (let 
+    ((fontFamily (dictRef boxDict "fontFamily"))
+    (fontSize (dictRef boxDict "fontSize"))
+    (content (dictRef boxDict "content")))
+        (let
+            ((measuredWidthPx (measureWidthPx content fontFamily fontSize)))
+            (addDictItem boxDict "widthPx" measuredWidthPx)
+        )
+)))
+
+(define text2box (lambda (txt)
+    (let ((tmp1 (text2boxAux1 defaultFontFormat txt)))
+    (let ((res (measureBoxItem tmp1))) res)
 )))
 
-(define text2box (lambda (txt) (text2boxAux1 defaultFontFormat txt)))
 
 
 
 
-(drawText
-(dictRef defaultFontFormat "fontFamily")
-(dictRef defaultFontFormat "fontSize")
-(dictRef defaultFontFormat "color")
-40.0
-50.0
-"blah"
+//(drawText
+//(dictRef defaultFontFormat "fontFamily")
+//(dictRef defaultFontFormat "fontSize")
+//(dictRef defaultFontFormat "color")
+//40.0
+//50.0
+//"blah"
+//)
+(define x 0.0)
+
+(define text '("abracabra" ("fontSize" 18.0 "cat") "foo"))
+
+(define putOnChar (lambda (boxDict x)
+(let
+    ((content (dictRef boxDict "content"))
+    (fontFamily (dictRef boxDict "fontFamily"))
+    (fontSize (dictRef boxDict "fontSize"))
+    (color (dictRef boxDict "color"))
+    (widthPx (dictRef boxDict "widthPx"))
+    )
+    (begin
+    (drawText fontFamily fontSize color x 100.0 content)
+    (+ x widthPx)) // return an updated x
+
+)))
+
+(define putOnChars (lambda (ls x)
+                    (if (= ls '())
+                        '()
+                        (let 
+                        ((newX (putOnChar (car ls) x)))
+                        (putOnChars (cdr ls) newX))                
+                                ))
 )
-(define text '("abracabra" ("fontSize" 18 "貓") "foo"))
-(text2box text)
-(measureWidthPx "1314abc" "Gentium" 12.0)
+
+(let ((boxOfText (text2box text)))
+    (putOnChars boxOfText 0.0)
+)
+
+
+
+ (text2box text)
+// (measureWidthPx "1314abc" "Gentium" 12.0)
 )
\ No newline at end of file
index 335d5699028c25694bdf15c52c3e0319b518bde1..3fef8383e331f0c390319af5110d01b28a0c3d8f 100644 (file)
Binary files a/text.lisp.pdf and b/text.lisp.pdf differ