Global

Members

WMd2docx

Description:
  • Markdown轉Docx工具集

    匯整五個入口:cvMdToDocx(md檔轉docx檔)、cvMdTo(md內容轉html/docx之base64)、addDocxToc(既有docx添加章節目錄、圖目錄、表目錄並重編頁碼)、rmApiServer(hapi轉檔服務)、rmApiClient(呼叫轉檔服務之用戶端)。

Source:

Markdown轉Docx工具集

匯整五個入口:cvMdToDocx(md檔轉docx檔)、cvMdTo(md內容轉html/docx之base64)、addDocxToc(既有docx添加章節目錄、圖目錄、表目錄並重編頁碼)、rmApiServer(hapi轉檔服務)、rmApiClient(呼叫轉檔服務之用戶端)。

Example
import WMd2docx from 'w-md2docx/src/WMd2docx.mjs'

let r = await WMd2docx.cvMdToDocx('./test/report.md', './test/report.docx')
console.log(r)
// => { fpOutDocx: '…', sizeDocx: 39856, sizeHtml: 12345, ms: 8342 }

Methods

(async) addDocxToc(fpDocx, optopt) → {Promise}

Description:
  • 於docx添加章節目錄、圖目錄、表目錄並重編頁碼

    先以純結構處理準備內容(見docxToc.mjs之prepDocxToc:圖名表名編號改SEQ欄位、標題粗體改由樣式提供、插入目錄欄位、分節與頁碼),再以本機Microsoft Word更新欄位(目錄內容與頁碼只有Word能算),最後逐項核對目錄項目、連結落點、頁碼與分節,全部相符才覆寫原檔。故僅能於已安裝Word之Windows執行,Word之調用與轉檔共用同一佇列。

    頁碼:第1個標題前有內容者視為封面,封面無頁碼;前置章節與目錄為大寫羅馬數字(I起);正文自1起。無封面者不另建封面頁。

    標題以段落之大綱階層判斷,第1個標題即視為正文之始(前置章節除外):Markdown以單一#為文件標題、##為章者,文件標題會列為目錄第1層且正文自其起算;欲置於封面請以非標題之段落撰寫(如

    )。

    Word更新以cscript執行updateDocxToc.vbs(VBScript):微軟已公告VBScript將轉為選用功能並於日後移除,屆時須另行啟用或改以其他方式調用Word。逾時被終止時,經COM啟動之WINWORD行程可能殘留,須人工確認後結束。

    文件無標題段落時不處理並於回傳之skip說明原因;前提不符或核對不符時reject,原檔不變。

Source:
Example
import addDocxToc from 'w-md2docx/src/addDocxToc.mjs'

let r = await addDocxToc('./report.docx')
console.log(r)
// => { skip: '', cover: true, levels: [1, 2], front: [], lists: ['toc', 'fig', 'tab'], toc: 58, fig: 246, tab: 55, pagesFirst: '1', pages: 170, warns: [], ms: 12500 }
Parameters:
Name Type Attributes Default Description
fpDocx String

輸入docx檔位置字串,處理成功時就地覆寫

opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
labels Object <optional>
{fig:'圖',tab:'表'}

輸入圖名、表名之標籤(段首「圖N」「表N」,編號後須接空白),須為不含空白與引號之非空字串且兩者不同,英文報告可給{fig:'Figure',tab:'Table'}

titles Object <optional>
{toc:'目錄',fig:'圖目錄',tab:'表目錄'}

輸入三目錄之標題

frontHeadings Array <optional>
['摘要','ABSTRACT','Abstract']

輸入前置章節之標題文字,文件開頭之標題與之相同者排在封面與目錄之間且不列入目錄

maxLevels Integer <optional>
3

輸入目錄列出之標題層數(自正文最高之大綱階層起算),上限9

titleStyle String <optional>
'TPC11報告目錄(標題)'

輸入三目錄標題之段落樣式名稱(預設為本套件所附temp_tpc.docx之樣式),模板無此樣式時另建置中粗體樣式

headStyles Array <optional>
['章標題','節標題','小節標題']

輸入承接標題粗體之段落樣式名稱(依層),模板已有同名樣式時須為粗體

pageNumbers Boolean <optional>
true

輸入是否分節重編頁碼,false時只插入三目錄(各自起新頁),不動分節與頁碼

keepLines Boolean <optional>
true

輸入是否將目錄來源段落(列入目錄之標題、圖名、表名)設為段落內不分頁,使目錄之頁碼即該段落所在之頁(多行之表名跨頁時,首行留在前頁而表格在次頁,表目錄之頁碼會指向前頁)

keepWithObject Boolean <optional>
true

輸入是否使圖名、表名與其圖、表同頁(與keepCaption同一規則,見docxKeep.mjs之planKeepNext):與下段之表格或圖片、或上段之圖片同頁,上下皆有圖表時依同類圖名表名之多數位置,平手時圖名取上段、表名取下段(圖在頁底而圖名被擠到次頁時,圖目錄之頁碼會指向次頁)

replaceTocStyles Boolean <optional>
true

輸入是否以本套件之目錄項目樣式(第1層粗體、下層縮排並懸掛縮排、點線引導頁碼,字型沿用正文第1個標題)取代模板既有之toc N與table of figures樣式,false時沿用模板既有者、僅補建缺少者

timeoutMs Integer <optional>
1800000

輸入Word更新之逾時毫秒數,預設1800000(30分鐘)

Returns:

