diff --git a/papers/commands/tags_cmd.py b/papers/commands/tags_cmd.py index c56384d..7d8eab7 100644 --- a/papers/commands/tags_cmd.py +++ b/papers/commands/tags_cmd.py @@ -1,13 +1,59 @@ -from ..repo import Repository +""" +This command is all about tags. +The different use cases are : +1. > papers tag + Returns the list of all tags +2. > papers tag citekey + Return the list of tags of the given citekey +3. > papers tag citekey math + Add 'math' to the list of tags of the given citekey +4. > papers tag citekey :math + Remove 'math' for the list of tags of the given citekey +5. > papers tag citekey math,romance,:war + Add 'math' and 'romance' tags to the given citekey, and remove the 'war' tag +6. > papers tag math + If 'math' is not a citekey, then display all papers with the tag 'math' +""" +from ..repo import Repository, InvalidReference +from . import helpers def parser(subparsers, config): - parser = subparsers.add_parser('tags', help="list existing tags") + parser = subparsers.add_parser('tags', help="add, remove and show tags") + parser.add_argument('referenceOrTag', nargs='?', default = None, + help='reference to the paper (citekey or number), or ' + 'tag.') + parser.add_argument('tags', nargs='?', default = None, + help='If the previous argument was a reference, then ' + 'then a list of tags separated by commas.') + # TODO find a way to display clear help for multiple command semantics, + # indistinguisable for argparse. (fabien, 201306) return parser - -def command(config, ui): - """List existing tags""" +def command(config, ui, referenceOrTag, tags): + """Add, remove and show tags""" rp = Repository.from_directory(config) - for tag in rp.get_tags(): - ui.print_(tag) + + if referenceOrTag is None: + for tag in rp.get_tags(): + ui.print_(tag) + else: + try: + citekey = rp.citekey_from_ref(referenceOrTag) + p = rp.get_paper(citekey) + if tags is None: + ui.print_(' '.join(p.tags)) + else: + tags = tags.split(',') + for tag in tags: + if tag[0] == ':': + p.remove_tag(tag[1:]) + else: + p.add_tag(tag) + rp.save_paper(p) + except InvalidReference: + tag = referenceOrTag + papers_list = [(p, n) for n, p in enumerate(rp.all_papers()) + if tag in p.tags] + ui.print_('\n'.join(helpers.paper_oneliner(p, n) + for p, n in papers_list)) \ No newline at end of file diff --git a/papers/paper.py b/papers/paper.py index 55d5705..037b5a6 100644 --- a/papers/paper.py +++ b/papers/paper.py @@ -69,6 +69,7 @@ def get_safe_metadata(meta): base_meta = Paper.create_meta() if meta is not None: base_meta.update(meta) + base_meta['tags'] = set(base_meta['tags']) return base_meta @@ -266,11 +267,8 @@ class Paper(object): self.tags.add(tag) def remove_tag(self, tag): - """Remove a tag from a paper. Fails silently.""" - try: - self.tags.pop(tag) - except KeyError: - pass + """Remove a tag from a paper if present.""" + self.tags.discard(tag) class PaperInRepo(Paper): # TODO document why this class exists (fabien, 2013/06)