【问题标题】:Implementing preview for markdown text实现 Markdown 文本的预览
【发布时间】:2016-04-27 07:36:18
【问题描述】:

我正在开发 Ruby on Rails 项目,我已经使用 redcarpet gem 为我的项目中的一些文本描述实现了降价语法。

它的工作原理就像魅力一样,允许将 Markdown 文本转换为 HTML,就像

<%= markdown some_text_variable %>

但现在我想实现预览功能,只渲染全文的一小部分。

下面的幼稚构造

<%= markdown some_text_variable[0..preview_length] %>

不会起作用,因为它很容易分解 MD 语法,从而导致结构混乱(想象一下,例如,在图像链接的一半上拆分原始字符串)。

我想出了

<%= markdown some_text_variable[0..preview_length].split(/\r?\n/)[0..-2].join("\r\n")) %>

但它不处理例如代码块。

有没有什么方法可以实现这样的MD文本预览?

【问题讨论】:

  • 你能遍历 markdown 语法数组并检查匹配换行符和任何 markdown 字符的正则表达式吗?如果为真,(有开始和结束),打印切片,如果为假,(在下一个结束或换行之前有开始但没有结束并且没有打开标签),添加结束标签并打印切片?
  • @BottledSmoke 是不是太复杂了?以及如何处理没有结束标签的列表?我想出了在新行上切片的想法(但不少于一定数量的字符)。但它也不处理列表...
  • 是的,我刚刚意识到您可以使用降价和摊牌。你必须原谅我。我刚起床:)

标签: ruby-on-rails ruby markdown redcarpet


【解决方案1】:

使用markdown.js 和/或showdown 应该可以。 Here's a StackO with the same question and answer。我个人之前在 Ember 应用程序中使用过摊牌来呈现文本的实时预览,因为它正在被键入(通过 2 路数据绑定),并且它完美地工作。

在下面的小提琴中,我编写了一个小摊牌解析器,它接收一个 markdown 字符串,在换行符上拆分它(返回一个标签数组),然后遍历数组。在每次迭代中,它会删除标签,检查结果字符串的长度,然后将其与预览的最大字符数进行比较。一旦下一次迭代超过最大字符数,它就会返回预览。 do 循环可确保您始终获得至少一个 html blob 作为预览。

Fiddle

$(function() {
  var converter = new Showdown.converter();
  var previewMax = 200;

  $('button').click(function() {        
    var content = $('#markdown').val(),
        charCount = 0,
        i = 0,
        output = '';

    if (!content) {
      return $('div.preview').html("Please enter some text.");
    }

    var mark = converter.makeHtml(content);
    var mark_arr = mark.split('\n');

    while (charCount < previewMax) {
      var html = mark_arr[i];
      var text = htmlStrip(html);            

      if ((charCount + text.length) > previewMax) {
        var overflow = (charCount + text.length) - previewMax;
        var clipAmount = text.length - overflow;
        html = jQuery.truncate(mark_arr[i], { length: clipAmount });
        }

      output += html;
      charCount += text.length;
      i++;
    };

    $('div.preview').html(output);
    $('div.full').html(mark);
  });

  function htmlStrip (html) {
    var div = document.createElement('div');
    div.innerHTML = html;
    var text = div.textContent || div.innerText || "";
    return text;
  }
});

修订

我使用jQuery Truncate 更新了函数,将最终字符串切割成省略号,这样您的所有预览都与其他预览的长度相同。另外,我意识到原始函数在没有输入文本时一遍又一遍地返回一长串未定义的字符串,因此有一个检查可以消除它。由于这个循环现在总是会返回至少一个 html 项,我将 do 循环更改为 while 循环以便于阅读。最后,如果您希望截断始终以单词边界结束,请在调用时传递words: true 选项。显然,这不会为每个预览提供相同级别的截断,但会提高易读性。就是这样!

【讨论】:

  • 感谢您的好主意!但是,如果我渲染一大块数据,它将包含 HTML 标记,所以我将无法只在中间分割字符串......
  • 是的,我意识到了这一点,所以我编辑了我的答案。这样的事情会奏效吗?
  • IMO 最难的部分是找出准确的正则表达式用于您的算法。
  • 抱歉,您不需要正则表达式。昨天是圣帕蒂。当早晨像货运列车一样来袭时,我的头不太对劲。我再次用一个可以解决您的问题或至少为您指明正确方向的小提琴修改了我的答案(不涉及正则表达式)。
  • 哇!非常感谢您在该问题上花费的精力和时间!如果可能的话,我真的会投票至少 10 次 :)
【解决方案2】:

我想分享我的预览版,它非常简单,带有 showdown.jsprism.js 语法突出显示。

Prism.js 可以轻松使用 JavaScript 和 CSS 进行语法化。您只需要选择特定语言并将其下载到资产文件夹即可。或者您可以将其指定到特定页面。

这将在实时预览中以表格形式发生。

Rails 形式:

<div class="col-md-12">
  <div class="form-group">
    <%= f.label :body %>
    <%= f.text_area :body, class: "form-control", rows: 10 %>
  </div>
</div>


<div class="col-md-12">
  <h1> Preview Markdown </h1>
  <div class="form-group markdownOutput"></div>
</div>

并在表单页面正下方添加此脚本。

<script>
function mkdown(){
  var converter  = new showdown.Converter(),
      $post_body = $("#post_body");

  // This line will keep adding new rows for textarea. 
  function postBodyLengthDetector(post_body){
    var lines = post_body.val().split("\n");
    post_body.prop('rows', lines.length+5);
  }


  // Textarea rows in default '10', when focusing on this. It will expand. 
  $post_body.focus(function(){
    postBodyLengthDetector($(this));
    $('.markdownOutput').html(converter.makeHtml($post_body.val()));
  });

  // All simple magic goes here, each time when texting anything into textarea
  //it will be generated to markdown. You are able to see preview right below of textarea.
  $post_body.keyup(function() {
    postBodyLengthDetector($(this));
      var value = $( this ).val(),
          html  = converter.makeHtml(value);
          $('.markdownOutput').html(html);
  });
}
$(mkdown);
$(document).on("turbolinks:load", mkdown);
</script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    相关资源
    最近更新 更多