回傳Promise,resolve回傳{skip,cover,levels,front,lists,toc,fig,tab,pagesFirst,pages,warns,ms}(toc、fig、tab為各目錄之項目數,lists為實際插入之目錄,pagesFirst為目錄第1項之頁碼),無標題時僅回傳{skip,ms};reject回傳錯誤訊息字串

Type
Promise

addKeepLines(p) → {String}

Description:
  • 段落設為段落內不分頁(w:keepLines)

    已有者原樣回傳;新增時依pPr子元素順序置於pStyle、keepNext之後。

Source:
Parameters:
Name Type Description
p String

輸入段落XML字串

Returns:

回傳段落XML字串

Type
String

addKeepNext(p) → {String}

Description:
  • 段落設為與下段同頁(w:keepNext)

    已有者原樣回傳;新增時依pPr子元素順序置於pStyle之後。

Source:
Parameters:
Name Type Description
p String

輸入段落XML字串

Returns:

回傳段落XML字串

Type
String

checkDocxReady() → {Object}

Description:
  • 檢查本機是否具備docx轉檔條件

    ready僅以作業系統為Windows判定,不以轉檔器是否存在為條件:exeFound為false代表轉檔器目前尚未取得,將於首次轉檔時由w-html2docx自動下載,並非不可用。

    注意:僅代表環境條件成立,不代表轉檔器可下載成功或Word確實可被調用;後二者須實際轉一份小檔驗證。

Source:
Example
console.log(checkDocxReady())
// => { platform: 'win32', isWindows: true, cwd: '...', exePath: '', exeFound: false, ready: true }
Returns:

回傳狀態物件{platform,isWindows,cwd,exePath,exeFound,ready},exePath與exeFound為轉檔器目前所在位置與是否已存在(診斷用)

Type
Object

checkDocxToc(u8, info) → {Object}

Description:
  • 核對Word更新後之目錄

    逐項取出目錄、圖目錄、表目錄之項目,檢查:項目與預期之標題、圖名、表名逐一相同且順序相同、各項為超連結且其書籤落在同文字之段落、頁碼為依序不遞減之數字、應有之目錄欄位皆存在;分節時另查各節之頁尾與頁碼設定(有封面3節,無封面2節)。

Source:
Parameters:
Name Type Description
u8 Uint8Array

輸入Word更新後之docx內容

info Object

輸入prepDocxToc回傳之info

Returns:

回傳{ok,errs,stats},errs為不符之說明字串陣列,stats為{toc,fig,tab,pagesFirst},分別為各目錄之項目數與目錄第1項之頁碼

Type
Object

cleanWorkDir(dirWork, optopt) → {Integer}

Description:
  • 清除工作資料夾內逾時未刪之作業夾(前綴job_)

    工作資料夾不存在時自動建立。

Source:
Example
let n = cleanWorkDir('./tmp', { msAge: 3600 * 1000 })
// => 2
Parameters:
Name Type Attributes Default Description
dirWork String

輸入工作資料夾位置字串

opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
msAge Number <optional>
21600000

輸入視為逾時之毫秒數,預設6小時(21600000)

Returns:

回傳刪除之作業夾數整數

Type
Integer

createEdits() → {Object}

Description:
  • 建立段落改寫之登錄表

    以段落起點為鍵登錄改寫函數(依登錄順序套用)與插於段落前之內容,apply時由後往前套用,使各段落之位置不受前段改寫影響。

Source:
Returns:

回傳{addEdit(p,fn),addPre(p,s),apply(doc)},apply回傳改寫後之doc

Type
Object

(async) cvMdTo(optopt) → {Promise}

Description:
  • Markdown內容轉Html與Docx內容

    與cvMdToDocx之差異:本函數接收Markdown「內容」與其引用之資產(圖片等),於獨立工作資料夾內還原後轉檔,完成後回傳產物之base64內容並清除工作資料夾。適用於服務端等無實體來源檔之情境;有實體md檔者請直接用cvMdToDocx。

Source:
Example
import cvMdTo from 'w-md2docx/src/cvMdTo.mjs'

let r = await cvMdTo({
    md: '# 標題\n\n<img src="pics/圖.png" />',
    name: '報告R00.01',
    out: 'docx',
    assets: [{ path: 'pics/圖.png', base64: '…' }],
})
console.log(r)
// => { name: '報告R00.01', out: 'docx', ms: 8342, nAssets: 1, msDocx: 8300, docx: { fileName: '報告R00.01.docx', mime: '…', size: 39856, base64: '…' } }
Parameters:
Name Type Attributes Default Description
opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
md String <optional>
''

輸入Markdown內容字串,與mdBase64二擇一

mdBase64 String <optional>
''

輸入Markdown內容之base64字串,與md二擇一

name String <optional>
'output'

輸入輸出檔名主體字串(不含副檔名),將自動移除路徑成分與非法字元,預設'output'

out String <optional>
'docx'

輸入產出類型字串,可為'html'、'docx'、'both',預設'docx'

assets Array <optional>
[]

輸入md內引用之相對路徑資產陣列,格式[{path,base64}],預設[]

dirWork String <optional>
''

輸入工作資料夾根位置字串,未給則用系統暫存夾下之w-md2docx,預設''

fpInTemp String <optional>
''

輸入Docx模板檔位置字串,未給則由w-html2docx使用其內建模板,預設''

optMd2html Object <optional>
{}

輸入傳予w-md2html之設定物件,預設{}

