最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

.md 文檔自動編號 js 腳本

2022-11-06 11:45 作者:hqzqaq  | 我要投稿

.md 文檔自動編號 js 腳本

1、契機

在使用 typora 的時候,沒有自動編號,每一級標題要手動編號,比較累。之前有找過修改主題的 css 來實現自動編號的,但是只是個樣式而已,沒有真正的編號,而且導出的 pdf 中是沒有編號的。這次找的腳本是直接修改 md 文檔的,根據行首的 # 來判斷是不是標題。

md 文檔一共有六級標題,不對一級標題編號,二級、三級、四級、五級、六級標題進行級聯編號。

根據這篇文章的 java 代碼修改而來,并做了一點小小的改進,用 java 感覺有點重,最近喜歡用 js 寫點腳本,比如一些字符串處理的,挺方便的。

文章鏈接:

https://blog.csdn.net/oneby1314/article/details/107311743

2、腳本代碼

js 代碼如下:

const?fs?=?require('fs');
const?readline?=?require('readline');
const?{once}?=?require('node:events')
const?ncp?=?require("copy-paste");
const?path?=?require('path')

/**
?*?執(zhí)行標題自動編號
?*
?*?@param?destMdFilePath?MD?文件路徑
?*/

function?doTitleAutoNumbering(destMdFilePath)?{
????//?獲取標題自動編號的MD文件內容
????const?mdFileContent?=?getAutoTitledMdContent(destMdFilePath);
????mdFileContent.then((res)?=>?{
????????//?執(zhí)行保存(覆蓋原文件)
????????saveMdContentToFile(destMdFilePath,?res);
????})
}

/**
?*?獲取標題自動編號的MD文件內容
?*
?*?@param?destMdFilePath?MD?文件路徑
?*?@return
?*/

async?function?getAutoTitledMdContent(destMdFilePath)?{
????//?標題編號
????/*
????????標題編號規(guī)則:
????????-?一級標題為文章的題目,不對一級標題編號
????????-?二級、三級、四級、五級、六級標題需要級聯編號
?????*/

????let?titleNumber?=?[0,?0,?0,?0,?0]
????//?存儲md文件內容
????let?mdContent?=?''

????const?md?=?readline.createInterface({
????????input:?fs.createReadStream(destMdFilePath),
????????output:?process.stdout,
????????terminal:?false
????});

????//?一行一行讀取數據
????md.on('line',?(line)?=>?{
????????//?判斷是否為標題行,如果是標題,是幾級標題
????????const?curTitleLevel?=?calcTitleLevel(line);
????????if?(curTitleLevel?!==?-1)?{

????????????//?插入標題序號
????????????line?=?insertTitleNumber(line,?titleNumber);

????????????//?重新計算標題計數器
????????????reCalcTitleCounter(curTitleLevel,?titleNumber);

????????}
????????mdContent?=?mdContent.concat(line,?'\r\n')
????})

????//?等待監(jiān)聽事件完成
????await?once(md,?'close')
????return?mdContent;
}

/**
?*?計算當前標題等級
?*
?*?@param?curLine?當前行的內容
?*?@return?-1?:非標題行;大于等于?2?的正數:當前行的標題等級
?*/

function?calcTitleLevel(curLine)?{
????//?由于一級標題無需編號,所以從二級標題開始判斷
????let?isTitle?=?curLine.startsWith("##");
????if?(!isTitle)?{
????????//?返回?-1?表示非標題行
????????return?-1;
????}

????//?現在來看看是幾級標題
????return?curLine.indexOf("?");
}

/**
?*?向標題行中插入標題序號
?*
?*?@param?curLine?????當前行內容
?*?@param?titleNumber?標題計數器
?*?@return
?*/

