2

我为我的大学写了一封每周摘要邮件,邮件格式如下:

############################
#          HEADER          #
# ======================== #
#   IMAGE | Title          #
#         | Description    #
# ------------------------ #
#           ...            #
# ------------------------ #
#   IMAGE | Title          #
#         | Description    #
# ======================== #
#          FOOTER          #
############################

目前,这些都是每周通过 Copy-Paste-Tweak 从一个可怕的 HTML 模板构建的。

我使用 Markdown 写博客并经常使用 Markdown,我想知道是否有某种方法可以轻松使用它来解析包含摘要的主要详细信息的文件以产生上述输出?

“摘要电子邮件”(包括其他字段)的基本结构是

- header
  - main title
  - subtitle
  - date

- entry
  - image
  - title
  - body
   ...
- entry
  - image
  - title
  - body

- footer text

我想以上面的格式呈现出来。

我有一些初步的想法,希望能提供以下方面的意见:

  • Ruby/Python 中的 YAML + 自定义处理器 - 但是降价格式的条目主体如何工作?
  • Redcarpet似乎允许自定义渲染,但我可以将其转换为上述格式吗?
  • Python Markdown - 我看到一些关于使用 python-markdown 扩展 markdown 的帖子,但我不确定它在这里的适用性如何?

毫无疑问,我忽略了一些非常简单的实现。

**更新**

对于这个问题的含糊之处,我深表歉意。我无法真正优雅地描述我正在尝试做的事情:(

最后,我使用了一个带有多行字符串的 YAML 文件,后来使用 Maruku 将其解析为 Markdown。

对于那些对它的工作原理和最终结果感兴趣的人,该项目在 github

4

3 回答 3

1

这是用于 html 输出的 python 版本。 输出

import markdown
import pprint
import yaml
from mako.template import Template

pp = pprint.PrettyPrinter(indent=4)

MAX_WIDTH=50
raw = """
header:
    main_title: title text
    subtitle: subtitle text
    date: 2012-11-13

entries:
    - image: https://upload.wikimedia.org/wikipedia/en/c/cb/Placeholder_logo.png
      title: title1
      body: >
        Lorem ipsum dolor sit amet,
         consectetuer adipiscing elit,
         sed diam **nonummy** nibh euismod
         tincidunt ut laoreet dolore
         magna aliquam erat volutpat.

    - image: https://upload.wikimedia.org/wikipedia/en/c/cb/Placeholder_logo.png
      title: title2
      body: >
        * Lorem ipsum dolor sit amet,

        * consectetuer adipiscing elit,

        * sed diam **nonummy** nibh euismod

        * tincidunt ut laoreet dolore

        * magna aliquam erat volutpat.

footer:
    text: i'm footer
"""
stream = yaml.load(raw)

for i in range(len(stream['entries'])):
    stream['entries'][i]['html'] = markdown.markdown(stream['entries'][i]['body'])

md_template = """
<table>
    <tr><td colspan=2><h2>${stream['header']['main_title']}</h2></td></tr>
    <tr><td colspan=2><h3>${stream['header']['subtitle']}</h3></td></tr>
    <tr><td colspan=2><h3>${str(stream['header']['date'])}</h3></td></tr>

    % for x in stream['entries']:
        <tr>
            <td>
            <img src=${x['image']}>
            </td>
            <td>
            <h3>${x['title']}</h3>
            </br>
            ${x['html']}
            </td>
        </tr>
    % endfor
</table>
"""

print Template(md_template).render(stream = stream)
于 2012-11-13T02:06:27.000 回答
1

这听起来像是 Jekyll 的一个很好的用例:https ://github.com/mojombo/jekyll

或者,您可以使用任何模板系统(ERb、Haml 等)+ 任何 Markdown 系统(我喜欢 RedCarpet),然后使用一个简单的 Ruby 对象从 Markdown 文件中提取 YAML frontmatter:

  class Page
    def initialize(source_file)
      self.filename = File.basename(source_file)

      read_page(source_file)
    end

    attr_reader :filename, :metadata, :contents

    private

    attr_writer :filename, :metadata, :contents

    def read_page(filename)
      self.contents = File.read(filename)

      begin
        if (md = contents.match(/^(?<headers>---\s*\n.*?\n?)^(---\s*$\n?)/m))
          self.contents = md.post_match
          self.metadata = YAML.load(md[:headers])
        end
      rescue => e
        puts "YAML Exception reading #{filename}: #{e.message}"
      end
    end
  end

使用这个对象,假设你有一个文件被调用first_post.md,内容如下:

---
title: First Post
category: essays
---

# My First Post!

It's *really* awesome

您可以通过Page以下方式使用对象处理它:

page = Page.new("first_post.md")
p page.metadata[:title]    #=> "First Post"
p page.metadata[:category] #=> "essays"
p page.contents            #=> "# My First Post!\n\nIt's *really* awesome"

markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
formatted_content = markdown.render(page.contents)
   #=> "<h1>My First Post!</h1>\n\n<p>It&#39;s <em>really</em> awesome</p>\n"

从这里开始,您需要做的就是连接模板引擎。如果您已经在使用 HTML 模板,ERb 可能是最简单的。

您将有一个名为 的模板layout.erb,这将是一个混合了一些 Ruby 的 HTML 文件:

<html>
  <body>
     <h1><%= page.metadata[:title] %></h1>
     <%= formatted_content %>
  </body>
<html>

然后,您将执行以下操作:

puts ERB.new(File.read("layout.erb")).result(binding)

从那里开始,我认为您将拥有所需的东西,但显然您首先需要以更有条理的方式将所有这些缝合在一起:-)