optHtml2docx Object <optional>
{}

輸入傳予w-html2docx之設定物件,其imgHeightReserveLines未給時由cvMdToDocx預設4(行格線模板之圖片下方預留格數,給null停用),預設{}

keepWork Boolean <optional>
false

輸入是否保留工作資料夾供除錯布林值,預設false

keepCaption Boolean | Object <optional>
false

輸入是否使圖名、表名與其圖、表同頁(true或{labels}),傳予cvMdToDocx,僅於產出docx時有效,預設false

toc Boolean | Object <optional>
false

輸入是否添加章節目錄、圖目錄、表目錄並重編頁碼(true或addDocxToc之設定物件),傳予cvMdToDocx,僅於產出docx時有效,預設false

Returns:

回傳Promise,resolve回傳結果物件{name,out,ms,nAssets,[msDocx],[html],[docx],[keepCaption],[toc]},其中html與docx為{fileName,mime,size,base64},keepCaption與toc為cvMdToDocx之同名結果(有要求且產出docx時才有),reject回傳錯誤訊息

Type
Promise

(async) cvMdTo(optopt) → {Promise}

Description:
  • 將本機Markdown檔送至轉檔服務,取回並寫出Html與(或)Docx

    供無Microsoft Word之機器產製docx:讀取本機md與其引用之圖片,送至rmApiServer轉檔後寫回本機。連線層失敗會自動重試;逾時與HTTP錯誤不重試。

Source:
Example
import { cvMdTo } from 'w-md2docx/src/rmApiClient.mjs'

let r = await cvMdTo({
    host: '127.0.0.1',
    port: 22000,
    fpInMd: './test/report.md',
    fpOutDocx: './test/report.docx',
})
console.log(r)
// => { ms: 8342, nAssets: 1, template: 'default', docx: { fp: '…', size: 39856 } }
Parameters:
Name Type Attributes Default Description
opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
host String <optional>
'127.0.0.1'

輸入服務主機位址(ip或網域)字串,未給則取環境變數WMD2DOCX_HOST,再無則用'127.0.0.1',預設'127.0.0.1'

port Integer <optional>
22000

輸入服務埠號整數,未給則取環境變數WMD2DOCX_PORT,再無則用22000,預設22000

url String <optional>
''

輸入服務完整位址字串(如'https://host/prefix'),給予時覆寫host與port,預設''

fpInMd String

輸入來源Markdown檔位置字串

fpOutDocx String <optional>
''

輸入轉出Docx檔位置字串,與fpOutHtml皆未給時預設於md旁產出同名docx,預設''

fpOutHtml String <optional>
''

輸入轉出Html檔位置字串,預設''

fpInTemp String <optional>
''

輸入本機Docx模板檔位置字串,給予時以base64夾帶至服務端,預設''

templateName String <optional>
''

輸入服務端模板檔名字串,預設''

name String <optional>
''

輸入輸出檔名主體字串,未給則取md檔名,預設''

token String <optional>
''

輸入x-api-token字串,未給則取環境變數WMD2DOCX_TOKEN,預設''

optMd2html Object <optional>

輸入傳予w-md2html之設定物件

optHtml2docx Object <optional>

輸入傳予w-html2docx之設定物件,其imgHeightReserveLines未給時由服務端預設4(行格線模板之圖片下方預留格數,給null停用,見cvMdToDocx)

allowMissingAssets Boolean <optional>
false

輸入是否容許md引用之資產檔不存在布林值,預設false

keepCaption Boolean | Object <optional>
false

輸入是否於服務端使圖名、表名與其圖、表同頁(true或{labels});有產出docx而服務端回應未帶其結果時(服務端版本不支援)reject且不寫檔,預設false

toc Boolean | Object <optional>
false

輸入是否於服務端添加章節目錄、圖目錄、表目錄並重編頁碼(true或addDocxToc之設定物件,其timeoutMs由服務端決定而不採用);有產出docx而服務端回應未帶目錄結果時(服務端版本不支援)reject且不寫檔,預設false

timeoutMs Number <optional>
600000

輸入逾時毫秒數,轉檔含Word啟動故預設10分鐘,預設600000

retries Integer <optional>
3

輸入連線層失敗之重試次數整數,預設3

Returns:

回傳Promise,resolve回傳結果物件{ms,nAssets,template,[html],[docx],[keepCaption],[toc]},其中html與docx為{fp,size},keepCaption與toc為服務端之同名結果,reject回傳錯誤訊息

Type
Promise

(async) cvMdToDocx(fpInMd, fpOutDocx, optopt) → {Promise}

Description:
  • Markdown檔轉Docx檔

    內部流程為md -> html -> docx。docx階段係調用本機Microsoft Word(win32com),故僅能於已安裝Word之Windows執行,且同時間僅一份轉檔作業(內部佇列自動排隊)。

    轉檔器htmlToDocx.exe之定位與補齊由w-html2docx負責:其以當前工作目錄(cwd)查找,缺檔(如npm封鎖安裝腳本致postinstall未執行)時於轉檔當下自動下載,故須於含node_modules/w-html2docx之專案根執行,且首次轉檔須可連網。

    w-html2docx(≥1.0.29)於轉檔器失敗(Word未安裝、模板無法開啟、另存失敗等)時以離開碼1 reject並帶轉檔器回報之原因,resolve前亦自行確認docx已產生;本函數將其訊息加上前綴原樣傳出,並再以產物實體檔之存在與大小把關一次,不會回報假成功。

