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