于 2012-11-12T19:13:16.643 回答
-1

我认为您需要一个名为 texttable 的库来格式化多行文本。然后你可以使用正则表达式来替换你需要的装饰。

__author__ = 'mmyjona'
#coding=utf-8

import pprint
from texttable import Texttable
import yaml

pp = pprint.PrettyPrinter(indent=4)

#set the width here
MAX_WIDTH=50
raw = """
header:
    main_title: title text
    subtitle: subtitle text
    date: 2012-11-13

entries:
    - image: 1.jpg
      title: title1
      body: Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

    - image: 2.jpg
      title: title2
      body: Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

footer:
    text: i'm footer
"""
stream = yaml.load(raw)

pp.pprint(stream)

tar = """
############################
#          HEADER          #
# ======================== #
#   IMAGE | Title          #
#         | Description    #
# ------------------------ #
#           ...            #
# ------------------------ #
#   IMAGE | Title          #
#         | Description    #
# ======================== #
#          FOOTER          #
############################
"""
table1 = Texttable()
table1.__init__(max_width=MAX_WIDTH)
table1.set_chars(['=', '|', '+', '-'])
table1.set_cols_align(["r", "l"])
table1.set_cols_valign(["t", "t"])
table1.add_rows([["foo","bar"]
    ,["Main Title",stream['header']['main_title']+"\n"]
    ,["Subtitle",stream['header']['subtitle']+"\n"]
    ,["Date",str(stream['header']['date'])+"\n"]
])

for x in stream['entries']:
    table1.add_row([x['image'],x['title'] + "\n" + x['body']])

table1.add_row(['Footer', stream['footer']['text']])
print table1.draw() + "\n"

输出:

{   'entries': [   {   'body': 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.',
                       'image': '1.jpg',
                       'title': 'title1'},
                   {   'body': 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.',
                       'image': '2.jpg',
                       'title': 'title2'}],
    'footer': {   'text': "i'm footer"},
    'header': {   'date': datetime.date(2012, 11, 13),
                  'main_title': 'title text',
                  'subtitle': 'subtitle text'}}
+=======================+=======================+
|          foo          |          bar          |
+-----------------------+-----------------------+
|            Main Title | title text            |
+=======================+=======================+
|              Subtitle | subtitle text         |
+=======================+=======================+
|                  Date | 2012-11-13            |
+=======================+=======================+
|                 1.jpg | title1                |
|                       | Lorem ipsum dolor sit |
|                       | amet, consectetuer    |
|                       | adipiscing elit, sed  |
|                       | diam nonummy nibh     |
|                       | euismod tincidunt ut  |
|                       | laoreet dolore magna  |
|                       | aliquam erat          |
|                       | volutpat. Ut wisi     |
|                       | enim ad minim veniam, |
|                       | quis nostrud exerci   |
|                       | tation ullamcorper    |
|                       | suscipit lobortis     |
|                       | nisl ut aliquip ex ea |
|                       | commodo consequat.    |
+=======================+=======================+
|                 2.jpg | title2                |
|                       | Lorem ipsum dolor sit |
|                       | amet, consectetuer    |
|                       | adipiscing elit, sed  |
|                       | diam nonummy nibh     |
|                       | euismod tincidunt ut  |
|                       | laoreet dolore magna  |
|                       | aliquam erat          |
|                       | volutpat. Ut wisi     |
|                       | enim ad minim veniam, |
|                       | quis nostrud exerci   |
|                       | tation ullamcorper    |
|                       | suscipit lobortis     |
|                       | nisl ut aliquip ex ea |
|                       | commodo consequat.    |
+=======================+=======================+
|                Footer | i'm footer            |
+=======================+=======================+
于 2012-11-12T18:28:29.960 回答