扩展

标准扩展

CoffeeScript

Plim 使用 Python-CoffeeScript 包作为 JS 与 CoffeeScript 之间的桥梁。你可以使用 -coffee 作为 CoffeeScript 代码块标记。

- coffee
  # Assignment:
  number   = 42
  opposite = true

  # Conditions:
  number = -42 if opposite

  # Functions:
  square = (x) -> x * x

  # Arrays:
  list = [1, 2, 3, 4, 5]

  # Objects:
  math =
    root:   Math.sqrt
    square: square
    cube:   (x) -> x * square x

  # Splats:
  race = (winner, runners...) ->
    print winner, runners

  # Existence:
  alert "I knew it!" if elvis?

  # Array comprehensions:
  cubes = (math.cube num for num in list)

SCSS/SASS

Plim 使用 pyScss 包将 SCSS/SASS 翻译为普通的 CSS。你可以使用 -scss-sass 作为 SCSS/SASS 代码块标记。输出结果中将会自动包裹在 <style></style> 标签中。

例如:

- scss
  @option compress: no;
  .selector {
    a {
      display: block;
    }
    strong {
      color: blue;
    }
  }

输出:

<style>.selector a {
  display: block;
}
.selector strong {
  color: #00f;
}</style>

Stylus

Plim uses stylus package to translate stylus markup to plain CSS. You can start Stylus block with the -stylus construct. The output will be wrapped with <style></style> tags.

例如:

- stylus
  @import 'nib'
  body
    background: linear-gradient(top, white, black)

  border-radius()
    -webkit-border-radius arguments
    -moz-border-radius arguments
    border-radius arguments

  a.button
    border-radius 5px

输出:

<style>body {
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #000));
  background: -webkit-linear-gradient(top, #fff 0%, #000 100%);
  background: -moz-linear-gradient(top, #fff 0%, #000 100%);
  background: -o-linear-gradient(top, #fff 0%, #000 100%);
  background: -ms-linear-gradient(top, #fff 0%, #000 100%);
  background: linear-gradient(top, #fff 0%, #000 100%);
}
a.button {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}</style>

Markdown

Plim uses python-markdown2 package for the -markdown (or -md) extension.

例如:

- markdown
  A First Level Header
  ====================

  A Second Level Header
  ---------------------

  Now is the time for all good men to come to
  the aid of their country. This is just a
  regular paragraph.

  The quick brown fox jumped over the lazy
  dog's back.

  ### Header 3

  > This is a blockquote.
  >
  > This is the second paragraph in the blockquote.
  >
  > ## This is an H2 in a blockquote

输出:

<h1>A First Level Header</h1>

<h2>A Second Level Header</h2>

<p>Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.</p>

<p>The quick brown fox jumped over the lazy
dog's back.</p>

<h3>Header 3</h3>

<blockquote>
    <p>This is a blockquote.</p>

    <p>This is the second paragraph in the blockquote.</p>

    <h2>This is an H2 in a blockquote</h2>
</blockquote>

reStructuredText

Plim 使用 python-markdown2 作为 -markdown (或者 -md) 扩展。

例如:

- rest
  Grid table:

  +------------+------------+-----------+
  | Header 1   | Header 2   | Header 3  |
  +============+============+===========+
  | body row 1 | column 2   | column 3  |
  +------------+------------+-----------+
  | body row 2 | Cells may span columns.|
  +------------+------------+-----------+
  | body row 3 | Cells may  | - Cells   |
  +------------+ span rows. | - contain |
  | body row 4 |            | - blocks. |
  +------------+------------+-----------+

输出:

<p>Grid table:</p>
<table border="1">
  <thead valign="bottom">
    <tr>
      <th>Header 1
      </th><th>Header 2
      </th><th>Header 3
    </th></tr>
  </thead>
  <tbody valign="top">
    <tr>
      <td>body row 1
      </td><td>column 2
      </td><td>column 3
    </td></tr>
    <tr>
      <td>body row 2
      </td><td colspan="2">Cells may span columns.
    </td></tr>
    <tr>
      <td>body row 3
      </td><td rowspan="2">Cells may<br>span rows.
      </td><td rowspan="2">
        <ul>
          <li>Cells
          </li><li>contain
          </li><li>blocks.
        </li></ul>
    </td></tr>
    <tr>
      <td>body row 4
    </td></tr>
</tbody></table>

Handlebars

handlebars 是 Plim 支持的一个特殊标签,将会翻译为 handlebars

<script type="text/x-handlebars"></script>

这对 Ember.js 开发者来说非常便利。

例如,下面的 Plim 文档

html
    body
        handlebars#testapp
            .container {{outlet}}

        handlebars#about: .container {{outlet}}

将会成为

<html>
    <body>
        <script type="text/x-handlebars" id="testapp">
            <div class="container">{{outlet}}</div>
        </script>
        <script type="text/x-handlebars" id="about">
            <div class="container">{{outlet}}</div>
        </script>
    </body>
</html>

使用定制的分析器扩展 Plim

0.9.2 新版功能.

你也可以自己扩展 Plim 标签,该功能允许你在 Plim 之上定义自己的 DSL。例如,下面的代码将定义一个新的 HTML 链接解释器,将会处理 http_url > title 形式的链接。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# my_module.py
import re
from plim import preprocessor_factory


PARSE_HTTP_LINKS_RE = re.compile('(?P<url>https?://[^>]+)+\s+>\s+(?P<title>.*)')


def parse_http_link(indent_level, current_line, matched, source, syntax):
    url = matched.group('url')
    url_title = matched.group('title')
    rt = '<a href="{}">{}</a>'.format(url, url_title)
    return rt, indent_level, '', source


CUSTOM_PARSERS = [
    (PARSE_HTTP_LINKS_RE, parse_http_link)
]


custom_preprocessor = preprocessor_factory(custom_parsers=CUSTOM_PARSERS, syntax='mako')

parse_http_link() 函数的定义严格地遵循了 Plim API,

所有扩展解释器都应该接受 5 个参数:

  1. indent_level - an indentation level of the current line. When the parser reaches a line which indentation is lower or equal to indent_level, it returns control to a top-level function.
  2. current_line - a line which is being parsed. This is the line that has been matched by matched object at the previous parsing step.
  3. matched - an instance of re.MatchObject of the regex associated with the current parser.
  4. source - an instance of an enumerated object returned by plim.lexer.enumerate_source().
  5. syntax - an instance of one of plim.syntax.BaseSyntax children.

并返回 4 位元组:

  1. parsed_data - a string of successfully parsed data
  2. tail_indent - an indentation level of the tail line
  3. tail_line - a line which indentation level (tail_indent) is lower or equal to the input indent_level.
  4. source - an instance of enumerated object returned by plim.lexer.enumerate_source() which represents the remaining (untouched) plim markup.

现在我们已经可以像使用标准 Plim 预处理器 plim.preprocessor 一样使用 custom_preprocessor 了。

让我们使用新定义的语法来创建一个 plim 文档:

1
2
3
4
5
6
7
8
9
/ hamilton.plim
---------------
html
    head:title Alexander Hamilton
    body
        h1 Alexander Hamilton
        ul
            li: http://en.wikipedia.org/wiki/Alexander_Hamilton > Wikipedia Article
            li: http://www.amazon.com/Alexander-Hamilton-Ron-Chernow/dp/0143034758 > Full-length Biography

将会输出这样的有效 HTML (注意 -p 参数):

$ plimc -H -p my_module:custom_preprocessor hamilton.plim

输出结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<html>
    <head>
        <title>Alexander Hamilton</title>
    </head>
    <body>
        <h1>Alexander Hamilton</h1>
        <ul>
            <li><a href="http://en.wikipedia.org/wiki/Alexander_Hamilton">Wikipedia Article</a></li>
            <li><a href="http://www.amazon.com/Alexander-Hamilton-Ron-Chernow/dp/0143034758">Full-length Biography</a></li>
        </ul>
    </body>
</html>