将Markdown/Textile转换为HTML的Javascript代码(最好还能将HTML转换回Markdown/Textile)

106

有几个适用于Markdown / Textile的优秀Javascript编辑器(例如:http://attacklab.net/showdown/,我现在正在使用的编辑器),但我只需要一个将字符串从Markdown / Textile -> HTML并反过来转换的Javascript函数。

最佳方法是什么?(理想情况下,它应该与jQuery兼容 - 例如:$("#editor").markdown_to_html()

编辑:另一种表达方式是,我正在寻找Rails' textilize()markdown()文本助手的Javascript实现。

13个回答

120

对于Markdown转换成HTML,有Showdown

StackOverflow本身使用Markdown语言进行提问和回答;你尝试过看一下它是如何工作的吗?

嗯,似乎它使用的是PageDown,可在MIT许可证下获得。

问题有没有好的Markdown JavaScript库或控件?及其答案可能也会有所帮助 :-)


当然,一个完整的编辑器不完全是你要求的;但是他们必须使用某种函数来将Markdown代码转换为HTML;根据这些编辑器的许可证,你可能可以重用那个函数......

实际上,如果你仔细看一下Showdown,在它的源代码(文件showdown.js)中,你会发现这部分注释:

//
// Showdown usage:
//
//   var text = "Markdown *rocks*.";
//
//   var converter = new Showdown.converter();
//   var html = converter.makeHtml(text);
//
//   alert(html);
//
// Note: move the sample code to the bottom of this
// file before uncommenting it.
//

这不是jQuery语法,但应该很容易集成到您的应用程序中 ;-)


关于Textile,似乎很难找到有用的东西 :-(


另一方面,HTML -> Markdown,我想事情可能会有点困难...

我会在我的应用程序数据存储(数据库?)中存储Markdown和HTML,并使用一个进行编辑,另一个进行渲染...会占用更多空间,但似乎比“解密”HTML更少风险...


5
链接似乎已经更改。演示在http://softwaremaniacs.org/playground/showdown-highlight/,源代码可在http://softwaremaniacs.org/playground/showdown-highlight/showdown.js中找到。 - John J. Camilleri
1
@John,感谢您的评论;我已经编辑了我的答案以更改链接;-) - Pascal MARTIN
不幸的是,这个库似乎不能用于基于Markdown的链接,即:某些文字无法转换。它似乎缺少一些语法,这很不幸。它还缺少什么? - Oddman

61

我认为在这里列出JavaScript解决方案及其未压缩的大小、优点和缺点是值得的。未压缩代码的压缩大小约为未压缩大小的50%。以下是重点:

  • 如果您需要全面支持并且将拥有用户编辑或任意文档,但不过分关注大小/带宽,请使用markdown-it(104KB)。
  • 如果您需要相当高的质量和表格支持,但想要轻量级且不需要除转换以外的任何功能或处理每个边缘情况,请使用我自己的drawdown(1.3KB)。
  • 如果您需要安全性或可扩展性等独特功能,请使用其他解决方案之一。

所有这些都使用MIT许可证,大多数都在npm上。

  • markdown-it:104KB。Powers StackExchange 自CommonMark迁移以来。遵循CommonMark规范,现在更或多或少是黄金标准;支持语法扩展;默认输出安全。快速;像showdown一样强大,但非常大。具有许多功能(例如同步滚动)。也是http://dillinger.io/的基础。

  • showdown:28KB。具有全面的CommonMark支持,并且先前是黄金标准;比Markdown-It小得多,但速度较慢。它是pagedown的基础。

  • pagedown:8KB。Powered StackExchange 在CommonMark迁移之前。它非常强大,但缺少表格、定义列表、脚注等。除了8KB的转换器脚本外,还提供编辑器和清理脚本。

  • drawdown:1.3KB。完全透明,我写了它。比任何其他轻量级转换器具有更广泛的功能范围;处理大多数但不是所有的CommonMark规范。不建议用户进行编辑,但非常适用于在Web应用程序中呈现信息。没有内联HTML。

  • marked:19KB。全面的;针对单元测试套件进行了测试;支持自定义词法分析器规则。

  • micromarkdown:5KB。支持许多功能,但缺少一些常见的功能,例如使用*的无序列表和一些不严格属于规范的常见功能,例如有栏代码块。许多错误,在大多数较长的文档上会抛出异常。我认为它是实验性的。

  • nano-markdown:1.9KB。功能范围仅限于大多数文档使用的内容;比micromarkdown更健壮,但并非完美;使用自己的非常基本的单元测试。相当健壮,但在许多边缘情况下会出错。

  • mmd.js:800字节。旨在制作最小可能的仍然可用的解析器的结果。支持一个小子集;需要为文档量身定制。

  • markdown-js:54KB(未提供下载压缩版本;可能会压缩到~20KB)。看起来非常全面,包括测试,但我对它不太熟悉。

  • meltdown:41KB(未提供下载压缩版本;可能会压缩到~15KB)。jQuery插件;Markdown Extra(表格、定义列表、脚注)。

  • unified.js:变化,5-100KB。一个基于插件的系统,用于在html、markdown和散文之间进行转换。根据您需要的插件(拼写检查、语法高亮、输入清理),文件大小将有所不同。可能更多地在服务器端使用而不是客户端。