Source:
Example
import cvMdToDocx from 'w-md2docx/src/cvMdToDocx.mjs'

let r = await cvMdToDocx('./test/report.md', './test/report.docx', {
    fpInTemp: './src/templates/temp_tpc.docx',
    optMd2html: {
        imgWidthMax: '500px',
    },
    toc: true,
})
console.log(r)
// => { fpOutDocx: '…', sizeDocx: 41210, sizeHtml: 12345, ms: 12342, toc: { skip: '', cover: true, levels: [2, 4], lists: ['toc'], toc: 26, … } }
Parameters:
Name Type Attributes Default Description
fpInMd String

輸入來源Markdown檔位置字串

fpOutDocx String

輸入轉出Docx檔位置字串

opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
fpInTemp String <optional>
''

輸入Docx模板檔位置字串,未給則由w-html2docx使用其內建模板,預設''

fpOutHtml String <optional>
''

輸入另存中介Html檔位置字串,未給則中介檔產於系統暫存夾並於轉檔後刪除,預設''

optMd2html Object <optional>
{}

輸入傳予w-md2html之設定物件(如imgWidthMax、fontSizeScale等),預設{}

optHtml2docx Object <optional>
{}

輸入傳予w-html2docx之設定物件(如imgRatioWidthMax、fontFamilies等),其imgHeightReserveLines未給時預設4:行格線模板之圖片下方預留4格,供圖區塊間之空段落與至多2行之圖名使用,使整頁高之圖片與其圖名可同頁,無行格線之模板不生效,給null停用(見w-html2docx),預設{}

keepCaption Boolean | Object <optional>
false

輸入是否使圖名、表名與其圖、表同頁(不依附目錄):轉檔後圖名表名設段落內不分頁,並與其下之表格或圖片、或其上之圖片設為同頁(可越過空段落;上下皆有圖表時依同類圖名表名之多數位置,平手時圖名取上方、表名取下方,見docxKeep.mjs之planKeepNext),於添加目錄之前執行;true用預設,物件可給{labels}(見docxKeep.mjs之prepDocxKeep,與toc之labels各自獨立);處理失敗時刪除本次產出之docx並reject,預設false

toc Boolean | Object <optional>
false

輸入是否添加章節目錄、圖目錄、表目錄並重編頁碼(封面無頁碼、目錄為大寫羅馬數字、正文自1起),true用預設,物件為addDocxToc之設定(見addDocxToc.mjs);添加失敗時刪除本次產出之docx並reject,預設false

Returns:

回傳Promise,resolve回傳結果物件{fpOutDocx,sizeDocx,sizeHtml,ms,[fpOutHtml],[keepCaption],[toc]},keepCaption為{figs,tabs,keepNext,keepLines,changed,warns,ms}(圖名數、表名數、新增與下段同頁及段落內不分頁之段落數、是否改寫、提示、耗時),toc為addDocxToc之結果(文件無標題時僅含skip與ms),reject回傳錯誤訊息

Type
Promise

esc(s) → {String}

Description:
  • 跳脫XML文字與屬性值之特殊字元

Source:
Parameters:
Name Type Description
s *

輸入資料,轉字串後跳脫

Returns:

回傳跳脫後字串

Type
String

escRe(s) → {String}

Description:
  • 跳脫正則表達式之特殊字元

Source:
Parameters:
Name Type Description
s *

輸入資料,轉字串後跳脫

Returns:

回傳跳脫後字串

Type
String

findCaptions(tops, labels) → {Object}

Description:
  • 找出圖名與表名

    圖名、表名為段首「標籤+編號+空白」之段落(標籤與編號間可有空白);段首為標籤與編號而其後非空白者(如「圖1:名稱」)不視為圖名表名,另行列出供提示。

Source:
Parameters:
Name Type Description
tops Array

輸入候選段落陣列(scanParas之元素,呼叫端須先排除表格內等不適用之段落)

labels Object

輸入標籤物件{fig,tab}

Returns:

回傳{caps,capsLike},caps之元素為段落另加{kind,num,s,e,text}(kind為'fig'或'tab',s與e為編號於段落文字之起訖位置),capsLike為疑似圖名表名之段落文字陣列

Type
Object

getFpExe() → {String}

Description:
  • 取w-html2docx之htmlToDocx.exe目前所在位置(僅供診斷顯示)

    依w-html2docx之查找位置(cwd之src/、cwd之node_modules/w-html2docx/src/)查詢檔案「目前」是否存在,不下載。

    注意:不得作為轉檔前之守門。查無不代表無法轉檔——w-html2docx於轉檔當下會自動下載缺少之轉檔器,上層以此攔截會使該機制永遠不被執行。

Source:
Example
console.log(getFpExe())
// => 'C:\\proj\\node_modules\\w-html2docx\\src\\htmlToDocx.exe'
Returns:

回傳exe位置字串,目前不存在則回傳空字串

Type
String

getFpVbs(fdopt) → {String}

Description:
  • 取Word更新腳本updateDocxToc.vbs之位置

    依序查找模組所在資料夾、其上層之src資料夾:以src執行時腳本位於同層;以打包後之dist執行時模組位於dist,腳本則隨套件之src發布,故另查../src。

Source:
Example
import { getFpVbs } from 'w-md2docx/src/addDocxToc.mjs'

console.log(getFpVbs())
// => 'D:\\…\\node_modules\\w-md2docx\\src\\updateDocxToc.vbs'
Parameters:
Name Type Attributes Description
fd String <optional>

