【问题标题】:Markdown: how to show a preview (such as the first N words)Markdown:如何显示预览(比如前N个字)
【发布时间】:2016-01-06 14:55:54
【问题描述】:

我正在使用 Rails 4 和 Kramdown,但我相信这个问题可以扩展到任何支持 Markdown 的(网络)编程语言。

我正在制作一个博客网站。在概述页面上,我想显示每篇文章的开头。

由于文章可能很长,我只想展示第一部分。

一个简单的想法是在 N 个字符后截断文章。一个稍微好一点的想法是在 N 个单词后截断文章。

当然,在处理包含附加标记(例如降价)的文档时,这可能并且将会破坏内容,因此需要另一种解决方案。

如何在不破坏 Markdown 标记的情况下只显示 Markdown 文档的第一个,比如 100 个单词?

【问题讨论】:

  • 你可以使用^[\S\s]{N}
  • @Tushar:请注意,如果您启动了斜体环境 (*),它将被切断等...

标签: regex string markdown blogs string-split


【解决方案1】:
Let's use this **sample document** with _various_ types of [Markdown](http://daringfireball.net/projects/markdown/) markup.

现在,假设您使用前 20 个字符。你会得到:

Let's use this **sam

100 个字符给你:

Let's use this **sample document** with _various_ types of [Markdown](http://dar

虽然这些 char 长度是任意的,并且可能不是您会使用的长度,但关键是它们中的每一个都破坏了 Markdown 语法。更好的方法是将文档解析为 HTML,然后拆分 HTML 文档的开头。

当然,出于同样的原因,您可能希望以某种方式使用 HTML 文档模型,而不是根据原始字符长度进行拆分。为什么不直接取第一段呢?如果段落太长,则在第 N 个字符处中断,但只计算正文中的字符,而不是构成 HTML 标记的字符。如何做到这一点取决于您用来处理 HTML 的工具/库,这不是提出工具建议的地方(而且我对 Ruby/Rails 不是很熟悉——更像是一个 Python 人)。

请注意,我在上面给出的第二个示例打破了链接 URL 中间的 Markdown。如果您首先将 Markdown 转换为 HTML 并仅中断计数文本字符,那么即使链接文本(标签)被截断,URL 也会保持不变。尽管在这种情况下,最好在链接结束后截断文本。这取决于你想让你的代码有多复杂。

下一步自然是问为什么不使用 Markdown 文本而不是先将整个文档转换为 HTML 呢?你可以,但是你会重新实现你自己的 Markdown 解析器......除非你碰巧使用了一个 Markdown 解析器,它可以让你访问内部(通过一些插件 API)或输出一个解析三。如果您使用的是返回解析树的解析器,则可以截断解析树,然后将其传递给渲染器。除此之外,使用解析过的 HTML 可能是最好的选择。

无论哪种方式,让我们通过一个例子来工作。上面示例的 HTML 看起来像这样:

<p>Let's use this <strong>sample document</strong> with <emphasis>various</emphasis> types of <a href="http://daringfireball.net/projects/markdown/">Markdown</a> documents</p>

现在,让我们将该文档表示为某种伪文档对象(使用 JSON):

[{
    'type': 'element',
    'tag': 'p',
    'children' :
        [
            {
                'type': 'text',
                'text': "Let's use this "
            },
            {
                'type': 'element',
                'tag': 'strong',
                'children': 
                    [
                        {
                            'type': text,
                            'text': "sample document"
                        }
                    ]
            },
            {
                'type': 'text',
                'text': " with "
            },
            {
                'type': 'element',
                'tag': 'emphasis',
                'children': 
                    [
                        {
                            'type': text,
                            'text': "various"
                        }
                    ]
            },
            {
                'type': 'text',
                'text': " types of "
            },
            {
                'type': 'element',
                'tag': 'a',
                'href': 'http://daringfireball.net/projects/markdown/'
                'children': 
                    [
                        {
                            'type': text,
                            'text': "Markdown"
                        }
                    ]
            },
            {
                'type': 'text',
                'text': "  markup."
            }
        ]
}]

现在,只需遍历该文档(及其子文档),只计算“文本”类型的“文本”字段的字符数,直到达到最大值。然后截断文档中之后的任何其他元素。当文档被渲染(使用适当的 HTML 渲染器)时,所有的 HTML 元素都将被正确关闭。显然,确切的过程将取决于文档包含在哪种文档对象中(这可能取决于您使用的 HTML 解析器和/或 Markdown 解析器)。

无论如何,截断为 20 个字符的文档会导致:

[{
    'type': 'element',
    'tag': 'p',
    'children' :
        [
            {
                'type': 'text',
                'text': "Let's use this "
            },
            {
                'type': 'element',
                'tag': 'strong',
                'children': 
                    [
                        {
                            'type': text,
                            'text': "sampl"
                        }
                    ]
            },
        ]
}]

这将呈现为:

<p>Let's use this <strong>sampl</strong></p>

请注意,仅文本 (Let's us this sampl) 计为 20 个字符。

虽然上述示例使用字符,但您当然可以使用相同的原则并计算字数。

【讨论】:

  • 这是一个很好的例子和演练。为什么这不是图书馆?
猜你喜欢
  • 2010-11-20
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
相关资源
最近更新 更多