2

私は自分の大学のために毎週ダイジェスト メールを書きます。このメールは次のメール形式で表示されます。

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

現在、これらは Copy-Paste-Tweak を介して恐ろしい HTML テンプレートから毎週構築されています。

私は Markdown でブログを書いて定期的に使用していますが、ダイジェストの主な詳細を含むファイルを簡単に解析して上記の出力を生成する方法があるかどうか疑問に思っています。

「ダイジェスト メール」の基本構造 (その他のフィールドを含む) は次のとおりです。

- header
  - main title
  - subtitle
  - date

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

- footer text

そして、上記の形式でレンダリングしたいと思います。

私が持っていたいくつかの初期のアイデアと、いくつかの意見をいただければ幸いです。

  • YAML + Ruby/Python のカスタム プロセッサ - しかし、マークダウン形式のエントリ ボディはどのように機能しますか?
  • Redcarpetはカスタム レンダリングを許可しているようですが、上記の形式に組み込むことはできますか?
  • Python Markdown - python-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 が好きです) を使用してから、Markdown ファイルから YAML フロントマターを抽出するための単純な Ruby オブジェクトを使用できます。

  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 に答える