輸入模組所在資料夾位置字串,未給則為本模組所在資料夾

Returns:

回傳腳本之絕對路徑字串,查無則回傳空字串

Type
String

getQueueSize() → {Integer}

Description:
  • 取當前排隊中(含執行中)之docx轉檔數

Source:
Example
console.log(getQueueSize())
// => 0
Returns:

回傳排隊數整數

Type
Integer

hasObj(p) → {Boolean}

Description:
  • 判斷段落是否含圖片或內嵌物件

Source:
Parameters:
Name Type Description
p Object

輸入段落(scanParas之元素)

Returns:

回傳是否含圖片或內嵌物件

Type
Boolean

(async) health(optopt) → {Promise}

Description:
  • 查詢轉檔服務之健康狀態

Source:
Example
import { health } from 'w-md2docx/src/rmApiClient.mjs'

let r = await health({ host: '127.0.0.1', port: 22000 })
console.log(r)
// => { success: true, platform: 'win32', docxReady: true, … }
Parameters:
Name Type Attributes Default Description
opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
host String <optional>
'127.0.0.1'

輸入服務主機位址(ip或網域)字串,未給則取環境變數WMD2DOCX_HOST,再無則用'127.0.0.1',預設'127.0.0.1'

port Integer <optional>
22000

輸入服務埠號整數,未給則取環境變數WMD2DOCX_PORT,再無則用22000,預設22000

url String <optional>
''

輸入服務完整位址字串,給予時覆寫host與port,預設''

token String <optional>
''

輸入x-api-token字串,未給則取環境變數WMD2DOCX_TOKEN,預設''

timeoutMs Number <optional>
20000

輸入逾時毫秒數,預設20000

Returns:

回傳Promise,resolve回傳服務端回傳之狀態物件,reject回傳錯誤訊息

Type
Promise

isBlank(p) → {Boolean}

Description:
  • 判斷段落是否為可越過之空段落

    不在表格內、無文字、無圖片與物件、其前其後皆不分頁或分節者為空段落(如w-md2html之換行標記轉檔後之段落),判斷圖名表名與其圖表是否相鄰時可越過。

Source:
Parameters:
Name Type Description
p Object

輸入段落(scanParas之元素)

Returns:

回傳是否為可越過之空段落

Type
Boolean

isBrkAfter(p) → {Boolean}

Description:
  • 判斷段落之後是否分頁或分節

    含分節設定或分頁、分欄符號者為是。

Source:
Parameters:
Name Type Description
p Object

輸入段落(scanParas之元素)

Returns:

回傳段落之後是否分頁或分節

Type
Boolean

isBrkBefore(p) → {Boolean}

Description:
  • 判斷段落之前是否分頁

    設段落前分頁(未設為關閉)或含分頁、分欄符號者為是。

Source:
Parameters:
Name Type Description
p Object

輸入段落(scanParas之元素)

Returns:

回傳段落之前是否分頁

Type
Boolean

isPicPara(p) → {Boolean}

Description:
  • 判斷段落是否為圖片段落

    含圖片或內嵌物件而無文字者為圖片段落;水平線(如md之---經Word匯入之VML橫線,帶o:hr)不算。

Source:
Parameters:
Name Type Description
p Object

輸入段落(scanParas之元素)

Returns:

回傳是否為圖片段落

Type
Boolean

normKeepReq(keepCaption) → {Boolean|Object}

Description:
  • 整理服務端請求之圖名表名同頁設定

    同normReqOpt,回傳false、true或設定物件之複本。

Source:
Example
console.log(normKeepReq({ labels: { fig: 'Figure', tab: 'Table' } }))
// => { labels: { fig: 'Figure', tab: 'Table' } }
Parameters:
Name Type Description
keepCaption *

輸入請求之keepCaption

Returns:

回傳false、true或設定物件

Type
Boolean | Object

normLabels(labelsopt) → {Object}

Description:
  • 整理圖名表名之標籤

    fig與tab須為不含空白、引號與反斜線之非空字串(添加目錄時其亦為SEQ欄位之識別名稱,並置於TOC欄位之\c參數內),否則該項退回預設;兩者相同時無法區分圖名與表名,皆退回預設。

Source:
Parameters:
Name Type Attributes Default Description
labels Object <optional>
{}

輸入標籤物件{fig,tab},預設{}

Returns:

回傳標籤物件{fig,tab}

Type
Object

normReqOpt(v, omitopt) → {Boolean|Object}

Description:
  • 整理服務端請求之開關或設定物件

    值為true或字串'true'時回傳true;為物件時回傳移除omit所列鍵後之複本;其餘回傳false。供toc、keepCaption等「true或設定物件」型之請求參數共用。

Source:
Example
console.log(normReqOpt('true'))
// => true

console.log(normReqOpt({ a: 1, b: 2 }, ['b']))
// => { a: 1 }
Parameters:
Name Type Attributes Default Description
v *

輸入請求之值

omit Array <optional>
[]

輸入不由請求端決定而須移除之鍵陣列,預設[]

Returns:

回傳false、true或設定物件

Type
Boolean | Object

normTocOpt(optopt) → {Object}