function?insertTitleNumber(curLine,?titleNumber)?{
????//?標題等級(以空格分隔的前提是?Typora?開啟嚴格模式)
????let?titleLevel?=?curLine.indexOf("?");
????//?標題等級部分
????let?titleLevelStr?=?curLine.substring(0,?titleLevel);
????//?標題內容部分
????let?titleContent?=?curLine.substring(titleLevel?+?1);
????//?先去除之前的編號
????titleContent?=?removePreviousTitleNumber(titleContent);
????//?標題等級遞增
????let?titleIndex?=?titleLevel?-?2;
????titleNumber[titleIndex]?+=?1;
????//?標題序號
????let?titleNumberStr?=?"";
????switch?(titleLevel)?{
????????case?2:
????????????titleNumberStr?=?`${titleNumber[0]}`;
????????????break;
????????case?3:
????????????titleNumberStr?=?`${titleNumber[0]}.${titleNumber[1]}`
????????????break;
????????case?4:
????????????titleNumberStr?=?`${titleNumber[0]}.${titleNumber[1]}.${titleNumber[2]}`
????????????break;
????????case?5:
????????????titleNumberStr?=?`${titleNumber[0]}.${titleNumber[1]}.${titleNumber[2]}.${titleNumber[3]}`
????????????break;
????????case?6:
????????????titleNumberStr?=?`${titleNumber[0]}.${titleNumber[1]}.${titleNumber[2]}.${titleNumber[3]}.${titleNumber[4]}`
????????????break;
????}
????titleNumberStr?+=?"、";
????//?插入標題序號
????titleContent?=?titleNumberStr?+?titleContent;
????//?返回帶序號的標題
????curLine?=?titleLevelStr?+?"?"?+?titleContent;
????return?curLine;
}

/**
?*?去除之前標題的編號
?*?@param?titleContent?標題內容
?*?@return?去除標題編號之后的標題內容
?*/

function?removePreviousTitleNumber(titleContent)?{
????//?尋找標題中的?、?字符
????let?index?=?titleContent.indexOf("、");
????if?(index?>?0?&&?index?<?10)?{
????????//?之前已經進行過標號
????????return?titleContent.substring(index?+?1);
????}?else?{
????????//?之前未進行過標號,直接返回
????????return?titleContent;
????}
}

/**
?*??重新計算標題計數器的值
?*
?*?@param?titleLevel??當前行的標題等級
?*?@param?titleNumber?標題計數器
?*/

function?reCalcTitleCounter(titleLevel,?titleNumber)?{
????//?二級標題更新時,三級及三級以下的標題序號重置為?0
????let?startIndex?=?titleLevel?-?1;
????for?(let?i?=?startIndex;?i?<?titleNumber.length;?i++)?{
????????titleNumber[i]?=?0;
????}
}

/**
?*?保存MD文件
?*
?*?@param?destMdFilePath?MD文件路徑
?*?@param?mdFileContent??MD文件內容
?*/

function?saveMdContentToFile(destMdFilePath,?mdFileContent)?{
????//?不保存空文件
????if?(mdFileContent?==?null?||?mdFileContent?===?"")?{
????????return;
????}
????//?執(zhí)行保存
????fs.writeFile(destMdFilePath,?mdFileContent,?(err)?=>?{
????????if?(err)?{
????????????return?console.log(err)
????????}
????????console.log('數據寫入成功!')
????})
}

function?getNcpPath()?{
????return?new?Promise((resolve,?reject)?=>?{
????????ncp.paste((err,?p)?=>?{
????????????if?(err)?{
????????????????reject(err)
????????????}?else?{
????????????????if?(typeof?p?===?'string')?{
????????????????????resolve(p)
????????????????}
????????????}
????????})
????})
}

