From 7287dfb2b9609e7dfc527a2d54a517f3ed47509d Mon Sep 17 00:00:00 2001 From: Owen Jeon Date: Thu, 8 Sep 2022 10:12:30 +0900 Subject: [PATCH 1/3] tsc --- lib/index.d.ts | 3 ++ lib/index.js | 137 +++++++++++++++++++++++++++++++++++++++++++------ package.json | 2 +- 3 files changed, 125 insertions(+), 17 deletions(-) diff --git a/lib/index.d.ts b/lib/index.d.ts index 3dcb5f5..f5603aa 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -1,4 +1,5 @@ /** @format */ +/// import { Command, flags } from "@oclif/command"; declare class Zigzi extends Command { static description: string; @@ -19,6 +20,8 @@ declare class Zigzi extends Command { marp(): Promise; toHtml(): Promise; toPdf(): Promise; + toPdfOfficial(): Promise; + mergePdfBuffers(target1: Buffer, target2: Buffer): Promise; setVSCodeSetting(): Promise; } export = Zigzi; diff --git a/lib/index.js b/lib/index.js index ae19ae5..acce84b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,8 +6,12 @@ const child_process = require("child_process"); const marked = require("marked"); const puppeteer = require("puppeteer"); const shell = require("shelljs"); +const pdfParse = require("pdf-parse"); +const opentype = require("opentype.js"); +const fm = require("front-matter"); const command_1 = require("@oclif/command"); const fs_1 = require("fs"); +const pdf_lib_1 = require("pdf-lib"); const convertCss = { zb_ppt: __dirname + "/../asset/ppt.css", zb_ppt_large: __dirname + "/../asset/ppt-large.css", @@ -36,7 +40,12 @@ class Zigzi extends command_1.Command { else { await this.toHtml(); if (output === "pdf") { - await this.toPdf(); + if (flags.template === "zb_official") { + await this.toPdfOfficial(); + } + else { + await this.toPdf(); + } } } } @@ -44,7 +53,9 @@ class Zigzi extends command_1.Command { async marp() { const { args, flags } = this.parse(Zigzi); let md = fs.readFileSync(this.file, "utf8"); - const cssFile = (md.indexOf("theme: ppt-large") > 0) ? convertCss["zb_ppt_large"] : convertCss["zb_ppt"]; + const cssFile = md.indexOf("theme: ppt-large") > 0 + ? convertCss["zb_ppt_large"] + : convertCss["zb_ppt"]; const pdfFileName = `${this.file.replace(".md", ".pdf")}`; await child_process.execSync(`npx @marp-team/marp-cli@latest --allow-local-files ${this.file} -o ${pdfFileName} --theme ${cssFile}`); } @@ -52,19 +63,25 @@ class Zigzi extends command_1.Command { const { flags } = this.parse(Zigzi); const cssType = convertCss[this.converType]; const htmlFileName = `${this.file.replace(".md", ".html")}`; - let md = fs.readFileSync(this.file, "utf8"); + const md = fs.readFileSync(this.file, "utf8"); + let css = fs.readFileSync(cssType, "utf8"); const pageBreak = //g; - md = md.replace(pageBreak, `
`); - md = md.replace(RegExp(//g), ""); + const modifiedMd = md + .replace(pageBreak, `
`) + .replace(RegExp(//g), "") + .replace(/^---$.*^---$/ms, ""); let markedHtml; if (flags.template === "zb_official") { - markedHtml = `
${marked(md)}
`; + const { attributes: { 주소, 전화번호 } = { 주소: "", 전화번호: "" }, } = fm(md); + markedHtml = `
${marked(modifiedMd)}
`; + css += `header::after{ + content: "${주소}\\ATel) ${전화번호}" + }`; } else { - markedHtml = marked(md); + markedHtml = marked(modifiedMd); } - const css = fs.readFileSync(cssType, "utf8"); const html = ` @@ -84,9 +101,6 @@ class Zigzi extends command_1.Command { const { flags } = this.parse(Zigzi); const htmlFileName = `${this.file.replace(".md", ".html")}`; const pdfFileName = `${this.file.replace(".md", ".pdf")}`; - const headerFooterTemplate = (flags.template === "zb_doc") ? { - displayHeaderFooter: true - } : {}; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto(`file://${path.resolve(htmlFileName)}`, { @@ -99,7 +113,7 @@ class Zigzi extends command_1.Command { printBackground: true, headerTemplate: `
`, footerTemplate: ``, - displayHeaderFooter: (flags.template === "zb_doc"), + displayHeaderFooter: flags.template === "zb_doc", margin: { top: 50, bottom: 50, @@ -110,13 +124,104 @@ class Zigzi extends command_1.Command { await browser.close(); await fs.unlinkSync(`${htmlFileName}`); } + async toPdfOfficial() { + const md = fs.readFileSync(this.file, "utf8"); + const { attributes: { footer = [] }, } = fm(md); + const htmlFileName = `${this.file.replace(".md", ".html")}`; + const pdfFileName = `${this.file.replace(".md", ".pdf")}`; + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + await page.goto(`file://${path.resolve(htmlFileName)}`, { + waitUntil: "networkidle2", + timeout: 60000 * 2, + }); + await page.emulateMediaType("screen"); + const font = opentype.loadSync(path.resolve(__dirname, "../asset/SpoqaHanSansBold.ttf")); + const footerSvg = footer + .map((str) => { + const p = font.getPath(str, 0, 0, 21); + const { x1, x2, y1, y2 } = p.getBoundingBox(); + const height = y2 - y1; + const width = x2 - x1; + const svgPath = p.toSVG(2); + return `${svgPath}`; + }) + .join(""); + const headerTemplate = "
"; + const footerTemplate = ` + + + `; + const baseOpt = { + format: "a4", + path: `${path.resolve(pdfFileName)}`, + headerTemplate, + footerTemplate, + displayHeaderFooter: true, + margin: { + top: 50, + bottom: 50, + left: 58, + right: 58, + }, + timeout: 1000 * 60 * 10, + }; + await page.pdf(baseOpt); + const dataBuffer = fs.readFileSync(path.resolve(pdfFileName)); + const pdfInfo = await pdfParse(dataBuffer); + const numPages = pdfInfo.numpages; + if (numPages === 1) { + await page.addStyleTag({ + path: path.resolve(__dirname, "../asset/official-single-page-footer.css"), + }); + await page.pdf(Object.assign(Object.assign({}, baseOpt), { displayHeaderFooter: false })); + } + else { + const restBuffer = await page.pdf(Object.assign(Object.assign({}, baseOpt), { displayHeaderFooter: false, pageRanges: `-${numPages - 1}` })); + const lastPdfName = `${pdfFileName}-last.pdf`; + const lastBuffer = await page.pdf(Object.assign(Object.assign({}, baseOpt), { displayHeaderFooter: true, pageRanges: `${numPages}`, path: lastPdfName })); + await fs.unlinkSync(lastPdfName); + const mergedPdfBuffer = await this.mergePdfBuffers(restBuffer, lastBuffer); + await fs.writeFileSync(`${path.resolve(pdfFileName)}`, mergedPdfBuffer); + } + await browser.close(); + await fs.unlinkSync(`${htmlFileName}`); + } + async mergePdfBuffers(target1, target2) { + const pdf1 = await pdf_lib_1.PDFDocument.load(target1); + const pdf2 = await pdf_lib_1.PDFDocument.load(target2); + const mergedPdf = await pdf_lib_1.PDFDocument.create(); + const copiedPagesA = await mergedPdf.copyPages(pdf1, pdf1.getPageIndices()); + copiedPagesA.forEach((page) => mergedPdf.addPage(page)); + const copiedPagesB = await mergedPdf.copyPages(pdf2, pdf2.getPageIndices()); + copiedPagesB.forEach((page) => mergedPdf.addPage(page)); + return await mergedPdf.save(); + } async setVSCodeSetting() { const location = shell.exec("pwd"); - const setting_location = process.platform === "win32" ? "%APPDATA%\/Code\/User\/" : "~/Library/Application Support/Code/User/"; + const setting_location = process.platform === "win32" + ? "%APPDATA%/Code/User/" + : "~/Library/Application Support/Code/User/"; JSON.stringify; shell.cd(setting_location); shell.exec("pwd"); - const settingsBuffer = await (0, fs_1.readFileSync)("settings.json", { encoding: "utf8" }); + const settingsBuffer = await (0, fs_1.readFileSync)("settings.json", { + encoding: "utf8", + }); let settings = settingsBuffer; const css = ` "https://zigbang.github.io/zigzi/asset/ppt.css", @@ -151,7 +256,7 @@ Zigzi.flags = { }), vscode: command_1.flags.boolean({ description: "vscode markdown template setting", - }) + }), }; Zigzi.args = [ { diff --git a/package.json b/package.json index 501d975..7e4045e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zigzi", - "version": "1.0.6", + "version": "1.0.9", "author": "ZIGBANG Co., Ltd.", "keywords": [ "zigbang", From 555f5016e6930df7e6fc9f43329274877802ab12 Mon Sep 17 00:00:00 2001 From: Owen Jeon Date: Thu, 8 Sep 2022 10:18:30 +0900 Subject: [PATCH 2/3] fix typo --- lib/index.js | 18 +++++++++--------- package.json | 2 +- sample/official.pdf | Bin 96464 -> 96464 bytes src/index.ts | 18 +++++++++--------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/index.js b/lib/index.js index acce84b..fdf62ec 100644 --- a/lib/index.js +++ b/lib/index.js @@ -151,15 +151,15 @@ class Zigzi extends command_1.Command { const footerTemplate = `