Description:
  • 整理添加目錄之設定

    各設定非有效值時採預設:labels見docxKeep.mjs之normLabels(fig與tab須為不含空白、引號與反斜線之非空字串,否則該項退回預設,兩者相同時皆退回預設);titles之各值須為非空字串;frontHeadings須為陣列(僅保留非空字串);maxLevels須為正整數,上限9;titleStyle須為非空字串;headStyles須為非空字串組成之非空陣列;pageNumbers、keepLines、keepWithObject、replaceTocStyles須為布林值。

Source:
Parameters:
Name Type Attributes Default Description
opt Object | Boolean <optional>
{}

輸入設定物件,true或非物件時皆用預設,預設{}

Returns:

回傳設定物件{labels,titles,frontHeadings,maxLevels,titleStyle,titleStyleGiven,headStyles,pageNumbers,keepLines,keepWithObject,replaceTocStyles},titleStyleGiven表示titleStyle是否由呼叫端指定

Type
Object

normTocReq(toc) → {Boolean|Object}

Description:
  • 整理服務端請求之目錄設定

    同normReqOpt,另移除timeoutMs:Word更新之逾時屬服務端資源控管,不由請求端決定,否則請求端可用極短逾時反覆中斷Word更新,使經COM啟動之WINWORD行程殘留。

Source:
Example
console.log(normTocReq({ maxLevels: 2, timeoutMs: 1 }))
// => { maxLevels: 2 }
Parameters:
Name Type Description
toc *

輸入請求之toc

Returns:

回傳false、true或設定物件

Type
Boolean | Object

pPrOf(p) → {String}

Description:
  • 取段落之段落屬性w:pPr(須為段落之第1個子元素)

Source:
Parameters:
Name Type Description
p String

輸入段落XML字串

Returns:

回傳w:pPr元素字串,無則回傳空字串

Type
String

planKeepNext(doc, paras, caps, isSkipopt) → {Array}

Description:
  • 找出須設與下段同頁之段落,使圖名、表名與其圖、表同頁

    圖名表名之候選:下段為表格或圖片段落(見isPicPara)者,圖名表名在上,設圖名表名與下段同頁;上段為圖片段落者,圖名表名在下,設該圖片段落與下段同頁;上段為表格者,圖名表名在表格下方,不設(表格整體同頁須設其每一列,不處理),僅供判斷歧義與歸屬。上下段須相鄰:兩者之間只有空白或書籤,並可越過空段落(見isBlank),越過之空段落一併設與下段同頁;兩者之間分頁或分節(圖名表名或其圖表段落之前或之後,見isBrkBefore、isBrkAfter)即不相鄰。表格內之段落不作圖片段落。

    只有一方有候選者與該方同頁。上下皆有候選者(如連續之圖:圖、圖名、圖、圖名),依同類(圖名或表名)只有一方有候選者之多數位置取向:在上者多取下段,在下者多取上段,平手時圖名取上段、表名取下段(圖名在圖下方、表名在表上方之慣例)。一張圖表只歸屬一方:取向之一方已歸屬其他圖名表名而另一方未歸屬時改取另一方,兩方皆已歸屬時不設;取下段者自文件末往前、取上段者自文件首往後依序歸屬,使歸屬自與取向相反之圖名表名處延續。兩個只有一方有候選之圖名表名夾同一張圖時兩者皆設(無從判斷屬誰)。

Source:
Parameters:
Name Type Attributes Description
doc String

輸入document.xml字串

paras Array

輸入scanParas之結果

caps Array

輸入findCaptions之caps

isSkip function <optional>

輸入不參與判斷之段落之判斷函數(如文字方塊內或含文字方塊之段落),遇之即視為不相鄰,預設皆參與

Returns:

回傳須設與下段同頁之段落陣列(可能重複)

Type
Array

prepDocxKeep(u8, optopt) → {Object}

Description:
  • 準備圖名、表名與其圖、表同頁之docx內容(純結構處理, 不需Word)

    圖名表名設段落內不分頁(keepLines),並依planKeepNext設與下段同頁(keepNext),不依附目錄:編號不連續、分節不只1個、無標題、已有目錄欄位皆照常處理。文字方塊內之段落為巢狀段落,正則切段會截斷含文字方塊之段落,故文字方塊內與含文字方塊之段落不作圖名表名亦不作圖片段落,並列入warns。已有之設定不重複添加;無需改動時回傳原內容。

Source:
Parameters:
Name Type Attributes Default Description
u8 Uint8Array

輸入docx檔之內容

opt Object | Boolean <optional>
{}

輸入設定物件,true或非物件時皆用預設,預設{}

Properties
Name Type Attributes Default Description
labels Object <optional>
{fig:'圖',tab:'表'}

輸入圖名、表名之標籤,見normLabels

Returns:

回傳{u8,info},info為{figs,tabs,keepNext,keepLines,changed,warns}:figs、tabs為圖名與表名數,keepNext、keepLines為新增該設定之段落數,changed為內容是否改動(false時u8為原內容)

Type
Object

prepDocxToc(u8, optopt) → {Object}

