Changeset 2921
- Timestamp:
- 12/19/07 08:07:33 (1 year ago)
- Files:
-
- tagsplugin/trunk/tractags/expr.py (modified) (5 diffs)
- tagsplugin/trunk/tractags/htdocs/css/tractags.css (modified) (1 diff)
- tagsplugin/trunk/tractags/macros.py (modified) (5 diffs)
- tagsplugin/trunk/tractags/templates/tags.html (modified) (1 diff)
- tagsplugin/trunk/tractags/templates/tagswiki.cs (deleted)
- tagsplugin/trunk/tractags/web_ui.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
tagsplugin/trunk/tractags/expr.py
r2488 r2921 1 1 import compiler 2 2 import operator 3 import parser 3 4 import re 4 5 from trac.core import TracError … … 11 12 class Expression: 12 13 """ Pass a set of tags through a basic expression filter. 13 14 Supported operators are: unary - (not); binary +, - and | (and, and 15 not, or). All values in the expression are treated as tags. Any tag 16 not in the same form as a Python variable must be quoted. 17 14 15 Expressions are valid, basic Python expressions. 16 18 17 eg. Match all objects tagged with ticket and workflow, and not tagged 19 18 with wiki or closed. 20 21 (ticket +workflow)-(wiki|closed)19 20 (ticket and workflow) and not (wiki or closed) 22 21 """ 23 22 __slots__ = ['ast', 'expression'] … … 25 24 26 25 def __init__(self, expression): 27 tokenizer = re.compile(r'''"[^"]*"|'[^']*'|[-|,+()\[\]]|[^-,|+()\[\]\s]+''') 28 expr = [] 29 for token in tokenizer.findall(expression): 30 if token not in '-|+()[],' and token[0] not in '"\'': 31 expr.append('"%s"' % token) 32 else: 33 expr.append(token) 34 self.expression = (u' '.join(expr)).encode('utf-8') 26 self.expression = expression.decode('utf-8') 35 27 self.ast = compiler.parse(self.expression, 'eval') 36 28 … … 38 30 """ Fetch tags used in this expression. """ 39 31 tags = set() 40 import parser41 32 def walk(node): 42 33 if node[0] == 1: … … 74 65 and not self._visit(node.right, context) 75 66 76 def _visit_add(self, node, context): 77 return self._visit(node.left, context) \ 78 and self._visit(node.right, context) 67 def _visit_not(self, node, context): 68 return not self._visit(node.expr, context) 79 69 80 def _visit_bitor(self, node, context): 81 return self._visit(node.nodes[0], context) \ 82 or self._visit(node.nodes[1], context) 70 def _visit_and(self, node, context): 71 result = True 72 for arg in node.nodes: 73 result = result and self._visit(arg, context) 74 if not result: 75 return False 76 return True 77 78 _visit_add = _visit_and 79 80 def _visit_or(self, node, context): 81 result = False 82 for arg in node.nodes: 83 result = result or self._visit(arg, context) 84 if result: 85 return True 86 return False 87 88 _visit_bitor = _visit_or 83 89 84 90 def _visit_name(self, node, context): tagsplugin/trunk/tractags/htdocs/css/tractags.css
r1831 r2921 32 32 font-size: 10px; 33 33 height: 2.2em; 34 margin: 0 0 2em 2em; 35 text-align: right; 34 margin: 0 0 15em 2em; 35 text-align: left; 36 } 37 #expression ul { 38 list-style: none; 36 39 } 37 40 #expression input { font-size: 10px } tagsplugin/trunk/tractags/macros.py
r2569 r2921 31 31 32 32 def _current_page(self, req): 33 return req.hdf.getValue('wiki.page_name', '') 33 # FIXME Butt ugly - should be formatter.context.resource.id or something 34 return req.path_info.rstrip('/').split('/')[-1] 34 35 35 36 # IWikiMacroProvider methods … … 44 45 return pydoc.getdoc(getattr(self, 'render_' + name.lower())) 45 46 46 def render_macro(self, req, name, content):47 def expand_macro(self, formatter, name, content): 47 48 from trac.web.chrome import add_stylesheet 48 49 from parseargs import parseargs 49 add_stylesheet( req, 'tags/css/tractags.css')50 add_stylesheet(formatter.req, 'tags/css/tractags.css') 50 51 # Translate macro args into python args 51 52 args = [] … … 61 62 raise TracError("Invalid arguments '%s' (%s %s)" % (content, e.__class__.__name__, e)) 62 63 63 return getattr(self, 'render_' + name.lower(), content)( req, *args, **kwargs)64 return getattr(self, 'render_' + name.lower(), content)(formatter.req, *args, **kwargs) 64 65 65 66 # Macro implementations … … 171 172 172 173 engine = TagEngine(self.env) 173 page_name = req.hdf.get('wiki.page_name')174 page_name = self._current_page(req) 174 175 if page_name: 175 176 tags = [tag == '.' and page_name or tag for tag in tags] … … 186 187 try: 187 188 expr = Expression(expression) 189 self.env.log.debug(repr(expr)) 188 190 except Exception, e: 189 191 self.env.log.error("Invalid expression '%s'" % expression, exc_info=True) tagsplugin/trunk/tractags/templates/tags.html
r2918 r2921 17 17 value="${tag_expression}"/> 18 18 <input type="submit" value="Filter Tags" name="filter"/> 19 <div py:if="tag_expression_error" id="expression-error"> 20 <strong>Error:</strong> ${tag_expression_error} 21 </div> 19 22 <div> 20 <strong>Note:</strong> See 21 <a href="http://trac-hacks.org/wiki/TagsPlugin">TracTags</a> for 22 information about using tag expressions. 23 </div> 24 <div py:if="tag_expression_error" id="expression-error"> 25 <strong>Error:</strong> ${expression_error} 23 <p><strong>Tag expressions:</strong></p> 24 <ul> 25 <li><strong>and</strong> for AND operation: tag1 and tag2</li> 26 <li><strong>or</strong> for OR operation: tag1 or tag2</li> 27 <li><strong>not</strong> for NOT operation: tag1 and not tag2</li> 28 <li><strong>()</strong> to group sub-expressions:(tag1 or tag2) and not tag3</li> 29 <li><strong>'quoted string'</strong> to quote words with non-ASCII characters</li> 30 </ul> 26 31 </div> 27 32 </form> tagsplugin/trunk/tractags/web_ui.py
r2918 r2921 108 108 implements(IRequestHandler, INavigationContributor, ITemplateProvider) 109 109 110 def _prepare_wiki(self, req): 111 from tractags.api import TagEngine 112 page = req.path_info[6:] or 'WikiStart' 113 engine = TagEngine(self.env) 114 wikitags = engine.tagspace.wiki 115 tags = list(wikitags.get_tags(page)) 116 tags.sort() 117 118 action = req.args.get('action', 'view') 119 if action == 'edit': 120 req.hdf['tags'] = req.args.get('tags', ', '.join(tags)) 121 elif action == 'view': 122 hdf_tags = [] 123 for tag in tags: 124 href, title = engine.get_tag_link(tag) 125 hdf_tags.append({'name': tag, 126 'href': href, 127 'title': title}) 128 req.hdf['tags'] = hdf_tags 110 # This method is never really called by anything.... Remove? 111 # def _prepare_wiki(self, req): 112 # from tractags.api import TagEngine 113 # page = req.path_info[6:] or 'WikiStart' 114 # engine = TagEngine(self.env) 115 # wikitags = engine.tagspace.wiki 116 # tags = list(wikitags.get_tags(page)) 117 # tags.sort() 118 # 119 # action = req.args.get('action', 'view') 120 # if action == 'edit': 121 # req.hdf['tags'] = req.args.get('tags', ', '.join(tags)) 122 # elif action == 'view': 123 # hdf_tags = [] 124 # for tag in tags: 125 # href, title = engine.get_tag_link(tag) 126 # hdf_tags.append({'name': tag, 127 # 'href': href, 128 # 'title': title}) 129 # req.hdf['tags'] = hdf_tags 129 130 130 131 # ITemplateProvider methods
