You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.2KB

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from __future__ import print_function
  4. help_text = """
  5. Extracts tags from Vimwiki files. Useful for the Tagbar plugin.
  6. Usage:
  7. Install Tagbar (http://majutsushi.github.io/tagbar/). Then, put this file
  8. anywhere and add the following to your .vimrc:
  9. let g:tagbar_type_vimwiki = {
  10. \ 'ctagstype':'vimwiki'
  11. \ , 'kinds':['h:header']
  12. \ , 'sro':'&&&'
  13. \ , 'kind2scope':{'h':'header'}
  14. \ , 'sort':0
  15. \ , 'ctagsbin':'/path/to/vwtags.py'
  16. \ , 'ctagsargs': 'default'
  17. \ }
  18. The value of ctagsargs must be one of 'default', 'markdown' or 'media',
  19. whatever syntax you use. However, if you use multiple wikis with different
  20. syntaxes, you can, as a workaround, use the value 'all' instead. Then, Tagbar
  21. will show markdown style headers as well as default/mediawiki style headers,
  22. but there might be erroneously shown headers.
  23. """
  24. import sys
  25. import re
  26. if len(sys.argv) < 3:
  27. print(help_text)
  28. exit()
  29. syntax = sys.argv[1]
  30. filename = sys.argv[2]
  31. rx_default_media = r"^\s*(={1,6})([^=].*[^=])\1\s*$"
  32. rx_markdown = r"^\s*(#{1,6})([^#].*)$"
  33. if syntax in ("default", "media"):
  34. rx_header = re.compile(rx_default_media)
  35. elif syntax == "markdown":
  36. rx_header = re.compile(rx_markdown)
  37. else:
  38. rx_header = re.compile(rx_default_media + "|" + rx_markdown)
  39. file_content = []
  40. try:
  41. with open(filename, "r") as vim_buffer:
  42. file_content = vim_buffer.readlines()
  43. except:
  44. exit()
  45. state = [""]*6
  46. for lnum, line in enumerate(file_content):
  47. match_header = rx_header.match(line)
  48. if not match_header:
  49. continue
  50. match_lvl = match_header.group(1) or match_header.group(3)
  51. match_tag = match_header.group(2) or match_header.group(4)
  52. cur_lvl = len(match_lvl)
  53. cur_tag = match_tag.strip()
  54. cur_searchterm = "^" + match_header.group(0).rstrip("\r\n") + "$"
  55. cur_kind = "h"
  56. state[cur_lvl-1] = cur_tag
  57. for i in range(cur_lvl, 6):
  58. state[i] = ""
  59. scope = "&&&".join(
  60. [state[i] for i in range(0, cur_lvl-1) if state[i] != ""])
  61. if scope:
  62. scope = "\theader:" + scope
  63. print('{0}\t{1}\t/{2}/;"\t{3}\tline:{4}{5}'.format(
  64. cur_tag, filename, cur_searchterm, cur_kind, str(lnum+1), scope))