(async?()?=>?{
????const?arguments?=?process.argv;
????let?mdPath?=?''
????//?可以使用循環(huán)迭代所有的命令行參數(包括node路徑和文件路徑)
????//?命令行輸入參數的情況
????if?(arguments.length?>=?3)?{
????????//?解決路徑帶空格的情況
????????for?(let?i?=?2;?i?<?arguments.length;?i++)?{
????????????mdPath?=?mdPath.concat(arguments[i],?'?')
????????}
????????mdPath?=?mdPath.trim()
????}

????//?沒有輸入參數的情況,則去粘貼板尋找是否有文件路徑
????if?(arguments.length?<?3)?{
????????mdPath?=?await?getNcpPath()
????}

????let?stat?=?null
????try?{
????????//?路徑帶空格,需要輸入雙引號
????????stat?=?fs.lstatSync(mdPath)
????}?catch?(err)?{
????????console.log('參數錯誤,文件不存在')
????????return
????}
????if?(stat.isFile())?{
????????if?(!mdPath.endsWith('.md'))?{
????????????console.log('參數錯誤,請輸入md文件的路徑')
????????????return
????????}
????????//?執(zhí)行標題自動編號
????????doTitleAutoNumbering(mdPath)
????}
????if?(stat.isDirectory())?{
????????let?dirFiles?=?fs.readdirSync(mdPath);
????????dirFiles.forEach((item)?=>?{
????????????let?filePath?=?path.join(mdPath,?item)
????????????if?(filePath.endsWith('.md'))?{
????????????????//?執(zhí)行標題自動編號
????????????????doTitleAutoNumbering(filePath)
????????????}
????????})
????}
})()

3、使用說明

3.1、環(huán)境

  1. 需要本機安裝了 node js,最好配置了國內鏡像源

  2. 代碼拷貝到 js 文件中,執(zhí)行以下命令:

    #?忘了是不是這個命令初始化了
    npm?init
    #?安裝依賴
    npm?install

3.2、運行

3.2.1、命令行方式

3.2.1.1、傳入文件參數

node?autoNumMd.js?./test.md

傳入文件參數

編號效果:

編號效果

3.2.1.2、傳入文件夾參數

#?是文件夾的話,就將文件夾下的?md?文檔全部編號
#?但是不會遞歸子文件夾
node?autoNumMd.js?C:\...\_posts

文件夾

3.2.1.3、無參數的情況

#?沒有傳入參數,則會去粘貼板查看是否有復制路徑
node?autoNumMd.js

3.2.2、bat 腳本

新建 .bat 文件,寫入以下內容,注意 node Absolute path 需要替換為本機 node 的絕對路徑,js 文件也是,輸入文件夾、文件路徑或者直接回車(讀取粘貼板路徑)。

setlocal?EnableDelayedExpansion
set?/p?val=Please?enter?the?.md?file?path?or?folder?path:
echo?%val%
if?"%val%"?==?""?(
node?Absolute?path?"autoNumMd.js?Absolute?path"
)?else?(
node?Absolute?path?"autoNumMd.js?Absolute?path"?%val%
)

4、md 編寫說明

  1. 分級標題要連續(xù),按照二三四五六來,不要二級標題后接四五六級標題

  2. # 后面要接空格

5、總結

  1. js 的異步編程把我真是煩透了,很多的操作都是要同步的。。。,異步轉同步改了我好久阿,心累

  2. bat 腳本也畫了挺長時間的,這語法太怪了

  3. 此文檔的編號使用腳本生成


.md 文檔自動編號 js 腳本的評論 (共 條)

分享到微博請遵守國家法律
马山县| 昆明市| 普洱| 卢湾区| 滁州市| 江西省| 宁都县| 开化县| 平顺县| 高尔夫| 申扎县| 通山县| 富阳市| 托克托县| 湘西| 庄浪县| 英德市| 安阳市| 莱西市| 沧源| 祁东县| 东台市| 白银市| 沈丘县| 宝坻区| 蕉岭县| 河北省| 定襄县| 湘阴县| 互助| 新密市| 喀什市| 上虞市| 长乐市| 个旧市| 大同县| 兖州市| 兰州市| 巍山| 临沧市| 旬阳县|