谢谢,非常有用!我刚刚使用了showdownfetch(参考了一下Jake Archibald的"That's So Fetch")将Markdown文件读入我的静态HTML页面并将它们转换为HTML。太棒了 :-) - Dave Everitt
@DaveEveritt 很好 - 除非你的目标浏览器是固定的,否则不要忘记包含一个fetch polyfill。这将适用于您的目的,并且很小:https://github.com/developit/unfetch - Adam Leggett
同意,感谢提供链接,尽管我认为现在只有少数浏览器需要这个 - 三星在新版本中支持,而我不再针对IE,尽管我知道许多开发人员需要... https://caniuse.com/#feat=fetch - Dave Everitt
1
你有计划在drawdown上添加<table>功能吗?我尝试过自己添加,但是超出了我的理解范围。;( - jack
@AdamLeggett 谢谢! - jack
非常棒,感谢您提供如此详尽的答案! - deryb

14

Textile

你可以在这里找到一个看起来非常好的Textile的Javascript实现,还有另一个这里(也许不太好,但是有一个很好的随写随转换的示例页面)。

注意: 我在第一个链接中提供的实现中有一个错误:横杠没有正确呈现。要修复它,您可以将以下代码添加到文件中。

for(i=0;i<lines.length;i++) {
    // Add code :Start
    if (lines[i].match(/\s*-{4,}\s*/)){
      html+="<hr/>\n";
      continue;
    }
    // Add code :End
    if (lines[i].indexOf("[") == 0) {continue;}
    //...

13

我正在使用一个极简的脚本 - mmd.js,它仅支持Markdown的部分功能。不过,这可能就是人们所需要的所有功能,所以这个小于1kb的脚本非常惊人,不会造成太大负担。

支持的特性

  • 标题 #
  • 引用 >
  • 有序列表 1
  • 无序列表 *
  • 段落
  • 链接 []()
  • 图片 ![]()
  • 内联强调 *
  • 内联强调 **

不支持的特性

  • 引用和ID
  • Markdown字符转义
  • 嵌套

这真的很棒! - Arthur Ronconi
1
我们可以使用npm install安装mmd.js吗?我真的很想在我的项目中尝试它。 - sudhir shakya
2
https://adamvleggett.github.io/drawdown/并不比较大,但支持更多的Markdown语法,并且具有更高的灵活性。 - Adam Leggett

5

我发现这个问题很有趣,所以我决定开始尝试(只替换 strongitalic markdown 标签)。花了一个小时尝试使用正则表达式来设计一个解决方案后,我放弃了,并得到了以下解决方案,它似乎运行良好。话虽如此,它肯定可以进一步优化,而且我不确定它在这种形式下有多少真实世界的弹性:

function mdToHtml(str) {
    var tempStr = str;
    while(tempStr.indexOf("**") !== -1) {
        var firstPos = tempStr.indexOf("**");
        var nextPos = tempStr.indexOf("**",firstPos + 2);
        if(nextPos !== -1) {
            var innerTxt = tempStr.substring(firstPos + 2,nextPos);
            var strongified = '<strong>' + innerTxt + '</strong>';
            tempStr = tempStr.substring(0,firstPos) + strongified + tempStr.substring(nextPos + 2,tempStr.length);
        //get rid of unclosed '**'
        } else {
            tempStr = tempStr.replace('**','');
        }
    }
     while(tempStr.indexOf("*") !== -1) {
        var firstPos = tempStr.indexOf("*");
        var nextPos = tempStr.indexOf("*",firstPos + 1);
        if(nextPos !== -1) {
            var innerTxt = tempStr.substring(firstPos + 1,nextPos);
            var italicized = '<i>' + innerTxt + '</i>';
            tempStr = tempStr.substring(0,firstPos) + italicized + tempStr.substring(nextPos + 2,tempStr.length);
        //get rid of unclosed '*'
        } else {
            tempStr = tempStr.replace('*','');
        }
    }
    return tempStr;
}

测试代码:

    var s = "This would be *italicized* text and this would be **bold** text, This would be *italicized* text and this would be **bold** text, This would be *italicized* text and this would be **bold** text";
    alert(mdToHtml(s));

输出:

This would be <i>italicized</i>text and this would be <strong>bold</strong> text, This would be <i>italicized</i>text and this would be <strong>bold</strong> text, This would be <i>italicized</i>text and this would be <strong>bold</strong> text

编辑:V0.024新增 - 自动删除未闭合的Markdown标签


5

使用Showdown很容易带或不带jQuery。这是一个jQuery示例:

// See http://mathiasbynens.be/notes/showdown-javascript-jquery for a plain JavaScript version as well
$(function() {
 // When using more than one `textarea` on your page, change the following line to match the one you’re after
 var $textarea = $('textarea'),
     $preview = $('<div id="preview" />').insertAfter($textarea),
     converter = new Showdown.converter();
 $textarea.keyup(function() {
  $preview.html(converter.makeHtml($textarea.val()));
 }).trigger('keyup');
});

4

3
让我们编写一个简单的Markdown解析器函数,它将接收一行Markdown并将其翻译为适当的HTML。为了简单起见,我们只支持Markdown语法中的一种特性:标题。
标题由(1-6)个井号和一个空格后跟文本来指定。井号的数量确定HTML输出的标题级别。
function markdownParser(markdown) {
  const htmlText = markdown
    .replace(/^# (.*$)/gim, '<h1>$1</h1>')
    .replace(/^## (.*$)/gim, '<h2>$1</h2>')
    .replace(/^### (.*$)/gim, '<h3>$1</h3>')
    .replace(/^#### (.*$)/gim, '<h4>$1</h4>')
    .replace(/^##### (.*$)/gim, '<h5>$1</h5>')
    .replace(/^###### (.*$)/gim, '<h6>$1</h6>')
 return htmlText.trim() 
}

3

对我来说,这个库无法正确解释带有数字列表(使用#)的内容。 - david

1

markdown-js 是一个不错的 JavaScript Markdown 解析器,是一个带有测试的活跃项目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接