diff --git a/application.py b/application.py index ade6baa..db13aeb 100755 --- a/application.py +++ b/application.py @@ -12,7 +12,7 @@ import mode_mini, mode_search, mode_replace, mode_which import mode_console, mode_consolemini import mode_c, mode_python, mode_perl, mode_nasm, mode_sh import mode_blame, mode_diff -import mode_javascript, mode_sql, mode_xml, mode_tt +import mode_javascript, mode_sql, mode_xml, mode_tt, mode_css import mode_text, mode_mutt import mode_bds, mode_life @@ -95,6 +95,7 @@ class Application(object): 'text': mode_text.Text, 'which': mode_which.Which, 'xml': mode_xml.XML, + 'css': mode_css.CSS, 'life': mode_life.Life, 'mutt': mode_mutt.Mutt, 'javascript': mode_javascript.Javascript, @@ -130,7 +131,8 @@ class Application(object): '.htm': 'xml', '.js': 'javascript', '.sql': 'sql', - '.tt': 'template' + '.tt': 'template', + '.css': 'css', } self.mode_detection = { 'python': 'python', diff --git a/code_examples/PowerAttacker.css b/code_examples/PowerAttacker.css new file mode 100644 index 0000000..163a56b --- /dev/null +++ b/code_examples/PowerAttacker.css @@ -0,0 +1,87 @@ +/* PowerAttacker 0.1 +Copyright 2007 by Erik Osheim + +This file is licensed under the GNU General Public License. +http://www.gnu.org/copyleft/gpl.html */ + +/* shared */ +.captionText { + /*font:12px "Helvetica Neue";*/ + font:12px "Helvetica"; + font-weight:bold; + color:white; +} +.numInput { + width:30px; + text-align:left; +} + +/* front */ +#result { + font:24px "Helvetica"; + font-weight:bold; + color:white; + text-align:center; + width:100px; + height:100px; +} + +.mainTable { + margin-left:14px; + margin-top:20px; +} + +#front { + position:absolute; + top:0; + left:0; + width: 265px; + height:126px; + background-image:url("Default.png"); + background-repeat:no-repeat; +} + +/* backside */ +.backTable { + margin-left:10px; + margin-top:10px; +} + +#back { + display:none; + position:absolute; + top:0; + left:0; + width:265px; + height:126px; + background-image:url("Images/Backside.png"); + background-repeat:no-repeat; +} + +#doneButton { + position:absolute; + top:96px; + left:185px; +} + +/* flipper */ +.flip { + position:absolute; + left:245px; + top:106px; + width:13px; + height:13px; +} + +#flip { + opacity:0; + background:url(file:///System/Library/WidgetResources/ibutton/white_i.png); + background-repeat:no-repeat; +} + +#fliprollie { + display:none; + opacity:0.25; + background:url(file:///System/Library/WidgetResources/ibutton/white_rollie.png); + background-repeat:no-repeat; +} diff --git a/lex2.py b/lex2.py index 5f47c8b..7de1702 100755 --- a/lex2.py +++ b/lex2.py @@ -134,7 +134,12 @@ class RegionRule(Rule): self.start = start self.grammar = grammar self.end = end - self.start_re = re.compile(start) + self.start_re = self._compile_start() + + def _compile_start(self): + return re.compile(self.start) + def _compile_end(self, d): + return re.compile(self.end % d) def resume(self, lexer, toresume): #raise Exception, "%r %r" % (lexer, toresume) #XYZ @@ -183,7 +188,8 @@ class RegionRule(Rule): # reference named groups from the start token. if we have no end, # well, then, we're never getting out of here alive! if self.end: - end_re = re.compile(self.end % d) + #end_re = re.compile(self.end % d) + end_re = self._compile_end(d) # ok, so as long as we aren't done (we haven't found an end token), # keep reading input @@ -257,6 +263,12 @@ class RegionRule(Rule): return True +class NocaseRegionRule(RegionRule): + def _compile_start(self): + return re.compile(self.start, re.IGNORECASE) + def _compile_end(self, d): + return re.compile(self.end % d, re.IGNORECASE) + class DualRegionRule(Rule): def __init__(self, name, start, grammar1, middle, grammar2, end): assert valid_name_re.match(name), 'invalid name %r' % name diff --git a/mode_css.py b/mode_css.py new file mode 100644 index 0000000..1030949 --- /dev/null +++ b/mode_css.py @@ -0,0 +1,93 @@ +import color, mode2 +from lex2 import Grammar, PatternRule, NocasePatternRule, RegionRule, NocaseRegionRule +from point2 import Point + +class StringGrammar(Grammar): + rules = [ + PatternRule(name=r'octal', pattern=r'\\[0-7]{3}'), + PatternRule(name=r'escaped', pattern=r'\\.'), + ] + +class KeywordGrammar(Grammar): + rules = [ + PatternRule(name=r'octal', pattern=r'\\[0-7]{3}'), + PatternRule(name=r'escaped', pattern=r'\\.'), + RegionRule(name='string', start="'", grammar=StringGrammar(), end="'"), + RegionRule(name='string', start='"', grammar=StringGrammar(), end='"'), + ] + +class CSSGrammar(Grammar): + rules = [ + RegionRule(name=r'comment', start='/\*', grammar=Grammar(), end='\*/'), + RegionRule(name=r'htmlcomment', start=''), + NocasePatternRule(name=r'dimension', pattern=r'[+-]?(?:[0-9]+|[0-9]*\.[0-9]+)[-a-z_][-a-z0-9_]*'), + NocasePatternRule(name=r'percentage', pattern=r'[+-]?(?:[0-9]+|[0-9]*\.[0-9]+)%%'), + NocasePatternRule(name=r'length', pattern=r'[+-]?(?:[0-9]+|[0-9]*\.[0-9]+)(?:em|ex|px|in|cm|mm|pt|pc)'), + NocasePatternRule(name=r'hash', pattern=r'#[-a-z0-9_]+'), + NocasePatternRule(name=r'real', pattern=r'[+-]?[0-9]*\.[0-9]+'), + NocasePatternRule(name=r'int', pattern=r'[+-]?[0-9]+'), + NocasePatternRule(name=r'rule', pattern=r'@(?:page|media|import)'), + NocasePatternRule(name=r'color', pattern=r'(?:aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow|#[0-9]{6}|#[0-9]{3})'), + + NocasePatternRule(name=r'keyword', pattern=r'(?:url|rgb|counter)'), + NocaseRegionRule(name=r'keyword', start='(?:(?<=url)|(?<=rgb)|(?<=counter))\(', grammar=KeywordGrammar(), end='\)'), + + NocasePatternRule(name=r'label', pattern=r"\.?[-a-zA-Z0-9_]+(?= *{)"), + + NocasePatternRule(name=r'ident', pattern=r"-?[a-z_][-a-z0-9_]*"), + NocasePatternRule(name=r'name', pattern=r"[-a-z0-9_]+"), + NocasePatternRule(name=r'delimiter', pattern=r'[:;,{}()\[\]]|~=|\|=|='), + RegionRule(name='string', start="'", grammar=StringGrammar(), end="'"), + RegionRule(name='string', start='"', grammar=StringGrammar(), end='"'), + ] + +class CSS(mode2.Fundamental): + grammar = CSSGrammar() + def __init__(self, w): + mode2.Fundamental.__init__(self, w) + self.add_bindings('close-paren', (')',)) + self.add_bindings('close-brace', ('}',)) + self.add_bindings('close-bracket', (']',)) + self.colors = { + 'comment': color.build('red', 'default'), + 'comment.start': color.build('red', 'default'), + 'comment.null': color.build('red', 'default'), + 'comment.end': color.build('red', 'default'), + + 'htmlcomment': color.build('red', 'default'), + 'htmlcomment.start': color.build('red', 'default'), + 'htmlcomment.null': color.build('red', 'default'), + 'htmlcomment.end': color.build('red', 'default'), + + 'dimension': color.build('magenta', 'default'), + 'percentage': color.build('magenta', 'default'), + 'length': color.build('magenta', 'default'), + 'real': color.build('magenta', 'default'), + 'int': color.build('magenta', 'default'), + 'color': color.build('magenta', 'default'), + + 'hash': color.build('cyan', 'default'), + 'label': color.build('cyan', 'default'), + 'rule': color.build('cyan', 'default'), + 'keyword': color.build('cyan', 'default'), + + 'ident': color.build('default', 'default'), + 'name': color.build('default', 'default'), + + 'delimiter': color.build('default', 'default'), + + 'keyword': color.build('cyan', 'default'), + 'keyword.start': color.build('default', 'default'), + 'keyword.null': color.build('cyan', 'default'), + 'keyword.octal': color.build('magenta', 'default'), + 'keyword.escaped': color.build('magenta', 'default'), + 'keyword.end': color.build('default', 'default'), + + 'string.start': color.build('green', 'default'), + 'string.null': color.build('green', 'default'), + 'string.octal': color.build('magenta', 'default'), + 'string.escaped': color.build('magenta', 'default'), + 'string.end': color.build('green', 'default'), + } + def name(self): + return "Javascript"