Description:
  • 準備添加目錄之docx內容(純結構處理, 不含Word)

    處理內容:圖名與表名之編號改為SEQ欄位、標題粗體改由段落樣式提供、目錄來源段落(列入目錄之標題、圖名、表名)設為段落內不分頁(keepLines)、圖名表名與其圖表同頁(keepWithObject)、於正文第1個標題前插入目錄與圖目錄、表目錄之欄位(無圖名或表名時不列該目錄)、分節與頁碼、目錄項目之樣式。目錄之內容與頁碼須再交Word更新。

    分節(pageNumbers為true):第1個標題前有內容(含文字或圖片之段落、表格)者視為有封面,分為封面(無頁碼)、前置章節與目錄(大寫羅馬數字自I起)、正文(自1起)共3節;無封面者不建封面節,分為2節,以免多出空白首頁。

    圖名、表名以段首「標籤+編號+空白」判斷;段首為標籤與編號但其後非空白者(如「圖1:名稱」)不視為圖名表名,以warns提示筆數與前3例。目錄項目之字型沿用正文第1個標題之文字段字型,查無則沿用模板預設。

    前提不符時拋錯(不產出錯誤之目錄):含文字方塊、已有目錄欄位、分節不只1個(pageNumbers為true時)、圖名或表名之編號未依文件順序自1連續、編號所在之文字段含文字以外之元素、headStyles指定之既有樣式非粗體。

Source:
Parameters:
Name Type Attributes Default Description
u8 Uint8Array

輸入docx檔之內容

opt Object | Boolean <optional>
{}

輸入設定物件,見normTocOpt

Returns:

回傳{u8,info},u8為處理後之docx內容,info為{skip,cover,levels,front,expect,labels,lists,bookmark,pageNumbers,warns};無標題時info僅含skip(原因字串)且u8為原內容

Type
Object

readAssets(md, dirMd) → {Object}

Description:
  • 讀取Markdown引用之資產檔並轉base64

    path一律回傳md內之原字串(服務端據以還原相對路徑);實體檔則原字串與URL解碼後字串皆嘗試。

Source:
Example
let { assets, missing } = readAssets('![a](pics/a.png)', './report')
// => { assets: [ { path: 'pics/a.png', base64: '…' } ], missing: [] }
Parameters:
Name Type Description
md String

輸入Markdown內容字串

dirMd String

輸入Markdown所在資料夾位置字串,相對路徑以此為基準

Returns:

回傳{assets,missing},assets為[{path,base64}],missing為找不到之相對路徑陣列

Type
Object

resolveAssetPaths(dirJob, p) → {Array}

Description:
  • 解析資產之相對路徑並防護路徑穿越

    md內之圖片路徑可能為URL編碼(中文或空白),而轉檔器係以md內之原字串組路徑取圖;故原字串與解碼後字串不同時回傳兩者,供呼叫端寫入同一內容確保圖片必能被解析。

Source:
Example
console.log(resolveAssetPaths('C:\\job', 'pics/%E5%9C%96.png'))
// => [ 'C:\\job\\pics\\%E5%9C%96.png', 'C:\\job\\pics\\圖.png' ]
Parameters:
Name Type Description
dirJob String

輸入工作資料夾位置字串

p String

輸入資產相對路徑字串

Returns:

回傳實際寫入之絕對路徑陣列

Type
Array

(async) retryBusy(fun, optopt) → {Promise}

Description:
  • 重試短暫被鎖定之檔案操作

    Windows下新建檔案常被防毒或索引器即時掃描而短暫鎖定(EBUSY/EPERM),遇此類錯誤時延遲後重試以提高穩定性,其餘錯誤直接拋出。

Source:
Example
let r = await retryBusy(() => fs.promises.readFile('./a.txt', 'utf8'), { tries: 3 })
Parameters:
Name Type Attributes Default Description
fun function

輸入欲執行之函數,可回傳Promise

opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
tries Integer <optional>
6

輸入最多嘗試次數整數,預設6

delayMs Number <optional>
400

輸入每次重試前延遲毫秒數,預設400

Returns:

回傳Promise,resolve回傳fun之結果,reject回傳錯誤

Type
Promise

(async) rmApiServer(optopt) → {Promise}

Description:
  • 建立並啟動Markdown轉Html/Docx之API服務

    以hapi提供三個端點:GET /api/health(健康檢查與環境狀態)、GET /api/selftest(實跑一次最小轉檔驗證本機Word可用)、POST /api/convert(轉檔主端點,JSON參數同cvMdTo,另可用templateName指定服務端模板或templateBase64夾帶模板;query帶download=1時單一格式直接回傳二進位檔)。

    請求之keepCaption(true或{labels})轉傳cvMdTo使圖名表名與其圖表同頁;請求之toc(true或addDocxToc之設定物件)轉傳cvMdTo以添加目錄,其timeoutMs不採用(Word更新之逾時由服務端決定);兩者之結果隨回應傳回。

Source:
Example
import rmApiServer from 'w-md2docx/src/rmApiServer.mjs'

let { server, settings } = await rmApiServer({
    port: 22000,
    token: '',
})
console.log(`listening on ${server.info.uri}`, settings)
Parameters:
Name Type Attributes Default Description
opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
port Integer <optional>
22000

輸入服務埠號整數,給0則由系統自動配置(實際埠號見回傳之server.info.port),預設22000

host String <optional>
'0.0.0.0'

輸入監聽位址字串,預設'0.0.0.0'

token String <optional>
''

