| @@ -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() | |||