@@ -24,7 +24,7 @@ class SyntextPlugin(TextyPlugin): | |||
""" | |||
The default pattern for block open text. | |||
""" | |||
return '^\s*~~~+\s*([A-Za-z0-9_\-\.]+)\s*~*\s*$' | |||
return '^\s*~~~+\s*([A-Za-z0-9_\-\.:\']+)\s*~*\s*$' | |||
@property | |||
def default_close_pattern(self): | |||
@@ -33,6 +33,18 @@ class SyntextPlugin(TextyPlugin): | |||
""" | |||
return '^\s*~~~+\s*$' | |||
def get_params(self, match, start=True): | |||
""" | |||
~~~css~~~ will return css | |||
~~~css/style.css will return css,style.css | |||
""" | |||
params = super(SyntextPlugin, self).get_params(match, start) | |||
if ':' in params: | |||
(lex, _, filename) = params.rpartition(':') | |||
params = 'lex=\'%(lex)s\',filename=\'%(filename)s\'' % locals() | |||
return params | |||
def text_to_tag(self, match, start=True): | |||
""" | |||
Replace open pattern (default:~~~~~css~~~~~~) | |||
@@ -64,13 +64,16 @@ class TextyPlugin(Plugin): | |||
""" | |||
return None | |||
def get_params(self, match, start=True): | |||
return match.groups(1)[0] if match.lastindex else '' | |||
@abc.abstractmethod | |||
def text_to_tag(self, match, start=True): | |||
""" | |||
Replaces the matched text with tag statement | |||
given by the template. | |||
""" | |||
params = match.groups(1)[0] if match.lastindex else '' | |||
params = self.get_params(match, start) | |||
return (self.template.get_open_tag(self.tag_name, params) | |||
if start | |||
else self.template.get_close_tag(self.tag_name, params)) | |||
@@ -64,11 +64,10 @@ def markdown(env, value): | |||
@environmentfilter | |||
def syntax(env, value, lexer=None): | |||
def syntax(env, value, lexer=None, filename=None): | |||
""" | |||
Processes the contained block using `pygments` | |||
""" | |||
try: | |||
import pygments | |||
from pygments import lexers | |||
@@ -87,7 +86,10 @@ def syntax(env, value, lexer=None): | |||
formatter = formatters.HtmlFormatter(**settings) | |||
code = pygments.highlight(value, pyg, formatter) | |||
code = code.replace('\n\n', '\n \n').replace('\n', '<br />') | |||
return Markup('\n\n<div class="code">%s</div>\n\n' % code) | |||
caption = filename if filename else pyg.name | |||
return Markup( | |||
'\n\n<div class="code"><figcaption>%s</figcaption>%s</div>\n\n' | |||
% (caption, code)) | |||
class Markdown(Extension): | |||
""" | |||
@@ -115,35 +117,66 @@ class Markdown(Extension): | |||
output = caller().strip() | |||
return markdown(self.environment, output) | |||
def parse_kwargs(parser): | |||
name = parser.stream.expect('name').value | |||
parser.stream.expect('assign') | |||
if parser.stream.current.test('string'): | |||
value = parser.parse_expression() | |||
else: | |||
value = nodes.Const(parser.stream.next().value) | |||
return (name, value) | |||
class Syntax(Extension): | |||
""" | |||
A wrapper around the syntax filter for syntactic sugar. | |||
""" | |||
tags = set(['syntax']) | |||
def parse(self, parser): | |||
""" | |||
Parses the statements and defers to the callback for pygments processing. | |||
""" | |||
lineno = parser.stream.next().lineno | |||
lex = None | |||
if parser.stream.current.type != 'block_end': | |||
lex = parser.stream.next().value | |||
lex = nodes.Const(None) | |||
filename = nodes.Const(None) | |||
def fail_syntax(): | |||
parser.fail( | |||
'Invalid syntax tag. Expected:' | |||
'{% syntax lex=yaml, filename=abc.yaml %} or' | |||
'{% syntax yaml, \'abc.yaml\' %}') | |||
if not parser.stream.current.test('block_end'): | |||
if parser.stream.look().test('assign'): | |||
name = value = name1 = value1 = None | |||
(name, value) = parse_kwargs(parser) | |||
if parser.stream.skip_if('comma'): | |||
(name1, value1) = parse_kwargs(parser) | |||
(lex, filename) = (value, value1) \ | |||
if name == 'lex' \ | |||
else (value1, value) | |||
else: | |||
lex = nodes.Const(parser.stream.next().value) | |||
if parser.stream.skip_if('comma'): | |||
filename = parser.parse_expression() | |||
body = parser.parse_statements(['name:endsyntax'], drop_needle=True) | |||
return nodes.CallBlock( | |||
self.call_method('_render_syntax', args=[nodes.Const(lex)]), | |||
self.call_method('_render_syntax', | |||
args=[lex, filename]), | |||
[], [], body).set_lineno(lineno) | |||
def _render_syntax(self, lex, caller=None): | |||
def _render_syntax(self, lex, filename, caller=None): | |||
""" | |||
Calls the syntax filter to transform the output. | |||
""" | |||
if not caller: | |||
return '' | |||
output = caller().strip() | |||
return syntax(self.environment, output, lex) | |||
return syntax(self.environment, output, lex, filename) | |||
class IncludeText(Extension): | |||
""" | |||
@@ -63,11 +63,25 @@ article { | |||
} | |||
} | |||
.highlight pre{ | |||
font-size: @gutter; | |||
.boxshadow(0, 1px, 3px, @qdark); | |||
padding: @gutter + 4 @gutter @gutter; | |||
line-height: @gutter * 2; | |||
margin-bottom: @gutter / 2 + 2; | |||
.code{ | |||
position: relative; | |||
figcaption{ | |||
font-size: @gutter - 2; | |||
position:absolute; | |||
bottom: @gutter * 2.5; | |||
right: @gutter; | |||
color: @qdark; | |||
} | |||
} | |||
.highlight | |||
{ | |||
pre{ | |||
font-size: @gutter; | |||
.boxshadow(0, 1px, 3px, @qdark); | |||
padding: @gutter + 4 @gutter @gutter; | |||
line-height: @gutter * 2; | |||
margin-bottom: @gutter / 2 + 2; | |||
} | |||
} |
@@ -92,6 +92,7 @@ Hyde is [socially coded][hydepy]. Feel free to [fork][forking]. | |||
5. Feed / Listing generation | |||
6. Translation | |||
[hydeid]: http://groups.google.com/group/hyde-dev/web/hyde-1-0 | |||
[Jekyll]: http://jekyllrb.com | |||
[evil twin]: http://ringce.com/blog/2009/introducing_hyde | |||
@@ -24,28 +24,27 @@ know the base template for that page. The plugin will automatically emit an | |||
The following two configurations are equivalent. | |||
~~~~~jinja~~~~ | |||
~~~~~jinja:hello.html~~~~ | |||
{% raw %} | |||
{% extends "base.html" %} | |||
<!-- hello.html --> | |||
{% block content %} | |||
Hello World! | |||
{% endblock %} | |||
{% endraw %} | |||
~~~~~~~~~~~~~~~ | |||
~~~~~jinja~~~~ | |||
~~~~~jinja:hello.html~~~~ | |||
{% raw %} | |||
=== | |||
extends: base.html | |||
=== | |||
<!-- hello.html --> | |||
{% block content %} | |||
Hello World! | |||
{% endblock %} | |||
{% endraw %} | |||
~~~~~~~~~~~~~~~ | |||
## Default blocks | |||
It gets even better. The auto extend plugin also allows you to specify | |||
@@ -54,12 +53,11 @@ the default block so that you can take out another wrapping curly brace. | |||
The following snippet is equivalent to the above ones: | |||
~~~~~jinja~~~~ | |||
~~~~~jinja:hello.html~~~~ | |||
=== | |||
extends: base.html | |||
default_block: content | |||
=== | |||
<!-- hello.html --> | |||
Hello World! | |||
~~~~~~~~~~~~~~~ | |||
@@ -71,21 +69,22 @@ As you can see, this makes the page _layout free_. | |||
In combination with metadata inheritance, this plugin can completely | |||
eliminate redundancy on many sites. | |||
Given the following configuration, the output would be same as what | |||
is generated by any of the above snippets. | |||
Given this configuration: | |||
~~~yaml~~~ | |||
site_name: Hello World #site.yaml | |||
~~~yaml:site.yaml~~~ | |||
site_name: Hello World | |||
meta: | |||
extends: base.html | |||
default_block: content | |||
~~~~~~~~~ | |||
~~~jinja~~~ | |||
<!-- hello.html --> | |||
the output of the following file be same as what | |||
is generated by any of the above snippets. | |||
~~~jinja:hello.html~~~ | |||
Hello World | |||
~~~~~~~~~~~ | |||
Just Content! | |||
Just content! | |||
===/doc=== |
@@ -25,17 +25,32 @@ Hyde's plugins get loaded if they are listed in the plugins section of | |||
respective sections. For example, `MyAwesomePlugin` will get parameters | |||
from `myawesome` section in the configuration file. | |||
# In the box | |||
## In the box | |||
Hyde is shipped with the following plugins: | |||
* Autoextend | |||
* Metadata | |||
* Sorter | |||
* Less CSS | |||
* Text Replacement Plugins | |||
- Blockdown | |||
- Mark and Refer | |||
- Textlinks | |||
- Syntext | |||
* Folder flattener | |||
* [Metadata][] | |||
* [Autoextend][] | |||
* [Sorter][] | |||
* [Less CSS][] | |||
* [Text Replacement Plugins][] | |||
- [Blockdown][] | |||
- [Mark and Refer][] | |||
- [Textlinks][] | |||
- [Syntext][] | |||
* [Folder flattener][] | |||
[Autoextend]: [[plugins/autoextend]] | |||
[Blockdown]: [[plugins/blockdown]] | |||
[Folder flattener]: Folder flattener | |||
[Less CSS]: Less CSS | |||
[Mark and Refer]: Mark and Refer | |||
[Metadata]: Metadata | |||
[Sorter]: Sorter | |||
[Syntext]: Syntext | |||
[Text Replacement Plugins]: Text Replacement Plugins | |||
[Textlinks]: Textlinks | |||
[configuration]: configuration | |||
[devdocs]: devdocs | |||
@@ -1,3 +1,3 @@ | |||
extends: site.yaml | |||
mode: production | |||
deploy_root: ../../../../hydepy.github.com | |||
deploy_root: ../../../../hyde.github.com |
@@ -15,7 +15,6 @@ TEST_SITE = File(__file__).parent.parent.child_folder('_test') | |||
def assert_valid_conversion(html): | |||
assert html | |||
q = PyQuery(html) | |||
print html | |||
assert "is_processable" not in html | |||
assert q("h1") | |||
assert "This is a" in q("h1").text() | |||