| @@ -24,7 +24,7 @@ class SyntextPlugin(TextyPlugin): | |||||
| """ | """ | ||||
| The default pattern for block open text. | 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 | @property | ||||
| def default_close_pattern(self): | def default_close_pattern(self): | ||||
| @@ -33,6 +33,18 @@ class SyntextPlugin(TextyPlugin): | |||||
| """ | """ | ||||
| return '^\s*~~~+\s*$' | 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): | def text_to_tag(self, match, start=True): | ||||
| """ | """ | ||||
| Replace open pattern (default:~~~~~css~~~~~~) | Replace open pattern (default:~~~~~css~~~~~~) | ||||
| @@ -64,13 +64,16 @@ class TextyPlugin(Plugin): | |||||
| """ | """ | ||||
| return None | return None | ||||
| def get_params(self, match, start=True): | |||||
| return match.groups(1)[0] if match.lastindex else '' | |||||
| @abc.abstractmethod | @abc.abstractmethod | ||||
| def text_to_tag(self, match, start=True): | def text_to_tag(self, match, start=True): | ||||
| """ | """ | ||||
| Replaces the matched text with tag statement | Replaces the matched text with tag statement | ||||
| given by the template. | 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) | return (self.template.get_open_tag(self.tag_name, params) | ||||
| if start | if start | ||||
| else self.template.get_close_tag(self.tag_name, params)) | else self.template.get_close_tag(self.tag_name, params)) | ||||
| @@ -64,11 +64,10 @@ def markdown(env, value): | |||||
| @environmentfilter | @environmentfilter | ||||
| def syntax(env, value, lexer=None): | |||||
| def syntax(env, value, lexer=None, filename=None): | |||||
| """ | """ | ||||
| Processes the contained block using `pygments` | Processes the contained block using `pygments` | ||||
| """ | """ | ||||
| try: | try: | ||||
| import pygments | import pygments | ||||
| from pygments import lexers | from pygments import lexers | ||||
| @@ -87,7 +86,10 @@ def syntax(env, value, lexer=None): | |||||
| formatter = formatters.HtmlFormatter(**settings) | formatter = formatters.HtmlFormatter(**settings) | ||||
| code = pygments.highlight(value, pyg, formatter) | code = pygments.highlight(value, pyg, formatter) | ||||
| code = code.replace('\n\n', '\n \n').replace('\n', '<br />') | 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): | class Markdown(Extension): | ||||
| """ | """ | ||||
| @@ -115,35 +117,66 @@ class Markdown(Extension): | |||||
| output = caller().strip() | output = caller().strip() | ||||
| return markdown(self.environment, output) | 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): | class Syntax(Extension): | ||||
| """ | """ | ||||
| A wrapper around the syntax filter for syntactic sugar. | A wrapper around the syntax filter for syntactic sugar. | ||||
| """ | """ | ||||
| tags = set(['syntax']) | tags = set(['syntax']) | ||||
| def parse(self, parser): | def parse(self, parser): | ||||
| """ | """ | ||||
| Parses the statements and defers to the callback for pygments processing. | Parses the statements and defers to the callback for pygments processing. | ||||
| """ | """ | ||||
| lineno = parser.stream.next().lineno | 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) | body = parser.parse_statements(['name:endsyntax'], drop_needle=True) | ||||
| return nodes.CallBlock( | return nodes.CallBlock( | ||||
| self.call_method('_render_syntax', args=[nodes.Const(lex)]), | |||||
| self.call_method('_render_syntax', | |||||
| args=[lex, filename]), | |||||
| [], [], body).set_lineno(lineno) | [], [], 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. | Calls the syntax filter to transform the output. | ||||
| """ | """ | ||||
| if not caller: | if not caller: | ||||
| return '' | return '' | ||||
| output = caller().strip() | output = caller().strip() | ||||
| return syntax(self.environment, output, lex) | |||||
| return syntax(self.environment, output, lex, filename) | |||||
| class IncludeText(Extension): | 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 | 5. Feed / Listing generation | ||||
| 6. Translation | 6. Translation | ||||
| [hydeid]: http://groups.google.com/group/hyde-dev/web/hyde-1-0 | [hydeid]: http://groups.google.com/group/hyde-dev/web/hyde-1-0 | ||||
| [Jekyll]: http://jekyllrb.com | [Jekyll]: http://jekyllrb.com | ||||
| [evil twin]: http://ringce.com/blog/2009/introducing_hyde | [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. | The following two configurations are equivalent. | ||||
| ~~~~~jinja~~~~ | |||||
| ~~~~~jinja:hello.html~~~~ | |||||
| {% raw %} | {% raw %} | ||||
| {% extends "base.html" %} | {% extends "base.html" %} | ||||
| <!-- hello.html --> | |||||
| {% block content %} | {% block content %} | ||||
| Hello World! | Hello World! | ||||
| {% endblock %} | {% endblock %} | ||||
| {% endraw %} | {% endraw %} | ||||
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~ | ||||
| ~~~~~jinja~~~~ | |||||
| ~~~~~jinja:hello.html~~~~ | |||||
| {% raw %} | {% raw %} | ||||
| === | === | ||||
| extends: base.html | extends: base.html | ||||
| === | === | ||||
| <!-- hello.html --> | |||||
| {% block content %} | {% block content %} | ||||
| Hello World! | Hello World! | ||||
| {% endblock %} | {% endblock %} | ||||
| {% endraw %} | {% endraw %} | ||||
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~ | ||||
| ## Default blocks | ## Default blocks | ||||
| It gets even better. The auto extend plugin also allows you to specify | 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: | The following snippet is equivalent to the above ones: | ||||
| ~~~~~jinja~~~~ | |||||
| ~~~~~jinja:hello.html~~~~ | |||||
| === | === | ||||
| extends: base.html | extends: base.html | ||||
| default_block: content | default_block: content | ||||
| === | === | ||||
| <!-- hello.html --> | |||||
| Hello World! | 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 | In combination with metadata inheritance, this plugin can completely | ||||
| eliminate redundancy on many sites. | 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: | meta: | ||||
| extends: base.html | extends: base.html | ||||
| default_block: content | 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 | Hello World | ||||
| ~~~~~~~~~~~ | ~~~~~~~~~~~ | ||||
| Just Content! | |||||
| Just content! | |||||
| ===/doc=== | ===/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 | respective sections. For example, `MyAwesomePlugin` will get parameters | ||||
| from `myawesome` section in the configuration file. | from `myawesome` section in the configuration file. | ||||
| # In the box | |||||
| ## In the box | |||||
| Hyde is shipped with the following plugins: | 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 | extends: site.yaml | ||||
| mode: production | 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): | def assert_valid_conversion(html): | ||||
| assert html | assert html | ||||
| q = PyQuery(html) | q = PyQuery(html) | ||||
| print html | |||||
| assert "is_processable" not in html | assert "is_processable" not in html | ||||
| assert q("h1") | assert q("h1") | ||||
| assert "This is a" in q("h1").text() | assert "This is a" in q("h1").text() | ||||