From 8cf945bb596b18c95ff4c96484c6b34b7790efb1 Mon Sep 17 00:00:00 2001 From: Bosco Ho Date: Mon, 17 Jun 2013 11:11:05 +1000 Subject: [PATCH 1/4] Added :sass filter --- hamlpy/indentedsass.py | 60 ++++++++++++++++++++++++++++++++++++++++++ hamlpy/nodes.py | 32 ++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 hamlpy/indentedsass.py diff --git a/hamlpy/indentedsass.py b/hamlpy/indentedsass.py new file mode 100644 index 0000000..331ecf3 --- /dev/null +++ b/hamlpy/indentedsass.py @@ -0,0 +1,60 @@ +import StringIO + +# take from rapydcss https://bitbucket.org/pyjeon/rapydcss +# Copyright (C) 2012 Alexander Tsepkov +# GPL Version 3 license +def compile_to_scss(sass): + scss_buffer = StringIO.StringIO() + + state = { + 'indent_marker':0, + 'prev_indent': 0, + 'prev_line': '', + 'nested_blocks':0, + 'line_buffer': '', + } + + # create a separate funtion for parsing the line so that we can call it again after the loop terminates + def parse_line(line, state): + line = state['line_buffer'] + line.rstrip() # remove EOL character + if line and line[-1] == '\\': + state['line_buffer'] = line[:-1] + return + else: + state['line_buffer'] = '' + + indent = len(line) - len(line.lstrip()) + + # make sure we support multi-space indent as long as indent is consistent + if indent and not state['indent_marker']: + state['indent_marker'] = indent + + if state['indent_marker']: + indent /= state['indent_marker'] + + if indent == state['prev_indent']: + # same indentation as previous line + if state['prev_line']: + state['prev_line'] += ';' + elif indent > state['prev_indent']: + # new indentation is greater than previous, we just entered a new block + state['prev_line'] += ' {' + state['nested_blocks'] += 1 + else: + # indentation is reset, we exited a block + block_diff = state['prev_indent'] - indent + if state['prev_line']: + state['prev_line'] += ';' + state['prev_line'] += ' }' * block_diff + state['nested_blocks'] -= block_diff + + scss_buffer.write(state['prev_line'] + '\n') + + state['prev_indent'] = indent + state['prev_line'] = line + + for input_line in sass.splitlines(): + parse_line(input_line, state) + parse_line('\n', state) # parse the last line stored in prev_line buffer + + return scss_buffer.getvalue() diff --git a/hamlpy/nodes.py b/hamlpy/nodes.py index 0287ca2..f39ba96 100644 --- a/hamlpy/nodes.py +++ b/hamlpy/nodes.py @@ -18,6 +18,16 @@ except ImportError, e: _markdown_available = False +try: + from indentedsass import compile_to_scss + from scss import Scss + def sass_compile(text): + scss_text = compile_to_scss(text) + return Scss().compile(scss_text) + _sass_available = True +except ImportError, e: + _sass_available = False + class NotAvailableError(Exception): pass @@ -45,6 +55,8 @@ class NotAvailableError(Exception): MARKDOWN_FILTER = ':markdown' CDATA_FILTER = ':cdata' PYGMENTS_FILTER = ':highlight' +SCSS_FILTER = ':scss' +SASS_FILTER = ':sass' ELEMENT_CHARACTERS = (ELEMENT, ID, CLASS) @@ -111,6 +123,9 @@ def create_node(haml_line): if stripped_line == MARKDOWN_FILTER: return MarkdownFilterNode(haml_line) + if stripped_line == SASS_FILTER: + return SassFilterNode(haml_line) + return PlaintextNode(haml_line) class TreeNode(object): @@ -600,3 +615,20 @@ def _render(self): self.before += markdown(text) else: self.after = self.render_newlines() + +class SassFilterNode(FilterNode): + def _render(self): + if self.children: + if not _sass_available: + raise NotAvailableError("Markdown is not available") + + self.before = '\n' + indent_offset = len(self.children[0].spaces) + text = ''.join(''.join([c.spaces[indent_offset:], c.haml, c.render_newlines()]) for c in self.children) + self.before += sass_compile(text) + else: + self.after = self.render_newlines() From 6026a93c98eaa7818aacbd15e6fe9b5678f3dfb7 Mon Sep 17 00:00:00 2001 From: Bosco Ho Date: Tue, 25 Jun 2013 15:24:47 +1000 Subject: [PATCH 2/4] Converted indentedsass to sassin --- hamlpy/nodes.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hamlpy/nodes.py b/hamlpy/nodes.py index f39ba96..4d4eb9e 100644 --- a/hamlpy/nodes.py +++ b/hamlpy/nodes.py @@ -19,11 +19,7 @@ _markdown_available = False try: - from indentedsass import compile_to_scss - from scss import Scss - def sass_compile(text): - scss_text = compile_to_scss(text) - return Scss().compile(scss_text) + from sassin import compile_with_scss as sass_compile _sass_available = True except ImportError, e: _sass_available = False From 1d322528c2f6bdd0ede50f1001ae8f3be7b52895 Mon Sep 17 00:00:00 2001 From: Bosco Ho Date: Thu, 27 Jun 2013 12:54:31 +1000 Subject: [PATCH 3/4] Added :sass filter tests --- hamlpy/indentedsass.py | 60 ---------------------- hamlpy/nodes.py | 2 +- hamlpy/test/templates/filtersMarkdown.html | 2 +- hamlpy/test/templates/filtersSass.hamlpy | 11 ++++ hamlpy/test/templates/filtersSass.html | 8 +++ 5 files changed, 21 insertions(+), 62 deletions(-) delete mode 100644 hamlpy/indentedsass.py create mode 100644 hamlpy/test/templates/filtersSass.hamlpy create mode 100644 hamlpy/test/templates/filtersSass.html diff --git a/hamlpy/indentedsass.py b/hamlpy/indentedsass.py deleted file mode 100644 index 331ecf3..0000000 --- a/hamlpy/indentedsass.py +++ /dev/null @@ -1,60 +0,0 @@ -import StringIO - -# take from rapydcss https://bitbucket.org/pyjeon/rapydcss -# Copyright (C) 2012 Alexander Tsepkov -# GPL Version 3 license -def compile_to_scss(sass): - scss_buffer = StringIO.StringIO() - - state = { - 'indent_marker':0, - 'prev_indent': 0, - 'prev_line': '', - 'nested_blocks':0, - 'line_buffer': '', - } - - # create a separate funtion for parsing the line so that we can call it again after the loop terminates - def parse_line(line, state): - line = state['line_buffer'] + line.rstrip() # remove EOL character - if line and line[-1] == '\\': - state['line_buffer'] = line[:-1] - return - else: - state['line_buffer'] = '' - - indent = len(line) - len(line.lstrip()) - - # make sure we support multi-space indent as long as indent is consistent - if indent and not state['indent_marker']: - state['indent_marker'] = indent - - if state['indent_marker']: - indent /= state['indent_marker'] - - if indent == state['prev_indent']: - # same indentation as previous line - if state['prev_line']: - state['prev_line'] += ';' - elif indent > state['prev_indent']: - # new indentation is greater than previous, we just entered a new block - state['prev_line'] += ' {' - state['nested_blocks'] += 1 - else: - # indentation is reset, we exited a block - block_diff = state['prev_indent'] - indent - if state['prev_line']: - state['prev_line'] += ';' - state['prev_line'] += ' }' * block_diff - state['nested_blocks'] -= block_diff - - scss_buffer.write(state['prev_line'] + '\n') - - state['prev_indent'] = indent - state['prev_line'] = line - - for input_line in sass.splitlines(): - parse_line(input_line, state) - parse_line('\n', state) # parse the last line stored in prev_line buffer - - return scss_buffer.getvalue() diff --git a/hamlpy/nodes.py b/hamlpy/nodes.py index 4d4eb9e..9a75f00 100644 --- a/hamlpy/nodes.py +++ b/hamlpy/nodes.py @@ -607,7 +607,7 @@ def _render(self): self.before = self.render_newlines()[1:] indent_offset = len(self.children[0].spaces) - text = ''.join(''.join([c.spaces[indent_offset:], c.raw_haml.lstrip(), c.render_newlines()]) for c in self.children) + text = ''.join(''.join([c.spaces[indent_offset:], c.haml, c.render_newlines()]) for c in self.children) self.before += markdown(text) else: self.after = self.render_newlines() diff --git a/hamlpy/test/templates/filtersMarkdown.html b/hamlpy/test/templates/filtersMarkdown.html index 49f148a..3aa2a01 100644 --- a/hamlpy/test/templates/filtersMarkdown.html +++ b/hamlpy/test/templates/filtersMarkdown.html @@ -2,4 +2,4 @@ no paragraph

