Раньше по каким-то причинам мне нужно было преобразовать некоторые HTML-теги в формат уценки, но я по незнанию довел это до относительно полной функции.
Затем я инкапсулировал его в файл и разместил на github, а также просто сделал две пробные веб-страницы.
Кодовый адрес находится по адресу html2md
Код очень простой и использует собственный js. Он содержит множество простых регулярных правил и не использует дополнительных функций для оптимизации структуры. Однако позже я сделал на его основе плагин. в, я надеюсь, что это будет полезно для некоторых людей.
Адрес плагина https://www.emlog.net/plugin/detail/445
Тогда мне лень его дальше оптимизировать, поэтому я просто выложу здесь исходный код, а потом расскажу о том, как я реализовал эту функцию, надеюсь, некоторым она будет интересна.
Всего в исходном коде более 200 строк, но я знаю, что его можно написать проще.
/**
* Пучок html Контент изменен преобразован в markdown Формат V1.0
*
* @author kohunglee
* @param {string} htmlData Конвертироватьбывший html
* @return {string} изменить markdown Исходный код
*/
function html2md(htmlData){
codeContent = new Array // данные тега кода
preContent = new Array // данные предварительной этикетки
tableContent = new Array // данные метки таблицы
olContent = new Array // старые данные этикетки
imgContent = new Array // данные тега img
aContent = new Array // данные тега
let pureHtml = htmlData
// исходный код
console.log("Конвертироватьбывший Исходный код:" + pureHtml)
// Функция: удалить html-тег
function clearHtmlTag(sourceData = ''){
return sourceData.replace(/\<[\s\S]*?\>/g,'')
}
// восстановить старый тег
function olRecover(olData = ''){
let result = olData
let num = olData.match(/\<li\>/ig).length
for(let i = 1; i <= num; i++){
let line = '[~wrap]'
if(i == 1) line = '[~wrap][~wrap]'
result = result.replace(/\<li\>/i, line + i + '. ')
}
result = result.replace(/\<\/li\>/, '')
return result
}
// Функция: восстановить тег img
function imgRecover(imgHtml = ''){
let imgSrc,imgTit,imgAlt,result
imgSrc = imgHtml.match(/(?<=src=['"])[\s\S]*?(?=['"])/i)
imgTit = imgHtml.match(/(?<=title=['"])[\s\S]*?(?=['"])/i)
imgAlt = imgHtml.match(/(?<=alt=['"])[\s\S]*?(?=['"])/i)
imgTit = (imgTit != null) ? ` "${imgTit}"` : ' '
imgAlt = (imgAlt != 'null') ? imgAlt : " "
result = `![${imgAlt}](${imgSrc}${imgTit})`
return result
}
// Функция: восстановить тег
function aRecover(aData = ''){
let aHref = '' + aData.match(/(?<=href=['"])[\s\S]*?(?=['"])/i)
let aTit = '' + aData.match(/(?<=title=['"])[\s\S]*?(?=['"])/i)
let aText = '' + aData.match(/(?<=\<a\s*[^\>]*?\>)[\s\S]*?(?=<\/a>)/i)
let aImg = aData.match(/<img\s*[^\>]*?\>[^]*?(<\/img>)?/i)
let aImgSrc,aImgTit,aImgAlt
aTit = (aTit != 'null') ? ` "${aTit}"` : ' '
aText = clearHtmlTag(aText)
let result = `[${aText}](${aHref}${aTit})`
if(aImg != null){ // Функция: если изображение найдено, перейдите в режим отображения изображения.
aImgSrc = aImg[0].match(/(?<=src=['"])[\s\S]*?(?=['"])/i)
aImgTit = aImg[0].match(/(?<=title=['"])[\s\S]*?(?=['"])/i)
aImgAlt = aImg[0].match(/(?<=alt=['"])[\s\S]*?(?=['"])/i)
aImgTit = (aImgTit != null) ? ` "${aImgTit}"` : ' '
aImgAlt = (aImgAlt != 'null') ? aImgAlt : " "
result = `[![${aImgAlt}](${aImgSrc}${aImgTit})](${aHref}${aTit})`
}
return result
}
// Функция: восстановить метку таблицы
function tableRecover(tableData = null){
if(tableData[0] == null){ // если не существует th метка, таблица по умолчанию представляет собой один слой
let result = ''
let colNum = tableData[1].length
for(let i = 0; i < colNum; i++){
result += `|${clearHtmlTag(tableData[1][i])}`
}
result += `|[~wrap]`
for(let j = 0; j < colNum; j++){
result += `| :------------: `
}
result += `|[~wrap]`
return result
}
let colNum = tableData[0].length // если существует th этикетка, нажмите th количество ячеек для построения всей таблицы
let result = ''
for(let i = 0; i < colNum; i++){
result += `|${clearHtmlTag(tableData[0][i])}`
}
result += `|[~wrap]`
for(let j = 0; j < colNum; j++){
result += `| :------------: `
}
result += `|[~wrap]`
for(let k = 0; k < tableData[1].length;){
for(let z = 0; z < colNum; z++,k++){
result += `|${clearHtmlTag(tableData[1][k])}`
}
result += `|[~wrap]`
}
return result+`[~wrap]`
}
// Удаление стилей, скриптов и контента
pureHtml = pureHtml.replace(/<style\s*[^\>]*?\>[^]*?<\/style>/ig,'').replace(/<script\s*[^\>]*?\>[^]*?<\/script>/ig,'')
//Сохраняем содержимое предварительно,изаменять<pre>содержание в
preContent = pureHtml.match(/<pre\s*[^\>]*?\>[^]*?<\/pre>/ig)
pureHtml = pureHtml.replace(/(?<=\<pre\s*[^\>]*?\>)[\s\S]*?(?=<\/pre>)/ig,''#preContent#`')
//Сохраняем содержимое кода,изаменять<code>содержание в
codeContent = pureHtml.match(/(?<=\<code\s*[^\>]*?\>)[\s\S]*?(?=<\/code>)/ig)
pureHtml = pureHtml.replace(/(?<=\<code\s*[^\>]*?\>)[\s\S]*?(?=<\/code>)/ig,''#codeContent#`')
// Сохраняем содержимое,изаменять<a>содержание в
aContent = pureHtml.match(/<a\s*[^\>]*?\>[^]*?<\/a>/ig)
pureHtml = pureHtml.replace(/<a\s*[^\>]*?\>[^]*?<\/a>/ig,'`#aContent#`')
//Сохраняем содержимое img,изаменять<img>содержание в
imgContent = pureHtml.match(/<img\s*[^\>]*?\>[^]*?(<\/img>)?/ig)
pureHtml = pureHtml.replace(/<img\s*[^\>]*?\>[^]*?(<\/img>)?/ig,'`#imgContent#`')
// Получить чистый (без атрибутов) html
pureHtml = pureHtml.replace(/(?<=\<[a-zA-Z0-9]*)\s.*?(?=\>)/g,'')
// заголовок:целевое приобретение<h1><h2>...данные,изаменять
pureHtml = pureHtml.replace(/<h1>/ig,'[~wrap]# ').replace(/<\/h1>/ig,'[~wrap][~wrap]')
.replace(/<h2>/ig,'[~wrap]## ').replace(/<\/h2>/ig,'[~wrap][~wrap]')
.replace(/<h3>/ig,'[~wrap]### ').replace(/<\/h3>/ig,'[~wrap][~wrap]')
.replace(/<h4>/ig,'[~wrap]#### ').replace(/<\/h4>/ig,'[~wrap][~wrap]')
.replace(/<h5>/ig,'[~wrap]##### ').replace(/<\/h5>/ig,'[~wrap][~wrap]')
.replace(/<h6>/ig,'[~wrap]###### ').replace(/<\/h6>/ig,'[~wrap][~wrap]')
// Абзац: обработка некоторых общих структурных тегов
pureHtml = pureHtml.replace(/(<br>)/ig,'[~wrap]').replace(/(<\/p>)|(<br\/>)|(<\/div>)/ig,'[~wrap][~wrap]')
.replace(/(<meta>)|(<span>)|(<p>)|(<div>)/ig,'').replace(/<\/span>/ig,'')
// Смелый:заменять<b><strong>
pureHtml = pureHtml.replace(/(<b>)|(<strong>)/ig,'**').replace(/(<\/b>)|(<\/strong>)/ig,'**')
// курсив:заменять<i><em><abbr><dfn><cite><address>
pureHtml = pureHtml.replace(/(<i>)|(<em>)|(<abbr>)|(<dfn>)|(<cite>)|(<address>)/ig,'*').replace(/(<\/i>)|(<\/em>)|(<\/abbr>)|(<\/dfn>)|(<\/cite>)|(<\/address>)/ig,'*')
// удалить Проволока:заменять<del>
pureHtml = pureHtml.replace(/\<del\>/ig,'~~').replace(/\<\/del\>/ig,'~~')
// Цитировать:заменять<blockquote>
pureHtml = pureHtml.replace(/\<blockquote\>/ig,'[~wrap][~wrap]> ').replace(/\<\/blockquote\>/ig,'[~wrap][~wrap]')
// уровень Проволока:заменять<hr>
pureHtml = pureHtml.replace(/\<hr\>/ig,'[~wrap][~wrap]------[~wrap][~wrap]')
// лист <table>,получить данные,удалить Этикетка,Затемслой за слоемхранилище анализов, наконец-то сгенерированных на основе результатов
tableContent = pureHtml.match(/(?<=\<table\s*[^\>]*?\>)[\s\S]*?(?=<\/table>)/ig)
pureHtml = pureHtml.replace(/<table\s*[^\>]*?\>[^]*?<\/table>/ig,'`#tableContent#`')
if(tableContent !== null){ // хранилище анализов
tbodyContent = new Array
for(let i = 0; i < tableContent.length; i++){
tbodyContent[i] = new Array // Первые данные tbodyContent[i] — это данные заголовка, а вторые — данные тела.
tbodyContent[i].push(tableContent[i].match(/(?<=\<th>)[\s\S]*?(?=<\/th?>)/ig))
tbodyContent[i].push(tableContent[i].match(/(?<=\<td>)[\s\S]*?(?=<\/td?>)/ig))
}
}
if(typeof tbodyContent !== "undefined"){ // заменять
for(let i = 0; i < tbodyContent.length; i++){
let tableText = tableRecover(tbodyContent[i])
pureHtml = pureHtml.replace(/\`\#tableContent\#\`/i,tableText)
}
}
// упорядоченный список<ol>из<li>,Сохранить старый контент,ициклвосстанавливатьсяolсодержание в
olContent = pureHtml.match(/(?<=\<ol\s*[^\>]*?\>)[\s\S]*?(?=<\/ol>)/ig)
pureHtml = pureHtml.replace(/(?<=\<ol\s*[^\>]*?\>)[\s\S]*?(?=<\/ol>)/ig,'`#olContent#`')
if(olContent !== null){
for(let k = 0; k < olContent.length; k++){
let olText = olRecover(olContent[k])
pureHtml = pureHtml.replace(/\`\#olContent\#\`/i,clearHtmlTag(olText))
}
}
// неупорядоченный список<ul>из<li>,а также<dd>,прямойзаменять
pureHtml = pureHtml.replace(/(<li>)|(<dd>)/ig,'[~wrap] - ').replace(/(<\/li>)|(<\/dd>)/ig,'[~wrap][~wrap]')
// После обработки списка <lu>、<\lu>、<ol>、<\ol> иметь дело с
pureHtml = pureHtml.replace(/(<ul>)|(<ol>)/ig,'').replace(/(<\/ul>)|(<\/ol>)/ig,'[~wrap][~wrap]')
// Сначала восстановите img ,Сновареставрация a
if(imgContent !== null){
for(let i = 0; i < imgContent.length; i++){
let imgText = imgRecover(imgContent[i])
pureHtml = pureHtml.replace(/\`\#imgContent\#\`/i,imgText)
}
}
// восстанавливаться a
if(aContent !== null){
for(let k = 0; k < aContent.length; k++){
let aText = aRecover(aContent[k])
pureHtml = pureHtml.replace(/\`\#aContent\#\`/i,aText)
}
}
// Изменять ХОРОШОиметь дело с,1.заменять [~wrap] для ‘\n’ 2.голова ХОРОШОИзменять ХОРОШОУдалить。 3. Удалите другие слишком длинные слова-заменители: ХОРОШО.
pureHtml = pureHtml.replace(/\[\~wrap\]/ig,'\n')
.replace(/\n{3,}/g,'\n\n')
// код <code> ,Согласно вышеизложенномуизмножествовосстанавливатьсяcode,Затем Воляcodeзаменять
if(codeContent !== null){
for(let i = 0; i < codeContent.length; i++){
pureHtml = pureHtml.replace(/\`\#codeContent\#\`/i,clearHtmlTag(codeContent[i]))
}
}
pureHtml = pureHtml.replace(/\<code\>/ig,' ` ').replace(/\<\/code\>/ig,' ` ')
// код <pre> ,восстанавливатьсяpre,Затем Воляpreзаменять
if(preContent !== null){
for(let k = 0; k < preContent.length; k++){
let preLanguage = preContent[k].match(/(?<=language-).*?(?=[\s'"])/i)
let preText = clearHtmlTag(preContent[k])
preText = preText.replace(/^1\n2\n(\d+\n)*/,'') // Удалить номер ХОРОШО
preLanguage = (preLanguage != null && preLanguage[0] != 'undefined') ? preLanguage[0] + '\n' : '\n'
pureHtml = pureHtml.replace(/\`\#preContent\#\`/i,preLanguage + preText)
}
}
pureHtml = pureHtml.replace(/\<pre\>/ig,'```').replace(/\<\/pre\>/ig,'\n```\n')
// УдалитьостальныеизhtmlЭтикетка,Восстановить предлогкодсерединаиз '<' и '>'
pureHtml = clearHtmlTag(pureHtml)
pureHtml = pureHtml.replace(/\<\;/ig,'<').replace(/\>\;/ig,'>')
// Уберите пробел в шапке ХОРОШО
pureHtml = pureHtml.replace(/^\n{1,}/i,'')
return pureHtml
}
Среди них некоторые переменные массива объявляются вначале для хранения некоторых промежуточных продуктов во время процесса преобразования.
Затем pureHtml
Эта переменная является исходным материалом на протяжении всего процесса, вплоть до самого конца.
Во-первых, точка входа для обработки функции начинается со строки 112.
Первый шаг — удалить <style>
и <script>
Эти два тега и их содержимое.
Второй шаг заключается в том, чтобы pre Содержимое сначала сохраняется в массиве, а затем используется ‘#preContent#’
Этот персонаж заменяет оригинальный pre Для содержимого тега я называю эту операцию защитой. Поскольку в продолжении будет много сложного контента, я pre Если он защищен, его первоначальный вкус может быть гарантирован, потому что pre Это сам код, и его нельзя потрогать.
Шаг 3,и pre Такой же code , почему сначала pre Снова code Шерстяная ткань? Поскольку эти две вещи имеют такую всеобъемлющую взаимосвязь, как правило, pre Там может быть code ,но code но не pre , поэтому, рассмотрев эту логику, я решил сохранить ее вот так.
Четвертый шаг – не pre и code При помехах смело удаляйте в теге другие бесполезные атрибуты и заменяйте их на a и img тегировать содержимое "Защищать" , чтобы облегчить восстановление через некоторое время.
Шаг 5,то естьзаменятьчто-то простоеиз Этикетка,Какой титул?,Курсив,рядом Проволока Ах, подожди(кроме Волякакой-то беспорядокиз Этикеткапрямойудалить).....Последний по порядкуиметь дело слистисписок。
Шестой шаг — следовать определенным спецификациям и добавить вышеуказанное. "Защищать" контент и восстановить его.
Шаг 7,Удалите пробел ХОРОШО вверху. (Помню, я еще проверял лишние пробелы и удалял их.,Я не знаю, чего не хватает),Затем Конвертировать Завершить,Верните результат.