輸入權杖字串,非空時所有/api/*須帶x-api-token標頭,預設''

maxMb Number <optional>
256

輸入請求大小上限數字,單位MB,預設256

dirTemplates String <optional>
''

輸入docx模板資料夾位置字串,未給則用本套件src/templates,預設''

dirWork String <optional>
''

輸入工作資料夾位置字串,未給則用系統暫存夾下之w-md2docx,預設''

templateDef String <optional>
'temp_tpc.docx'

輸入預設模板檔名字串,預設'temp_tpc.docx'

autoStart Boolean <optional>
true

輸入是否立即啟動服務布林值,預設true

Returns:

回傳Promise,resolve回傳{server,settings,getState,stop},其中server為hapi實例,getState為取環境狀態之async函數,stop為停止服務之async函數,reject回傳錯誤訊息

Type
Promise

runExclusive(fun) → {Promise}

Description:
  • 將函數排入Word轉檔佇列並逐一執行

    底層係調用本機Word(win32com)轉檔,同時執行多份會相互干擾,故docx階段一律排隊逐一執行;前一件不論成敗均續行下一件。

Source:
Example
let r = await runExclusive(() => WHtml2docx('./a.html', './a.docx'))
Parameters:
Name Type Description
fun function

輸入欲執行之函數,可回傳Promise

Returns:

回傳Promise,resolve回傳fun之結果,reject回傳錯誤

Type
Promise

scanAssetPaths(md) → {Array}

Description:
  • 掃描Markdown內引用之本機相對路徑資產(圖片等)

    涵蓋html之<img src="…">與markdown之;排除網路位址、data協定、mailto、錨點與絕對路徑,並去除錨點與查詢字串。

Source:
Example
console.log(scanAssetPaths('![a](pics/a.png)\n<img src="pics/b.png" />\n![c](https://x.com/c.png)'))
// => [ 'pics/a.png', 'pics/b.png' ]
Parameters:
Name Type Description
md String

輸入Markdown內容字串

Returns:

回傳相對路徑字串陣列(已去重)

Type
Array

scanParas(doc) → {Array}

Description:
  • 依序列出document.xml之段落與其是否位於表格內

Source:
Parameters:
Name Type Description
doc String

輸入document.xml字串

Returns:

回傳段落陣列,元素為{start,end,xml,inTbl},start與end為段落於doc之起訖位置

Type
Array

tElem(s) → {String}

Description:
  • 產生w:t元素(前後有空白時加xml:space="preserve")

Source:
Parameters:
Name Type Description
s String

輸入文字字串

Returns:

回傳w:t元素字串

Type
String

textOf(x) → {String}

Description:
  • 取XML片段之文字(依序串接各w:t之內容)

Source:
Parameters:
Name Type Description
x String

輸入XML片段字串

Returns:

回傳文字字串

Type
String

toErrText(err) → {String}

Description:
  • 取錯誤訊息文字

    底層轉檔器之reject可能為字串或Error物件,統一轉為文字供組合訊息使用。

Source:
Example
console.log(toErrText('abc'))
// => 'abc'

console.log(toErrText(new Error('abc')))
// => 'abc'
Parameters:
Name Type Description
err *

輸入錯誤資料,可為字串、Error物件或任意資料

Returns:

回傳錯誤訊息字串

Type
String

toSafeName(name) → {String}

Description:
  • 取安全檔名主體

    移除路徑成分、常見副檔名與跨平台非法字元,避免路徑穿越與寫檔失敗;無效輸入回傳'output'。

Source:
Example
console.log(toSafeName('../report/報告R00.01.md'))
// => '報告R00.01'

console.log(toSafeName(''))
// => 'output'
Parameters:
Name Type Description
name String

輸入檔名字串

Returns:

回傳安全檔名主體字串

Type
String

transErrAsset(msg) → {String}

Description:
  • 轉譯資產缺漏之錯誤訊息

    底層僅回原始路徑訊息(且含內部工作夾路徑),此處改為可行動之提示並隱去工作路徑;非資產缺漏訊息原樣回傳。

Source:
Example
console.log(transErrAsset('fp[C:/tmp/job_1/pics/a.png] does not exist'))
// => 'Failed to convert md to html: the referenced file (pics/a.png) does not exist, please make sure it is included in assets'
Parameters:
Name Type Description
msg String

輸入原始錯誤訊息字串

Returns:

回傳轉譯後錯誤訊息字串

Type
String

unesc(s) → {String}

Description:
  • 還原XML文字之實體

Source:
Parameters:
Name Type Description
s String

輸入XML文字字串

Returns:

回傳還原後字串

Type
String

warnCapsLike(capsLike) → {String}

Description:
  • 產生疑似圖名表名之提示訊息

Source:
Parameters:
Name Type Description
capsLike Array

輸入findCaptions之capsLike

Returns:

回傳提示訊息字串(含筆數與前3例)

Type
String

writeAssets(dirJob, assets) → {Integer}

Description:
  • 將夾帶之資產(圖片等)還原至工作資料夾

    使md內之相對路徑得以解析;base64容許data URI形式。

Source:
Example
let n = writeAssets('C:\\job', [{ path: 'pics/圖.png', base64: '…' }])
// => 1
Parameters:
Name Type Description
dirJob String

輸入工作資料夾位置字串

assets Array

輸入資產陣列,格式[{path,base64}],亦接受contentBase64欄位

Returns:

回傳寫入之資產數整數

Type
Integer

writeDocx(z, partsopt) → {Uint8Array}

Description:
  • 以unzipSync之結果寫出docx,可取代部分檔案之內容

    檔案順序沿用原docx;圖檔已壓縮故不再壓,其餘以壓縮等級6寫出。

Source:
Parameters:
Name Type Attributes Default Description
z Object

輸入fflate之unzipSync回傳物件

parts Object <optional>
{}

輸入欲取代之檔案物件,鍵為檔名、值為文字內容

Returns:

回傳docx內容

Type
Uint8Array