New paragraph

test
-
+ \ No newline at end of file diff --git a/hamlpy/test/templates/filtersSass.hamlpy b/hamlpy/test/templates/filtersSass.hamlpy new file mode 100644 index 0000000..3a15ce5 --- /dev/null +++ b/hamlpy/test/templates/filtersSass.hamlpy @@ -0,0 +1,11 @@ +:sass + $highlight: #9F2 + /* our special border + @mixin big-border + border: 3px solid $highlightcolor + #main, + #another_main + font: + color: $highlight + @include big-border + diff --git a/hamlpy/test/templates/filtersSass.html b/hamlpy/test/templates/filtersSass.html new file mode 100644 index 0000000..76e92f3 --- /dev/null +++ b/hamlpy/test/templates/filtersSass.html @@ -0,0 +1,8 @@ + \ No newline at end of file From 410b40b294d3b7724f10352bdaf155d54217fac8 Mon Sep 17 00:00:00 2001 From: Bosco Ho Date: Thu, 1 Aug 2013 08:49:59 +1000 Subject: [PATCH 4/4] merged upstream --- hamlpy/nodes.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hamlpy/nodes.py b/hamlpy/nodes.py index 8ff41e2..b286825 100644 --- a/hamlpy/nodes.py +++ b/hamlpy/nodes.py @@ -606,10 +606,6 @@ def _render(self): raise NotAvailableError("Markdown is not available") self.before = self.render_newlines()[1:] indent_offset = len(self.children[0].spaces) -<<<<<<< HEAD - text = ''.join(''.join([c.spaces[indent_offset:], c.haml, c.render_newlines()]) for c in self.children) - self.before += markdown(text) -======= lines = [] for c in self.children: haml = c.raw_haml.lstrip() @@ -617,7 +613,6 @@ def _render(self): haml = haml[:-1] lines.append(c.spaces[indent_offset:] + haml + c.render_newlines()) self.before += markdown( ''.join(lines)) ->>>>>>> upstream/master else: self.after = self.render_newlines()