├── .gitignore
├── README.txt
├── autoload
├── voom.vim
└── voom
│ └── voom_vimplugin2657
│ ├── __init__.py
│ ├── voom_mode_asciidoc.py
│ ├── voom_mode_cwiki.py
│ ├── voom_mode_dokuwiki.py
│ ├── voom_mode_fmr.py
│ ├── voom_mode_fmr1.py
│ ├── voom_mode_fmr2.py
│ ├── voom_mode_fmr3.py
│ ├── voom_mode_hashes.py
│ ├── voom_mode_html.py
│ ├── voom_mode_inverseAtx.py
│ ├── voom_mode_latex.py
│ ├── voom_mode_latexDtx.py
│ ├── voom_mode_markdown.py
│ ├── voom_mode_org.py
│ ├── voom_mode_pandoc.py
│ ├── voom_mode_paragraphBlank.py
│ ├── voom_mode_paragraphIndent.py
│ ├── voom_mode_paragraphNoIndent.py
│ ├── voom_mode_python.py
│ ├── voom_mode_rest.py
│ ├── voom_mode_taskpaper.py
│ ├── voom_mode_thevimoutliner.py
│ ├── voom_mode_txt2tags.py
│ ├── voom_mode_viki.py
│ ├── voom_mode_vimoutliner.py
│ ├── voom_mode_vimwiki.py
│ ├── voom_mode_wiki.py
│ └── voom_vim.py
├── doc
└── voom.txt
└── plugin
└── voom.vim
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | *.pyc
3 | *.bat
4 | *.vbs
5 | *.lnk
6 | *.sh
7 |
8 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | This is a mirror of http://www.vim.org/scripts/script.php?script_id=2657
2 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/__init__.py:
--------------------------------------------------------------------------------
1 | # Dummy file to make this directory a Python package.
2 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_asciidoc.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_asciidoc.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for AsciiDoc document and section titles.
10 | See |voom-mode-asciidoc|, ../../../doc/voom.txt#*voom-mode-asciidoc*
11 | """
12 |
13 | ### NOTES
14 | #
15 | # When outline operation changes level, it has to deal with two ambiguities:
16 | # a) Level 1-5 headline can use 2-style (underline) or 1-style (=).
17 | # b) 1-style can have or not have closing ='s.
18 | # To determine current preferences: check first headline at level <6 and check
19 | # first headline with =. This must be done in hook_makeOutline().
20 | # (Save in VO, similar to reST mode.) Cannot be done during outline operation,
21 | # that is in hook_doBodyAfterOop().
22 | # Defaults: use underline, use closing ='s.
23 |
24 | try:
25 | import vim
26 | if vim.eval('exists("g:voom_asciidoc_do_blanks")')=='1' and vim.eval("g:voom_asciidoc_do_blanks")=='0':
27 | DO_BLANKS = False
28 | else:
29 | DO_BLANKS = True
30 | except ImportError:
31 | DO_BLANKS = True
32 |
33 | import sys
34 | if sys.version_info[0] > 2:
35 | xrange = range
36 | def len_u(s, enc):
37 | return len(s)
38 | else:
39 | def len_u(s, enc):
40 | return len(unicode(s, enc, 'replace'))
41 |
42 | import re
43 |
44 |
45 | # regex for 1-style headline, assumes there is no trailing whitespace
46 | HEAD_MATCH = re.compile(r'^(=+)(\s+\S.*?)(\s+\1)?$').match
47 |
48 | #---------------------------------------------------------------------
49 | # Characters used as underlines in two-line headlines.
50 | ADS_LEVELS = {'=' : 1, '-' : 2, '~' : 3, '^' : 4, '+' : 5}
51 | # Characters for Delimited Blocks. Headines are ignored inside such blocks.
52 | BLOCK_CHARS = {'/' : 0, '+' : 0, '-' : 0, '.' : 0, '*' : 0, '_' : 0, '=' : 0}
53 |
54 | #LEVELS_ADS = {1:'=', 2:'-', 3:'~', 4:'^', 5:'+'}
55 | LEVELS_ADS = {}
56 | for k in ADS_LEVELS:
57 | LEVELS_ADS[ADS_LEVELS[k]] = k
58 | # Combine all signficant chars. Need one of these at start of line for a headline or DelimitedBlock to occur.
59 | CHARS = {}
60 | for k in ADS_LEVELS:
61 | CHARS[k] = 0
62 | for k in BLOCK_CHARS:
63 | CHARS[k] = 0
64 | #---------------------------------------------------------------------
65 |
66 | def hook_makeOutline(VO, blines):
67 | """Return (tlines, bnodes, levels) for Body lines blines.
68 | blines is either Vim buffer object (Body) or list of buffer lines.
69 | """
70 | ENC = VO.enc
71 | Z = len(blines)
72 | tlines, bnodes, levels = [], [], []
73 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
74 |
75 | # trailing whitespace is always removed with rstrip()
76 | # if headline is precedeed by [AAA] and/or [[AAA]], bnode is set to their lnum
77 | #
78 | # 1-style, overrides 2-style
79 | # [[AAA]] L3, blines[i-2]
80 | # [yyy] L2, blines[i-1]
81 | # == head == L1, blines[i] -- current line, closing = are optional
82 | #
83 | # 2-style (underline)
84 | # [[AAA]] L4, blines[i-3]
85 | # [yyy] L3, blines[i-2]
86 | # head L2, blines[i-1] -- title line, many restrictions on the format
87 | # ---- L1, blines[i] -- current line
88 |
89 |
90 | # Set this the first time a headline with level 1-5 is encountered.
91 | # 0 or 1 -- False, use 2-style (default); 2 -- True, use 1-style
92 | useOne = 0
93 | # Set this the first time headline in 1-style is encountered.
94 | # 0 or 1 -- True, use closing ='s (default); 2 -- False, do not use closing ='s
95 | useOneClose = 0
96 |
97 | isHead = False
98 | isFenced = False # True if inside DelimitedBlock, the value is the char
99 | headI = -2 # idx of the last line that is part of a headline
100 | blockI = -2 # idx of the last line where a DelimitedBlock ended
101 | m = None # match object for 1-style regex
102 |
103 | for i in xrange(Z):
104 | L1 = blines[i].rstrip()
105 | if not L1 or not L1[0] in CHARS:
106 | continue
107 | ch = L1[0]
108 |
109 | if isFenced:
110 | if isFenced==ch and len(L1)>3 and L1.lstrip(ch)=='':
111 | isFenced = False
112 | blockI = i
113 | continue
114 |
115 | # 1-style headline
116 | if ch == '=' and L1.strip('='):
117 | m = HEAD_MATCH(L1)
118 | if m:
119 | isHead = True
120 | headI_ = headI
121 | headI = i
122 | lev = len(m.group(1))
123 | head = m.group(2).strip()
124 | bnode = i+1
125 |
126 | # current line is an underline
127 | # the previous, underlined line (L2) is not a headline if it:
128 | # is not exactly the length of underline +/- 2
129 | # is already part of in the previous headline
130 | # looks like an underline or a delimited block line
131 | # is [[AAA]] or [AAA] (BlockID or Attribute List)
132 | # starts with . (Block Title, they have no level)
133 | # starts with // (comment line)
134 | # starts with tab (don't know why, spaces are ok)
135 | # is only 1 chars (avoids confusion with --, as in Vim syntax, not as in AsciiDoc)
136 | if not isHead and ch in ADS_LEVELS and L1.lstrip(ch)=='' and i > 0:
137 | L2 = blines[i-1].rstrip()
138 | z2 = len_u(L2, ENC)
139 | z1 = len(L1)
140 | if (L2 and
141 | (-3 < z2 - z1 < 3) and z1 > 1 and z2 > 1 and
142 | headI != i-1 and
143 | not ((L2[0] in CHARS) and L2.lstrip(L2[0])=='') and
144 | not (L2.startswith('[') and L2.endswith(']')) and
145 | not L2.startswith('.') and
146 | not L2.startswith('\t') and
147 | not (L2.startswith('//') and not L2.startswith('///'))
148 | ):
149 | isHead = True
150 | headI_ = headI
151 | headI = i
152 | lev = ADS_LEVELS[ch]
153 | head = L2.strip()
154 | bnode = i # lnum of previous line (L2)
155 |
156 | if isHead and bnode > 1:
157 | # decrement bnode if preceding lines are [[AAA]] or [AAA] lines
158 | # that is set bnode to the topmost [[AAA]] or [AAA] line number
159 | j_ = bnode-2 # idx of line before the title line
160 | L3 = blines[bnode-2].rstrip()
161 | while L3.startswith('[') and L3.endswith(']'):
162 | bnode -= 1
163 | if bnode > 1:
164 | L3 = blines[bnode-2].rstrip()
165 | else:
166 | break
167 |
168 | # headline must be preceded by a blank line unless:
169 | # it's line 1 (j == -1)
170 | # headline is preceded by [AAA] or [[AAA]] lines (j != j_)
171 | # previous line is a headline (headI_ == j)
172 | # previous line is the end of a DelimitedBlock (blockI == j)
173 | j = bnode-2
174 | if DO_BLANKS and j==j_ and j > -1:
175 | L3 = blines[j].rstrip()
176 | if L3 and headI_ != j and blockI != j:
177 | # skip over any adjacent comment lines
178 | while L3.startswith('//') and not L3.startswith('///'):
179 | j -= 1
180 | if j > -1:
181 | L3 = blines[j].rstrip()
182 | else:
183 | L3 = ''
184 | if L3 and headI_ != j and blockI != j:
185 | isHead = False
186 | headI = headI_
187 |
188 | # start of DelimitedBlock
189 | if not isHead and ch in BLOCK_CHARS and len(L1)>3 and L1.lstrip(ch)=='':
190 | isFenced = ch
191 | continue
192 |
193 | if isHead:
194 | isHead = False
195 | # save style info for first headline and first 1-style headline
196 | if not useOne and lev < 6:
197 | if m:
198 | useOne = 2
199 | else:
200 | useOne = 1
201 | if not useOneClose and m:
202 | if m.group(3):
203 | useOneClose = 1
204 | else:
205 | useOneClose = 2
206 | # make outline
207 | tline = ' %s|%s' %('. '*(lev-1), head)
208 | tlines_add(tline)
209 | bnodes_add(bnode)
210 | levels_add(lev)
211 |
212 | # don't clobber these when parsing clipboard during Paste
213 | # which is the only time blines is not Body
214 | if blines is VO.Body:
215 | VO.useOne = useOne == 2
216 | VO.useOneClose = useOneClose < 2
217 |
218 | return (tlines, bnodes, levels)
219 |
220 |
221 | def hook_newHeadline(VO, level, blnum, tlnum):
222 | """Return (tree_head, bodyLines).
223 | tree_head is new headline string in Tree buffer (text after |).
224 | bodyLines is list of lines to insert in Body buffer.
225 | """
226 | tree_head = 'NewHeadline'
227 | if level < 6 and not VO.useOne:
228 | bodyLines = [tree_head, LEVELS_ADS[level]*11, '']
229 | else:
230 | lev = '='*level
231 | if VO.useOneClose:
232 | bodyLines = ['%s %s %s' %(lev, tree_head, lev), '']
233 | else:
234 | bodyLines = ['%s %s' %(lev, tree_head), '']
235 |
236 | # Add blank line when inserting after non-blank Body line.
237 | if VO.Body[blnum-1].strip():
238 | bodyLines[0:0] = ['']
239 |
240 | return (tree_head, bodyLines)
241 |
242 |
243 | #def hook_changeLevBodyHead(VO, h, levDelta):
244 | # DO NOT CREATE THIS HOOK
245 |
246 |
247 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
248 | # this is instead of hook_changeLevBodyHead()
249 |
250 | # Based on Markdown mode function.
251 | # Inserts blank separator lines if missing.
252 |
253 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
254 | Body = VO.Body
255 | Z = len(Body)
256 | bnodes, levels = VO.bnodes, VO.levels
257 | ENC = VO.enc
258 |
259 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
260 | # during up/down, or promoted/demoted.
261 | if blnum1:
262 | assert blnum1 == bnodes[tlnum1-1]
263 | if tlnum2 < len(bnodes):
264 | assert blnum2 == bnodes[tlnum2]-1
265 | else:
266 | assert blnum2 == Z
267 |
268 | # blnumCut is Body lnum after which a region was removed during 'cut',
269 | # 'up', 'down'. Need this to check if there is blank line between nodes
270 | # used to be separated by the cut/moved region.
271 | if blnumCut:
272 | if tlnumCut < len(bnodes):
273 | assert blnumCut == bnodes[tlnumCut]-1
274 | else:
275 | assert blnumCut == Z
276 |
277 | # Total number of added lines minus number of deleted lines.
278 | b_delta = 0
279 |
280 | ### After 'cut' or 'up': insert blank line if there is none
281 | # between the nodes used to be separated by the cut/moved region.
282 | if DO_BLANKS and (oop=='cut' or oop=='up') and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
283 | Body[blnumCut:blnumCut] = ['']
284 | update_bnodes(VO, tlnumCut+1 ,1)
285 | b_delta+=1
286 |
287 | if oop=='cut':
288 | return
289 |
290 | ### Make sure there is blank line after the last node in the region:
291 | # insert blank line after blnum2 if blnum2 is not blank, that is insert
292 | # blank line before bnode at tlnum2+1.
293 | if DO_BLANKS and blnum2 < Z and Body[blnum2-1].strip():
294 | Body[blnum2:blnum2] = ['']
295 | update_bnodes(VO, tlnum2+1 ,1)
296 | b_delta+=1
297 |
298 | ### Change levels and/or formats of headlines in the affected region.
299 | # Always do this after Paste, even if level is unchanged -- format can
300 | # be different when pasting from other outlines.
301 | # Examine each headline, from bottom to top, and change level and/or format.
302 | # To change from 1-style to 2-style:
303 | # strip ='s, strip whitespace;
304 | # insert underline.
305 | # To change from 2-style to 1-style:
306 | # delete underline;
307 | # insert ='s.
308 | # Update bnodes after inserting or deleting a line.
309 | #
310 | # NOTE: bnode can be [[AAA]] or [AAA] line, we check for that and adjust it
311 | # to point to the headline text line
312 | #
313 | # 1-style 2-style
314 | #
315 | # L0 L0 Body[bln-2]
316 | # == head L1 head L1 <--bnode Body[bln-1] (not always the actual bnode)
317 | # L2 ---- L2 Body[bln]
318 | # L3 L3 Body[bln+1]
319 |
320 | if levDelta or oop=='paste':
321 | for i in xrange(tlnum2, tlnum1-1, -1):
322 | # required level (VO.levels has been updated)
323 | lev = levels[i-1]
324 | # current level from which to change to lev
325 | lev_ = lev - levDelta
326 |
327 | # Body headline (bnode) and the next line
328 | bln = bnodes[i-1]
329 | L1 = Body[bln-1].rstrip()
330 | # bnode can point to the tompost [AAA] or [[AAA]] line
331 | # increment bln until the actual headline (title line) is found
332 | while L1.startswith('[') and L1.endswith(']'):
333 | bln += 1
334 | L1 = Body[bln-1].rstrip()
335 | # the underline line
336 | if bln < len(Body):
337 | L2 = Body[bln].rstrip()
338 | else:
339 | L2 = ''
340 |
341 | # get current headline format
342 | hasOne, hasOneClose = False, VO.useOneClose
343 | theHead = L1
344 | if L1.startswith('='):
345 | m = HEAD_MATCH(L1)
346 | if m:
347 | hasOne = True
348 | # headline without ='s but with whitespace around it preserved
349 | theHead = m.group(2)
350 | theclose = m.group(3)
351 | if theclose:
352 | hasOneClose = True
353 | theHead += theclose.rstrip('=')
354 | else:
355 | hasOneClose = False
356 |
357 | # get desired headline format
358 | if oop=='paste':
359 | if lev > 5:
360 | useOne = True
361 | else:
362 | useOne = VO.useOne
363 | useOneClose = VO.useOneClose
364 | elif lev < 6 and lev_ < 6:
365 | useOne = hasOne
366 | useOneClose = hasOneClose
367 | elif lev > 5 and lev_ > 5:
368 | useOne = True
369 | useOneClose = hasOneClose
370 | elif lev < 6 and lev_ > 5:
371 | useOne = VO.useOne
372 | useOneClose = VO.useOneClose
373 | elif lev > 5 and lev_ < 6:
374 | useOne = True
375 | useOneClose = hasOneClose
376 | else:
377 | assert False
378 | #print('useOne=%s hasOne=%s useOneClose=%s hasOneClose=%s' %(useOne, hasOne, useOneClose, hasOneClose))
379 |
380 | ### change headline level and/or format
381 | # 2-style unchanged, only adjust level of underline
382 | if not useOne and not hasOne:
383 | if not levDelta: continue
384 | Body[bln] = LEVELS_ADS[lev]*len(L2)
385 | # 1-style unchanged, adjust level of ='s and add/remove closing ='s
386 | elif useOne and hasOne:
387 | # no format change, there are closing ='s
388 | if useOneClose and hasOneClose:
389 | if not levDelta: continue
390 | Body[bln-1] = '%s%s%s' %('='*lev, theHead, '='*lev)
391 | # no format change, there are no closing ='s
392 | elif not useOneClose and not hasOneClose:
393 | if not levDelta: continue
394 | Body[bln-1] = '%s%s' %('='*lev, theHead)
395 | # add closing ='s
396 | elif useOneClose and not hasOneClose:
397 | Body[bln-1] = '%s%s %s' %('='*lev, theHead.rstrip(), '='*lev)
398 | # remove closing ='s
399 | elif not useOneClose and hasOneClose:
400 | Body[bln-1] = '%s%s' %('='*lev, theHead.rstrip())
401 | # insert underline, remove ='s
402 | elif not useOne and hasOne:
403 | L1 = theHead.strip()
404 | Body[bln-1] = L1
405 | # insert underline
406 | Body[bln:bln] = [LEVELS_ADS[lev] * len_u(L1, ENC)]
407 | update_bnodes(VO, i+1, 1)
408 | b_delta+=1
409 | # remove underline, insert ='s
410 | elif useOne and not hasOne:
411 | if useOneClose:
412 | Body[bln-1] = '%s %s %s' %('='*lev, theHead.strip(), '='*lev)
413 | else:
414 | Body[bln-1] = '%s %s' %('='*lev, theHead.strip())
415 | # delete underline
416 | Body[bln:bln+1] = []
417 | update_bnodes(VO, i+1, -1)
418 | b_delta-=1
419 |
420 | ### Make sure first headline is preceded by a blank line.
421 | blnum1 = bnodes[tlnum1-1]
422 | if DO_BLANKS and blnum1 > 1 and Body[blnum1-2].strip():
423 | Body[blnum1-1:blnum1-1] = ['']
424 | update_bnodes(VO, tlnum1 ,1)
425 | b_delta+=1
426 |
427 | ### After 'down' : insert blank line if there is none
428 | # between the nodes used to be separated by the moved region.
429 | if DO_BLANKS and oop=='down' and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
430 | Body[blnumCut:blnumCut] = ['']
431 | update_bnodes(VO, tlnumCut+1 ,1)
432 | b_delta+=1
433 |
434 | assert len(Body) == Z + b_delta
435 |
436 |
437 | def update_bnodes(VO, tlnum, delta):
438 | """Update VO.bnodes by adding/substracting delta to each bnode
439 | starting with bnode at tlnum and to the end.
440 | """
441 | bnodes = VO.bnodes
442 | for i in xrange(tlnum, len(bnodes)+1):
443 | bnodes[i-1] += delta
444 |
445 |
446 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_cwiki.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_cwiki.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for cwiki Vim plugin. Contributed by Craig B. Allen.
10 | http://www.vim.org/scripts/script.php?script_id=2176
11 | See |voom-mode-various|, ../../../doc/voom.txt#*voom-mode-various*
12 |
13 | +++ headline level 1
14 | some text
15 | ++++ headline level 2
16 | more text
17 | +++++ headline level 3
18 | ++++++ headline level 4
19 | etc.
20 |
21 | First + must be at start of line. Whitespace after the last + is optional.
22 | """
23 |
24 | import sys
25 | if sys.version_info[0] > 2:
26 | xrange = range
27 |
28 | import re
29 | headline_match = re.compile(r'^\+\+(\++)').match
30 |
31 |
32 | def hook_makeOutline(VO, blines):
33 | """Return (tlines, bnodes, levels) for Body lines blines.
34 | blines is either Vim buffer object (Body) or list of buffer lines.
35 | """
36 | Z = len(blines)
37 | tlines, bnodes, levels = [], [], []
38 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
39 | for i in xrange(Z):
40 | if not blines[i].startswith('+'):
41 | continue
42 | bline = blines[i]
43 | m = headline_match(bline)
44 | if not m:
45 | continue
46 | lev = len(m.group(1))
47 | head = bline[2+lev:].strip()
48 | tline = ' %s|%s' %('. '*(lev-1), head)
49 | tlines_add(tline)
50 | bnodes_add(i+1)
51 | levels_add(lev)
52 | return (tlines, bnodes, levels)
53 |
54 |
55 | def hook_newHeadline(VO, level, blnum, tlnum):
56 | """Return (tree_head, bodyLines).
57 | tree_head is new headline string in Tree buffer (text after |).
58 | bodyLines is list of lines to insert in Body buffer.
59 | """
60 | tree_head = 'NewHeadline'
61 | bodyLines = ['++%s %s' %('+'*level, tree_head), '']
62 | return (tree_head, bodyLines)
63 |
64 |
65 | def hook_changeLevBodyHead(VO, h, levDelta):
66 | """Increase of decrease level number of Body headline by levDelta."""
67 | if levDelta==0: return h
68 | m = headline_match(h)
69 | level = len(m.group(1))
70 | return '++%s%s' %('+'*(level+levDelta), h[m.end(1):])
71 |
72 |
73 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_dokuwiki.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_dokuwiki.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for DokuWiki sections.
10 | See |voom-mode-dokuwiki|, ../../../doc/voom.txt#*voom-mode-dokuwiki*
11 | """
12 | # based on voom_mode_inverseAtx.py
13 |
14 | try:
15 | import vim
16 | except ImportError:
17 | pass
18 |
19 | import sys
20 | if sys.version_info[0] > 2:
21 | xrange = range
22 |
23 | import re
24 |
25 | headline_match = re.compile(r'^( ?| \t[ \t]*)(={2,})(.+?)(={2,})[ \t]*$').match
26 | # Marker character that denotes a headline in the regexp above.
27 | CHAR = '='
28 | # The maximum possible level.
29 | # The number of leading marker characters for level 1 headline is MAX+1 or more.
30 | MAX = 5
31 |
32 | def hook_makeOutline(VO, blines):
33 | """Return (tlines, bnodes, levels) for Body lines blines.
34 | blines is either Vim buffer object (Body) or list of buffer lines.
35 | """
36 | Z = len(blines)
37 | tlines, bnodes, levels = [], [], []
38 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
39 | for i in xrange(Z):
40 | if not blines[i].lstrip().startswith(CHAR):
41 | continue
42 | bline = blines[i]
43 | m = headline_match(bline)
44 | if not m:
45 | continue
46 | n = len(m.group(2))
47 | if n > MAX:
48 | lev = 1
49 | else:
50 | lev = MAX - n + 2
51 | head = m.group(3).strip()
52 | tline = ' %s|%s' %('. '*(lev-1), head)
53 | tlines_add(tline)
54 | bnodes_add(i+1)
55 | levels_add(lev)
56 | return (tlines, bnodes, levels)
57 |
58 |
59 | def hook_newHeadline(VO, level, blnum, tlnum):
60 | """Return (tree_head, bodyLines).
61 | tree_head is new headline string in Tree buffer (text after |).
62 | bodyLines is list of lines to insert in Body buffer.
63 | """
64 | tree_head = 'NewHeadline'
65 | if level >= MAX:
66 | C = CHAR
67 | else:
68 | C = CHAR * (MAX - level + 1)
69 | bodyLines = ['=%s %s =%s' %(C, tree_head, C), '']
70 | return (tree_head, bodyLines)
71 |
72 |
73 | #def hook_changeLevBodyHead(VO, h, levDelta):
74 |
75 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
76 | # this is instead of hook_changeLevBodyHead()
77 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
78 | Body = VO.Body
79 | Z = len(Body)
80 | bnodes, levels = VO.bnodes, VO.levels
81 |
82 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
83 | # during up/down, or promoted/demoted.
84 | if blnum1:
85 | assert blnum1 == bnodes[tlnum1-1]
86 | if tlnum2 < len(bnodes):
87 | assert blnum2 == bnodes[tlnum2]-1
88 | else:
89 | assert blnum2 == Z
90 |
91 | # blnumCut is Body lnum after which a region was removed during 'cut'
92 | if blnumCut:
93 | if tlnumCut < len(bnodes):
94 | assert blnumCut == bnodes[tlnumCut]-1
95 | else:
96 | assert blnumCut == Z
97 |
98 | ### Change levels and/or sections of headlines in the affected region.
99 | if not levDelta:
100 | return
101 |
102 | # Examine each headline in the affected region from top to bottom.
103 | # Change levels.
104 | # Correct levels that exceed the MAX: set them to MAX.
105 | invalid_levs = [] # tree lnums of nodes with level > MAX
106 | for i in xrange(tlnum1, tlnum2+1):
107 | # required level based on new VO.levels, can be disallowed
108 | lev_ = levels[i-1]
109 | # Body line
110 | bln = bnodes[i-1]
111 | L = Body[bln-1] # original Body headline line
112 |
113 | if lev_ <= MAX:
114 | n = MAX - lev_ + 1
115 | # MAX level exceeded
116 | else:
117 | n = 1
118 | invalid_levs.append(i)
119 | levels[i-1] = MAX # correct VO.levels
120 | # don't change Body line if level is already at MAX
121 | if lev_ - levDelta == MAX:
122 | continue
123 | m = headline_match(L)
124 | # set Body line
125 | # don't bother changing closing CHARs if there are too many of them
126 | if len(m.group(4)) <= MAX+1:
127 | Body[bln-1] = '%s=%s%s=%s' %(m.group(1), CHAR * n, m.group(3), CHAR * n)
128 | else:
129 | Body[bln-1] = '%s=%s%s' %(m.group(1), CHAR * n, L[m.end(2):])
130 |
131 | ### --- the end ---
132 | if invalid_levs:
133 | vim.command("call voom#ErrorMsg('VOoM (dokuwiki): Disallowed levels have been corrected after ''%s''')" %oop)
134 | invalid_levs = ', '.join(['%s' %i for i in invalid_levs])
135 | vim.command("call voom#ErrorMsg(' level set to maximum (%s) for nodes: %s')" %(MAX, invalid_levs))
136 |
137 |
138 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_fmr.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_fmr.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for start fold markers with levels.
10 | See |voom-mode-fmr|, ../../../doc/voom.txt#*voom-mode-fmr*
11 | This is the default or "fmr" mode. This module changes absolutely nothing.
12 | """
13 |
14 | # Define this mode as an 'fmr' mode.
15 | MTYPE = 0
16 |
17 |
18 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_fmr1.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_fmr1.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for start fold markers with levels.
10 | See |voom-mode-fmr1|, ../../../doc/voom.txt#*voom-mode-fmr1*
11 |
12 | Headline text is before the start fold marker with level.
13 | Very similar to "fmr" mode.
14 |
15 | headline level 1 {{{1
16 | some text
17 | headline level 2 {{{2
18 | more text
19 | """
20 |
21 | import sys
22 | if sys.version_info[0] > 2:
23 | xrange = range
24 |
25 | # Define this mode as an 'fmr' mode.
26 | MTYPE = 0
27 |
28 |
29 | # voom_vim.makeoutline() without char stripping
30 | def hook_makeOutline(VO, blines):
31 | """Return (tlines, bnodes, levels) for Body lines blines.
32 | blines is either Vim buffer object (Body) or list of buffer lines.
33 | """
34 | marker = VO.marker
35 | marker_re_search = VO.marker_re.search
36 | Z = len(blines)
37 | tlines, bnodes, levels = [], [], []
38 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
39 | #c = VO.rstrip_chars
40 | for i in xrange(Z):
41 | if not marker in blines[i]: continue
42 | bline = blines[i]
43 | m = marker_re_search(bline)
44 | if not m: continue
45 | lev = int(m.group(1))
46 | #head = bline[:m.start()].lstrip().rstrip(c).strip('-=~').strip()
47 | head = bline[:m.start()].strip()
48 | tline = ' %s%s|%s' %(m.group(2) or ' ', '. '*(lev-1), head)
49 | tlines_add(tline)
50 | bnodes_add(i+1)
51 | levels_add(lev)
52 | return (tlines, bnodes, levels)
53 |
54 |
55 | # same as voom_vim.newHeadline() but without ---
56 | def hook_newHeadline(VO, level, blnum, ln):
57 | """Return (tree_head, bodyLines).
58 | tree_head is new headline string in Tree buffer (text after |).
59 | bodyLines is list of lines to insert in Body buffer.
60 | """
61 | tree_head = 'NewHeadline'
62 | #bodyLines = ['---%s--- %s%s' %(tree_head, VO.marker, level), '']
63 | bodyLines = ['%s %s%s' %(tree_head, VO.marker, level), '']
64 | return (tree_head, bodyLines)
65 |
66 |
67 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_fmr2.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_fmr2.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for start fold markers with levels.
10 | See |voom-mode-fmr2|, ../../../doc/voom.txt#*voom-mode-fmr2*
11 |
12 | Headline text is after the start fold marker with level.
13 |
14 | {{{1 headline level 1
15 | some text
16 | {{{2 headline level 2
17 | more text
18 | """
19 |
20 | import sys
21 | if sys.version_info[0] > 2:
22 | xrange = range
23 |
24 | # Define this mode as an 'fmr' mode.
25 | MTYPE = 0
26 |
27 |
28 | def hook_makeOutline(VO, blines):
29 | """Return (tlines, bnodes, levels) for Body lines blines.
30 | blines is either Vim buffer object (Body) or list of buffer lines.
31 | """
32 | marker = VO.marker
33 | marker_re_search = VO.marker_re.search
34 | Z = len(blines)
35 | tlines, bnodes, levels = [], [], []
36 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
37 | #c = VO.rstrip_chars
38 | for i in xrange(Z):
39 | if not marker in blines[i]: continue
40 | bline = blines[i]
41 | m = marker_re_search(bline)
42 | if not m: continue
43 | lev = int(m.group(1))
44 |
45 | head = bline[m.end():] # part after the fold marker
46 | # strip optional special marks from left side: "o", "=", "o="
47 | #if head and head[0]=='o': head = head[1:]
48 | #if head and head[0]=='=': head = head[1:]
49 | # lstrip all xo= to avoid conflicts with commands that add or remove them
50 | head = head.lstrip('xo=')
51 |
52 | tline = ' %s%s|%s' %(m.group(2) or ' ', '. '*(lev-1), head.strip())
53 | tlines_add(tline)
54 | bnodes_add(i+1)
55 | levels_add(lev)
56 | return (tlines, bnodes, levels)
57 |
58 |
59 | def hook_newHeadline(VO, level, blnum, ln):
60 | """Return (tree_head, bodyLines).
61 | tree_head is new headline string in Tree buffer (text after |).
62 | bodyLines is list of lines to insert in Body buffer.
63 | """
64 | tree_head = 'NewHeadline'
65 | bodyLines = ['%s%s %s' %(VO.marker, level, tree_head), '']
66 | return (tree_head, bodyLines)
67 |
68 |
69 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_fmr3.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_fmr3.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for start fold markers with levels.
10 | See |voom-mode-fmr3|, ../../../doc/voom.txt#*voom-mode-fmr3*
11 |
12 | Headline text can be before or after the start fold marker with level.
13 |
14 | {{{1 headline level 1
15 | headline level 2 {{{2
16 | """
17 |
18 | import sys
19 | if sys.version_info[0] > 2:
20 | xrange = range
21 |
22 | # Define this mode as an 'fmr' mode.
23 | MTYPE = 0
24 |
25 |
26 | def hook_makeOutline(VO, blines):
27 | """Return (tlines, bnodes, levels) for Body lines blines.
28 | blines is either Vim buffer object (Body) or list of buffer lines.
29 | """
30 | marker = VO.marker
31 | marker_re_search = VO.marker_re.search
32 | Z = len(blines)
33 | tlines, bnodes, levels = [], [], []
34 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
35 | #c = VO.rstrip_chars
36 | for i in xrange(Z):
37 | if not marker in blines[i]: continue
38 | bline = blines[i]
39 | m = marker_re_search(bline)
40 | if not m: continue
41 | lev = int(m.group(1))
42 |
43 | head = bline[m.end():] # part after the fold marker
44 | # strip optional special marks from left side: "o", "=", "o="
45 | #if head and head[0]=='o': head = head[1:]
46 | #if head and head[0]=='=': head = head[1:]
47 | # lstrip all xo= to avoid conflicts with commands that add or remove them
48 | head = head.lstrip('xo=')
49 |
50 | # add part before the fold marker
51 | if head:
52 | head = '%s %s' % (bline[:m.start()].rstrip(), head.lstrip())
53 | else:
54 | head = bline[:m.start()]
55 |
56 | tline = ' %s%s|%s' %(m.group(2) or ' ', '. '*(lev-1), head.strip())
57 | tlines_add(tline)
58 | bnodes_add(i+1)
59 | levels_add(lev)
60 | return (tlines, bnodes, levels)
61 |
62 |
63 | def hook_newHeadline(VO, level, blnum, ln):
64 | """Return (tree_head, bodyLines).
65 | tree_head is new headline string in Tree buffer (text after |).
66 | bodyLines is list of lines to insert in Body buffer.
67 | """
68 | tree_head = 'NewHeadline'
69 | bodyLines = ['%s %s%s' %(tree_head, VO.marker, level), '']
70 | return (tree_head, bodyLines)
71 |
72 |
73 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_hashes.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_hashes.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for headlines marked with #'s (atx-headers, a subset of Markdown format).
10 | See |voom-mode-hashes|, ../../../doc/voom.txt#*voom-mode-hashes*
11 |
12 | # heading level 1
13 | ##heading level 2
14 | ### heading level 3
15 | """
16 |
17 | import sys
18 | if sys.version_info[0] > 2:
19 | xrange = range
20 |
21 | import re
22 |
23 | # Marker character can be changed to any ASCII character.
24 | CHAR = '#'
25 |
26 | # Use this if whitespace after marker chars is optional.
27 | headline_match = re.compile(r'^(%s+)' %re.escape(CHAR)).match
28 |
29 | # Use this if a whitespace is required after marker chars (as in org-mode).
30 | #headline_match = re.compile(r'^(%s+)\s' %re.escape(CHAR)).match
31 |
32 | def hook_makeOutline(VO, blines):
33 | """Return (tlines, bnodes, levels) for Body lines blines.
34 | blines is either Vim buffer object (Body) or list of buffer lines.
35 | """
36 | Z = len(blines)
37 | tlines, bnodes, levels = [], [], []
38 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
39 | for i in xrange(Z):
40 | if not blines[i].startswith(CHAR):
41 | continue
42 | bline = blines[i]
43 | m = headline_match(bline)
44 | # Uncomment the next line if whitespace is required after marker chars.
45 | #if not m: continue
46 | lev = len(m.group(1))
47 | head = bline[lev:].strip()
48 | # Do this instead if optional closing markers need to be stripped.
49 | #head = bline[lev:].strip().rstrip(CHAR).rstrip()
50 | tline = ' %s|%s' %('. '*(lev-1), head)
51 | tlines_add(tline)
52 | bnodes_add(i+1)
53 | levels_add(lev)
54 | return (tlines, bnodes, levels)
55 |
56 |
57 | def hook_newHeadline(VO, level, blnum, tlnum):
58 | """Return (tree_head, bodyLines).
59 | tree_head is new headline string in Tree buffer (text after |).
60 | bodyLines is list of lines to insert in Body buffer.
61 | """
62 | tree_head = 'NewHeadline'
63 | bodyLines = ['%s %s' %(CHAR * level, tree_head), '']
64 | return (tree_head, bodyLines)
65 |
66 |
67 | def hook_changeLevBodyHead(VO, h, levDelta):
68 | """Increase of decrease level number of Body headline by levDelta."""
69 | if levDelta==0: return h
70 | m = headline_match(h)
71 | level = len(m.group(1))
72 | return '%s%s' %(CHAR * (level+levDelta), h[m.end(1):])
73 |
74 |
75 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_html.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_html.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for HTML headings.
10 | See |voom-mode-html|, ../../../doc/voom.txt#*voom-mode-html*
11 |
12 |
headline level 1
13 | some text
14 | headline level 2
15 | more text
16 | headline level 3
17 | < h4 > headline level 4
18 | some text headline 5
19 | etc.
20 | """
21 |
22 | import sys
23 | if sys.version_info[0] > 2:
24 | xrange = range
25 |
26 | import re
27 | headline_search = re.compile(r'<\s*h(\d+).*?>(.*?)', re.IGNORECASE).search
28 | html_tag_sub = re.compile('<.*?>').sub
29 |
30 |
31 | def hook_makeOutline(VO, blines):
32 | """Return (tlines, bnodes, levels) for Body lines blines.
33 | blines is either Vim buffer object (Body) or list of buffer lines.
34 | """
35 | Z = len(blines)
36 | tlines, bnodes, levels = [], [], []
37 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
38 | for i in xrange(Z):
39 | bline = blines[i]
40 | if not ('%s' %(level, tree_head, level), '']
63 | return (tree_head, bodyLines)
64 |
65 |
66 | def hook_changeLevBodyHead(VO, h, levDelta):
67 | """Increase of decrease level number of Body headline by levDelta."""
68 | if levDelta==0: return h
69 | m = headline_search(h)
70 | level = int(m.group(1))
71 | lev = level+levDelta
72 | return '%s%s%s%s%s' %(h[:m.start(1)], lev, h[m.end(1):m.start(3)], lev, h[m.end(3):])
73 |
74 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_inverseAtx.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_inverseAtx.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for inverse Atx-style headers.
10 | See |voom-mode-various|, ../../../doc/voom.txt#*voom-mode-various*
11 |
12 | Headlines start with '@'. There is a maximum of 3 levels:
13 |
14 | @@@ Headline level 1
15 | @@ Headline level 2
16 | @ Headline level 3
17 |
18 | To change the character that denotes headlines and the maximum level, change
19 | module-level constants CHAR and MAX below.
20 | You can also change them by adding options to .vimrc:
21 | let g:voom_inverseAtx_char = '^'
22 | let g:voom_inverseAtx_max = 5
23 |
24 | """
25 |
26 | # Marker character that denotes a headline. It can be any ASCII character.
27 | CHAR = '@'
28 | # The number of marker characters for level 1 headline. This is also the maximum possible level.
29 | MAX = 3
30 |
31 | try:
32 | import vim
33 | if vim.eval('exists("g:voom_inverseAtx_char")')=='1':
34 | CHAR = vim.eval("g:voom_inverseAtx_char")
35 | if vim.eval('exists("g:voom_inverseAtx_max")')=='1':
36 | MAX = int(vim.eval("g:voom_inverseAtx_max"))
37 | except ImportError:
38 | pass
39 |
40 | import sys
41 | if sys.version_info[0] > 2:
42 | xrange = range
43 |
44 | import re
45 |
46 | # Use this if whitespace after marker chars is optional.
47 | headline_match = re.compile(r'^(%s+)' %re.escape(CHAR)).match
48 |
49 | # Use this if a whitespace is required after marker chars.
50 | #headline_match = re.compile(r'^(%s+)\s' %re.escape(CHAR)).match
51 |
52 |
53 | # based on voom_mode_hashes.py
54 | def hook_makeOutline(VO, blines):
55 | """Return (tlines, bnodes, levels) for Body lines blines.
56 | blines is either Vim buffer object (Body) or list of buffer lines.
57 | """
58 | Z = len(blines)
59 | tlines, bnodes, levels = [], [], []
60 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
61 | for i in xrange(Z):
62 | if not blines[i].startswith(CHAR):
63 | continue
64 | bline = blines[i]
65 | m = headline_match(bline)
66 | # Uncomment the next line if whitespace is required after marker chars.
67 | #if not m: continue
68 | n = len(m.group(1))
69 | if n >= MAX:
70 | lev = 1
71 | else:
72 | lev = MAX - n + 1
73 | head = bline.lstrip(CHAR).strip()
74 | # Do this instead if optional closing markers need to be stripped.
75 | #head = bline.rstrip().strip(CHAR).strip()
76 | tline = ' %s|%s' %('. '*(lev-1), head)
77 | tlines_add(tline)
78 | bnodes_add(i+1)
79 | levels_add(lev)
80 | return (tlines, bnodes, levels)
81 |
82 |
83 | def hook_newHeadline(VO, level, blnum, tlnum):
84 | """Return (tree_head, bodyLines).
85 | tree_head is new headline string in Tree buffer (text after |).
86 | bodyLines is list of lines to insert in Body buffer.
87 | """
88 | tree_head = 'NewHeadline'
89 | if level >= MAX:
90 | n = 1
91 | else:
92 | n = MAX - level + 1
93 | bodyLines = ['%s %s' %(CHAR * n, tree_head), '']
94 | return (tree_head, bodyLines)
95 |
96 |
97 | ## This is not good enough: Body is always modified when move right fails
98 | ## because MAX level was exceeded, even if no changes to headlines were made.
99 | #def hook_changeLevBodyHead(VO, h, levDelta):
100 | # """Increase of decrease level number of Body headline by levDelta."""
101 | # if levDelta==0: return h
102 | # m = headline_match(h)
103 | # n = len(m.group(1))
104 | # if n >= MAX:
105 | # lev = 1
106 | # else:
107 | # lev = MAX - n + 1
108 | # level = lev + levDelta
109 | # if level >= MAX:
110 | # n = 1
111 | # else:
112 | # n = MAX - level + 1
113 | # return '%s%s' %(CHAR * n, h[m.end(1):])
114 |
115 |
116 | # based on voom_mode_latex.py
117 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
118 | # this is instead of hook_changeLevBodyHead()
119 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
120 | Body = VO.Body
121 | Z = len(Body)
122 | bnodes, levels = VO.bnodes, VO.levels
123 |
124 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
125 | # during up/down, or promoted/demoted.
126 | if blnum1:
127 | assert blnum1 == bnodes[tlnum1-1]
128 | if tlnum2 < len(bnodes):
129 | assert blnum2 == bnodes[tlnum2]-1
130 | else:
131 | assert blnum2 == Z
132 |
133 | # blnumCut is Body lnum after which a region was removed during 'cut'
134 | if blnumCut:
135 | if tlnumCut < len(bnodes):
136 | assert blnumCut == bnodes[tlnumCut]-1
137 | else:
138 | assert blnumCut == Z
139 |
140 | ### Change levels and/or sections of headlines in the affected region.
141 | if not levDelta:
142 | return
143 |
144 | # Examine each headline in the affected region from top to bottom.
145 | # Change levels.
146 | # Correct levels that exceed the MAX: set them to MAX.
147 | invalid_levs = [] # tree lnums of nodes with level > MAX
148 | for i in xrange(tlnum1, tlnum2+1):
149 | # required level based on new VO.levels, can be disallowed
150 | lev_ = levels[i-1]
151 | # Body line
152 | bln = bnodes[i-1]
153 | L = Body[bln-1] # original Body headline line
154 |
155 | if lev_ <= MAX:
156 | n = MAX - lev_ + 1
157 | # MAX level exceeded
158 | else:
159 | n = 1
160 | invalid_levs.append(i)
161 | levels[i-1] = MAX # correct VO.levels
162 | # don't change Body line if level is already at MAX
163 | if lev_ - levDelta == MAX:
164 | continue
165 | m = headline_match(L)
166 | Body[bln-1] ='%s%s' %(CHAR * n, L[m.end(1):])
167 |
168 | ### --- the end ---
169 | if invalid_levs:
170 | vim.command("call voom#ErrorMsg('VOoM (inverseAtx): Disallowed levels have been corrected after ''%s''')" %oop)
171 | invalid_levs = ', '.join(['%s' %i for i in invalid_levs])
172 | vim.command("call voom#ErrorMsg(' level set to maximum (%s) for nodes: %s')" %(MAX, invalid_levs))
173 |
174 |
175 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_latex.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_latex.py
2 | # Last Modified: 2017-01-15
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for LaTeX.
10 | See |voom-mode-latex|, ../../../doc/voom.txt#*voom-mode-latex*
11 | """
12 |
13 | # SECTIONS, ELEMENTS, VERBATIMS can be defined here or in Vim variables:
14 | # g:voom_latex_sections
15 | # g:voom_latex_elements
16 | # g:voom_latex_verbatims
17 | #
18 | # SECTIONS defines sectioning commands, in order of increasing level:
19 | # \part{A Heading}
20 | # \chapter{A Heading}
21 | # \section{A Heading}
22 | # \subsection{A Heading}
23 | # \subsubsection{A Heading}
24 | # \paragraph{A Heading}
25 | # \subparagraph{A Heading}
26 | #
27 | # ELEMENTS defines fixed elements -- always at level 1:
28 | # \begin{document}
29 | # \begin{abstract}
30 | # \begin{thebibliography}
31 | # \end{document}
32 | # \bibliography{...
33 | #
34 | # VERBATIMS defines regions where headlines are ignored:
35 | # \begin{verbatim} ... \end{verbatim}
36 | # \begin{comment} ... \end{comment}
37 | #
38 | # The actual levels are determined by sections that are present in the buffer.
39 | # Levels are always incremented by 1. That is, if there are only
40 | # \section and \paragraph then \section is level 1 and \paragraph is level 2.
41 |
42 | # sectioning commands, in order of increasing level
43 | SECTIONS = ['part', 'chapter',
44 | 'section', 'subsection', 'subsubsection',
45 | 'paragraph', 'subparagraph']
46 |
47 | # fixed elements -- always at level 1
48 | ELEMENTS = r'^\s*\\(begin\s*\{(document|abstract|thebibliography)\}|end\s*\{document\}|bibliography\s*\{)'
49 |
50 | # verbatim regions, headlines are ignored inside \begin{verbatim} ... \end{verbatim}
51 | VERBATIMS = ['verbatim', 'comment']
52 | #---------------------------------------------------------------------
53 |
54 | try:
55 | import vim
56 | if vim.eval('exists("g:voom_latex_sections")')=='1':
57 | SECTIONS = vim.eval("g:voom_latex_sections")
58 | if vim.eval('exists("g:voom_latex_elements")')=='1':
59 | ELEMENTS = vim.eval("g:voom_latex_elements")
60 | if vim.eval('exists("g:voom_latex_verbatims")')=='1':
61 | VERBATIMS = vim.eval("g:voom_latex_verbatims")
62 | except ImportError:
63 | pass
64 |
65 | import sys
66 | if sys.version_info[0] > 2:
67 | xrange = range
68 |
69 | import re
70 |
71 | # \section{head} or \section*{head} or \section[optionaltitle]{head}
72 | # NOTE: match leading whitespace to preserve it during outline operations
73 | # m.group() 1 2 3
74 | SECTS_RE = re.compile(r'^\s*\\(%s)\s*(\*|\[[^]{]*\])?\s*\{(.*)' %('|'.join(SECTIONS))).match
75 |
76 | if ELEMENTS:
77 | ELEMS_RE = re.compile(ELEMENTS).match
78 | else:
79 | ELEMS_RE = 0
80 |
81 | if VERBATIMS:
82 | # NOTE: leading whitespace must be lstripped before matching
83 | VERBS_RE = re.compile(r'^\\begin\s*\{(%s)\}' %('|'.join(VERBATIMS))).match
84 | else:
85 | VERBS_RE = 0
86 |
87 | SECTIONS = ['\\'+s for s in SECTIONS]
88 | SECTS_LEVS = {} # {section: its default level, ...}
89 | LEVS_SECTS = {} # {level: its default section, ...}
90 | i = 1
91 | for s in SECTIONS:
92 | SECTS_LEVS[s] = i
93 | LEVS_SECTS[i] = s
94 | i+=1
95 |
96 |
97 | def hook_makeOutline(VO, blines):
98 | """Return (tlines, bnodes, levels) for Body lines blines.
99 | blines is either Vim buffer object (Body) or list of buffer lines.
100 | """
101 | Z = len(blines)
102 | tlines, bnodes, levels = [], [], []
103 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
104 | marks, heads = [], []
105 | marks_add, heads_add = marks.append, heads.append
106 |
107 | sects_levs = {} # {section: its default level} for all section found in the buffer
108 | inVerbatim = False
109 | isHead = False
110 | mark = ' ' # * or -
111 | for i in xrange(Z):
112 | L = blines[i].lstrip()
113 | if not L.startswith('\\'): continue
114 | # regions to ignore: \begin{verbatim} ... \end{verbatim}
115 | if VERBS_RE:
116 | if inVerbatim:
117 | if re.match(inVerbatim, L):
118 | inVerbatim = False
119 | continue
120 | else:
121 | m = VERBS_RE(L)
122 | if m:
123 | inVerbatim = r'\\end\s*\{%s\}' %m.group(1)
124 | continue
125 | # check for sections
126 | m = SECTS_RE(L)
127 | if m:
128 | isHead = True
129 | s = '\\' + m.group(1)
130 | lev = SECTS_LEVS[s]
131 | sects_levs[s] = lev
132 | if m.group(2) and m.group(2)=='*':
133 | mark = '*'
134 | head = m.group(3)
135 | # truncate head before the matching '}'
136 | j = 0; k = 1
137 | for ch in head:
138 | if ch=='{': k+=1
139 | elif ch=='}': k-=1
140 | if not k: break
141 | j+=1
142 | head = head[:j].strip()
143 | # check for fixed level 1 elements
144 | elif ELEMS_RE:
145 | m = ELEMS_RE(L)
146 | if m:
147 | isHead = True
148 | lev = 1
149 | head = L.rstrip()
150 | mark = '-'
151 | # add node to outline
152 | if isHead:
153 | isHead = False
154 | bnodes_add(i+1)
155 | levels_add(lev)
156 | # tlines must be constructed from marks and heads and after levels are adjusted
157 | marks_add(mark)
158 | mark = ' '
159 | heads_add(head)
160 |
161 | # adjust default level numbers to reflect only sections present in the buffer
162 | # that is make all level numbers continuous, top level is 1
163 | d = {} # {default level: actual level, ...}
164 | levs_sects = {} # {actual level: section, ...}
165 | sects = [(sects_levs[s], s) for s in sects_levs.keys()]
166 | sects.sort()
167 | sects = [i[1] for i in sects]
168 | i = 1
169 | for s in sects:
170 | d[sects_levs[s]] = i
171 | levs_sects[i] = s
172 | i+=1
173 | levels = [d.get(i,i) for i in levels]
174 |
175 | # construct tlines
176 | for i in xrange(len(levels)):
177 | tlines_add(' %s%s|%s' %(marks[i], '. '*(levels[i]-1), heads[i]))
178 |
179 | # save levs_sects for outline operations
180 | # don't clobber VO.levs_sects when parsing clipboard during Paste
181 | # which is the only time blines is not Body
182 | if blines is VO.Body:
183 | VO._levs_sects = levs_sects
184 |
185 | return (tlines, bnodes, levels)
186 |
187 |
188 | def hook_newHeadline(VO, level, blnum, tlnum):
189 | """Return (tree_head, bodyLines).
190 | tree_head is new headline string in Tree buffer (text after |).
191 | bodyLines is list of lines to insert in Body buffer.
192 | """
193 | tree_head = 'NewHeadline'
194 | (sect, lev) = get_sect_for_lev(VO._levs_sects, level)
195 | assert lev <= level
196 | if not lev==level:
197 | vim.command("call voom#ErrorMsg('VOoM (latex): MAXIMUM LEVEL EXCEEDED')")
198 |
199 | bodyLines = ['%s{%s}' %(sect, tree_head), '']
200 | return (tree_head, bodyLines)
201 |
202 |
203 | #def hook_changeLevBodyHead(VO, h, levDelta):
204 | # DO NOT CREATE THIS HOOK
205 |
206 |
207 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
208 | # this is instead of hook_changeLevBodyHead()
209 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
210 | Body = VO.Body
211 | Z = len(Body)
212 | bnodes, levels = VO.bnodes, VO.levels
213 |
214 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
215 | # during up/down, or promoted/demoted.
216 | if blnum1:
217 | assert blnum1 == bnodes[tlnum1-1]
218 | if tlnum2 < len(bnodes):
219 | assert blnum2 == bnodes[tlnum2]-1
220 | else:
221 | assert blnum2 == Z
222 |
223 | # blnumCut is Body lnum after which a region was removed during 'cut'
224 | if blnumCut:
225 | if tlnumCut < len(bnodes):
226 | assert blnumCut == bnodes[tlnumCut]-1
227 | else:
228 | assert blnumCut == Z
229 |
230 | ### Change levels and/or sections of headlines in the affected region.
231 | # Sections must always be adjusted after Paste, even if level is unchanged,
232 | # in case pasting was done from another outline with different style.
233 | if not (levDelta or oop=='paste'):
234 | return
235 |
236 | # Examine each headline in the affected region from top to bottom.
237 | # For sections: change them to the current level and style.
238 | # Correct invalid levels: VOoM**voom_notes.txt#ID_20120520092604
239 | # use max level if max possible level is exeeded
240 | # use 1 for fixed elements at level >1
241 | invalid_sects, invalid_elems = [], [] # tree lnums of nodes with disallowed levels
242 | levs_sects = VO._levs_sects
243 | #for i in xrange(tlnum2, tlnum1-1, -1):
244 | for i in xrange(tlnum1, tlnum2+1):
245 | # required level based on new VO.levels, can be disallowed
246 | lev_ = levels[i-1]
247 | # Body line
248 | bln = bnodes[i-1]
249 | L = Body[bln-1] # NOTE: original line, not lstripped
250 |
251 | m = SECTS_RE(L)
252 | if not m:
253 | assert ELEMS_RE(L)
254 | # fixed level 1 element at level >1
255 | if lev_ > 1:
256 | invalid_elems.append(i)
257 | levels[i-1] = 1 # correct VO.levels
258 | continue
259 |
260 | # current section
261 | sect_ = '\\' + m.group(1)
262 | # required section and its actual level
263 | (sect, lev) = get_sect_for_lev(levs_sects, lev_)
264 | # change section (NOTE: SECTS_RE matches after \, thus -1)
265 | if not sect == sect_:
266 | Body[bln-1] = '%s%s%s' %(L[:m.start(1)-1], sect, L[m.end(1):])
267 | # check if max level was exceeded
268 | if not lev == lev_:
269 | invalid_sects.append(i)
270 | levels[i-1] = lev # correct VO.levels
271 | # changes VO._levs_sects
272 | if not lev in levs_sects:
273 | levs_sects[lev] = sect
274 |
275 | ### --- the end ---
276 | if invalid_elems or invalid_sects:
277 | vim.command("call voom#ErrorMsg('VOoM (latex): Disallowed levels have been corrected after ''%s''')" %oop)
278 | if invalid_elems:
279 | invalid_elems = ', '.join(['%s' %i for i in invalid_elems])
280 | vim.command("call voom#ErrorMsg(' level set to 1 for nodes: %s')" %invalid_elems)
281 | if invalid_sects:
282 | invalid_sects = ', '.join(['%s' %i for i in invalid_sects])
283 | vim.command("call voom#ErrorMsg(' level set to maximum for nodes: %s')" %invalid_sects)
284 |
285 |
286 | def get_sect_for_lev(levs_sects, level):
287 | """Return (section, actual level) corresponding to the desired level.
288 | levs_sects contains all sections currently in use.
289 | If level exceeds the maximum, return section for maximum possible level and max level.
290 | """
291 |
292 | if level in levs_sects:
293 | return (levs_sects[level], level)
294 |
295 | z = len(SECTIONS)
296 | # outline is empty
297 | if not levs_sects:
298 | if level <= z:
299 | return (SECTIONS[level-1], level)
300 | else:
301 | return (SECTIONS[-1], z)
302 |
303 | # pick new sect from SECTIONS
304 | levmax = max(levs_sects.keys()) # currently used max level
305 | sectmax = levs_sects[levmax]
306 | idx = SECTS_LEVS[sectmax] + (level - levmax)
307 | if idx <= z:
308 | return (SECTIONS[idx-1], level)
309 | else:
310 | return (SECTIONS[-1], level-(idx-z))
311 |
312 |
313 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_latexDtx.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_latexDtx.py
2 | # Last Modified: 2017-01-15
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for .dtx files (Documented LaTeX sources). It is almost
10 | identical to the LaTeX mode. The main difference is that only lines that begin
11 | with the comment character "%" can be headlines.
12 | See |voom-mode-latexDtx|, ../../../doc/voom.txt#*voom-mode-latexDtx*
13 | """
14 | # THIS MODULE IS ALMOST IDENTICAL TO voom_mode_latex.py -- KEEP IN SYNC.
15 | #
16 | # Only commented lines are considered. Commented lines start with: optional
17 | # leading whitespace, at least one % character, optionally followed by any
18 | # combination of % and whitespace.
19 | # The following are all valid sectioning commands:
20 | # %\section{Introduction}
21 | # % \section{Introduction}
22 | # %% \section{Introduction}
23 | # %%% % % \section{Introduction}
24 | # The leading string of % and whitespace is preserved during outline operations.
25 |
26 |
27 | # SECTIONS, ELEMENTS, VERBATIMS can be defined here or in Vim variables:
28 | # g:voom_latexdtx_sections
29 | # g:voom_latexdtx_elements
30 | # g:voom_latexdtx_verbatims
31 | #
32 | # SECTIONS defines sectioning commands, in order of increasing level:
33 | # \part{A Heading}
34 | # \chapter{A Heading}
35 | # \section{A Heading}
36 | # \subsection{A Heading}
37 | # \subsubsection{A Heading}
38 | # \paragraph{A Heading}
39 | # \subparagraph{A Heading}
40 | #
41 | # ELEMENTS defines fixed elements -- always at level 1:
42 | # \begin{document}
43 | # \begin{abstract}
44 | # \begin{thebibliography}
45 | # \end{document}
46 | # \bibliography{...
47 | #
48 | # VERBATIMS defines regions where headlines are ignored:
49 | # \begin{verbatim} ... \end{verbatim}
50 | # \begin{comment} ... \end{comment}
51 | #
52 | # The actual levels are determined by sections that are present in the buffer.
53 | # Levels are always incremented by 1. That is, if there are only
54 | # \section and \paragraph then \section is level 1 and \paragraph is level 2.
55 |
56 | # sectioning commands, in order of increasing level
57 | SECTIONS = ['part', 'chapter',
58 | 'section', 'subsection', 'subsubsection',
59 | 'paragraph', 'subparagraph']
60 |
61 | # fixed elements -- always at level 1
62 | ELEMENTS = r'^[\s%]*\\(begin\s*\{(document|abstract|thebibliography)\}|end\s*\{document\}|bibliography\s*\{)'
63 |
64 | # verbatim regions, headlines are ignored inside \begin{verbatim} ... \end{verbatim}
65 | VERBATIMS = ['verbatim', 'comment', 'macrocode']
66 | #---------------------------------------------------------------------
67 |
68 | try:
69 | import vim
70 | if vim.eval('exists("g:voom_latexdtx_sections")')=='1':
71 | SECTIONS = vim.eval("g:voom_latexdtx_sections")
72 | if vim.eval('exists("g:voom_latexdtx_elements")')=='1':
73 | ELEMENTS = vim.eval("g:voom_latexdtx_elements")
74 | if vim.eval('exists("g:voom_latexdtx_verbatims")')=='1':
75 | VERBATIMS = vim.eval("g:voom_latexdtx_verbatims")
76 | except ImportError:
77 | pass
78 |
79 | import sys
80 | if sys.version_info[0] > 2:
81 | xrange = range
82 |
83 | import re
84 |
85 | # \section{head} or \section*{head} or \section[optionaltitle]{head}
86 | # NOTE: match leading whitespace to preserve it during outline operations
87 | # m.group() 1 2 3
88 | SECTS_RE = re.compile(r'^[\s%%]*\\(%s)\s*(\*|\[[^]{]*\])?\s*\{(.*)' %('|'.join(SECTIONS))).match
89 |
90 | if ELEMENTS:
91 | ELEMS_RE = re.compile(ELEMENTS).match
92 | else:
93 | ELEMS_RE = 0
94 |
95 | if VERBATIMS:
96 | # NOTE: leading whitespace and % must be lstripped before matching
97 | VERBS_RE = re.compile(r'^\\begin\s*\{(%s)\}' %('|'.join(VERBATIMS))).match
98 | else:
99 | VERBS_RE = 0
100 |
101 | SECTIONS = ['\\'+s for s in SECTIONS]
102 | SECTS_LEVS = {} # {section: its default level, ...}
103 | LEVS_SECTS = {} # {level: its default section, ...}
104 | i = 1
105 | for s in SECTIONS:
106 | SECTS_LEVS[s] = i
107 | LEVS_SECTS[i] = s
108 | i+=1
109 |
110 |
111 | def hook_makeOutline(VO, blines):
112 | """Return (tlines, bnodes, levels) for Body lines blines.
113 | blines is either Vim buffer object (Body) or list of buffer lines.
114 | """
115 | Z = len(blines)
116 | tlines, bnodes, levels = [], [], []
117 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
118 | marks, heads = [], []
119 | marks_add, heads_add = marks.append, heads.append
120 |
121 | sects_levs = {} # {section: its default level} for all section found in the buffer
122 | inVerbatim = False
123 | isHead = False
124 | mark = ' ' # * or -
125 | for i in xrange(Z):
126 | L = blines[i].lstrip()
127 | if not L.startswith('%'): continue # dtx-specific
128 | L = L.lstrip('% \t') # dtx-specifc
129 | if not L.startswith('\\'): continue
130 | # regions to ignore: \begin{verbatim} ... \end{verbatim}
131 | if VERBS_RE:
132 | if inVerbatim:
133 | if re.match(inVerbatim, L):
134 | inVerbatim = False
135 | continue
136 | else:
137 | m = VERBS_RE(L)
138 | if m:
139 | inVerbatim = r'\\end\s*\{%s\}' %m.group(1)
140 | continue
141 | # check for sections
142 | m = SECTS_RE(L)
143 | if m:
144 | isHead = True
145 | s = '\\' + m.group(1)
146 | lev = SECTS_LEVS[s]
147 | sects_levs[s] = lev
148 | if m.group(2) and m.group(2)=='*':
149 | mark = '*'
150 | head = m.group(3)
151 | # truncate head before the matching '}'
152 | j = 0; k = 1
153 | for ch in head:
154 | if ch=='{': k+=1
155 | elif ch=='}': k-=1
156 | if not k: break
157 | j+=1
158 | head = head[:j].strip()
159 | # check for fixed level 1 elements
160 | elif ELEMS_RE:
161 | m = ELEMS_RE(L)
162 | if m:
163 | isHead = True
164 | lev = 1
165 | head = L.rstrip()
166 | mark = '-'
167 | # add node to outline
168 | if isHead:
169 | isHead = False
170 | bnodes_add(i+1)
171 | levels_add(lev)
172 | # tlines must be constructed from marks and heads and after levels are adjusted
173 | marks_add(mark)
174 | mark = ' '
175 | heads_add(head)
176 |
177 | # adjust default level numbers to reflect only sections present in the buffer
178 | # that is make all level numbers continuous, top level is 1
179 | d = {} # {default level: actual level, ...}
180 | levs_sects = {} # {actual level: section, ...}
181 | sects = [(sects_levs[s], s) for s in sects_levs.keys()]
182 | sects.sort()
183 | sects = [i[1] for i in sects]
184 | i = 1
185 | for s in sects:
186 | d[sects_levs[s]] = i
187 | levs_sects[i] = s
188 | i+=1
189 | levels = [d.get(i,i) for i in levels]
190 |
191 | # construct tlines
192 | for i in xrange(len(levels)):
193 | tlines_add(' %s%s|%s' %(marks[i], '. '*(levels[i]-1), heads[i]))
194 |
195 | # save levs_sects for outline operations
196 | # don't clobber VO.levs_sects when parsing clipboard during Paste
197 | # which is the only time blines is not Body
198 | if blines is VO.Body:
199 | VO._levs_sects = levs_sects
200 |
201 | return (tlines, bnodes, levels)
202 |
203 |
204 | def hook_newHeadline(VO, level, blnum, tlnum):
205 | """Return (tree_head, bodyLines).
206 | tree_head is new headline string in Tree buffer (text after |).
207 | bodyLines is list of lines to insert in Body buffer.
208 | """
209 | tree_head = 'NewHeadline'
210 | (sect, lev) = get_sect_for_lev(VO._levs_sects, level)
211 | assert lev <= level
212 | if not lev==level:
213 | vim.command("call voom#ErrorMsg('VOoM (latexDtx): MAXIMUM LEVEL EXCEEDED')")
214 |
215 | bodyLines = ['%% %s{%s}' %(sect, tree_head), '%'] # dtx-specific (insert %)
216 | return (tree_head, bodyLines)
217 |
218 |
219 | #def hook_changeLevBodyHead(VO, h, levDelta):
220 | # DO NOT CREATE THIS HOOK
221 |
222 |
223 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
224 | # this is instead of hook_changeLevBodyHead()
225 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
226 | Body = VO.Body
227 | Z = len(Body)
228 | bnodes, levels = VO.bnodes, VO.levels
229 |
230 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
231 | # during up/down, or promoted/demoted.
232 | if blnum1:
233 | assert blnum1 == bnodes[tlnum1-1]
234 | if tlnum2 < len(bnodes):
235 | assert blnum2 == bnodes[tlnum2]-1
236 | else:
237 | assert blnum2 == Z
238 |
239 | # blnumCut is Body lnum after which a region was removed during 'cut'
240 | if blnumCut:
241 | if tlnumCut < len(bnodes):
242 | assert blnumCut == bnodes[tlnumCut]-1
243 | else:
244 | assert blnumCut == Z
245 |
246 | ### Change levels and/or sections of headlines in the affected region.
247 | # Sections must always be adjusted after Paste, even if level is unchanged,
248 | # in case pasting was done from another outline with different style.
249 | if not (levDelta or oop=='paste'):
250 | return
251 |
252 | # Examine each headline in the affected region from top to bottom.
253 | # For sections: change them to the current level and style.
254 | # Correct invalid levels: VOoM**voom_notes.txt#ID_20120520092604
255 | # use max level if max possible level is exeeded
256 | # use 1 for fixed elements at level >1
257 | invalid_sects, invalid_elems = [], [] # tree lnums of nodes with disallowed levels
258 | levs_sects = VO._levs_sects
259 | #for i in xrange(tlnum2, tlnum1-1, -1):
260 | for i in xrange(tlnum1, tlnum2+1):
261 | # required level based on new VO.levels, can be disallowed
262 | lev_ = levels[i-1]
263 | # Body line
264 | bln = bnodes[i-1]
265 | L = Body[bln-1] # NOTE: original line, not lstripped
266 |
267 | m = SECTS_RE(L)
268 | if not m:
269 | assert ELEMS_RE(L)
270 | # fixed level 1 element at level >1
271 | if lev_ > 1:
272 | invalid_elems.append(i)
273 | levels[i-1] = 1 # correct VO.levels
274 | continue
275 |
276 | # current section
277 | sect_ = '\\' + m.group(1)
278 | # required section and its actual level
279 | (sect, lev) = get_sect_for_lev(levs_sects, lev_)
280 | # change section (NOTE: SECTS_RE matches after \, thus -1)
281 | if not sect == sect_:
282 | Body[bln-1] = '%s%s%s' %(L[:m.start(1)-1], sect, L[m.end(1):])
283 | # check if max level was exceeded
284 | if not lev == lev_:
285 | invalid_sects.append(i)
286 | levels[i-1] = lev # correct VO.levels
287 | # changes VO._levs_sects
288 | if not lev in levs_sects:
289 | levs_sects[lev] = sect
290 |
291 | ### --- the end ---
292 | if invalid_elems or invalid_sects:
293 | vim.command("call voom#ErrorMsg('VOoM (latexDtx): Disallowed levels have been corrected after ''%s''')" %oop)
294 | if invalid_elems:
295 | invalid_elems = ', '.join(['%s' %i for i in invalid_elems])
296 | vim.command("call voom#ErrorMsg(' level set to 1 for nodes: %s')" %invalid_elems)
297 | if invalid_sects:
298 | invalid_sects = ', '.join(['%s' %i for i in invalid_sects])
299 | vim.command("call voom#ErrorMsg(' level set to maximum for nodes: %s')" %invalid_sects)
300 |
301 |
302 | def get_sect_for_lev(levs_sects, level):
303 | """Return (section, actual level) corresponding to the desired level.
304 | levs_sects contains all sections currently in use.
305 | If level exceeds the maximum, return section for maximum possible level and max level.
306 | """
307 |
308 | if level in levs_sects:
309 | return (levs_sects[level], level)
310 |
311 | z = len(SECTIONS)
312 | # outline is empty
313 | if not levs_sects:
314 | if level <= z:
315 | return (SECTIONS[level-1], level)
316 | else:
317 | return (SECTIONS[-1], z)
318 |
319 | # pick new sect from SECTIONS
320 | levmax = max(levs_sects.keys()) # currently used max level
321 | sectmax = levs_sects[levmax]
322 | idx = SECTS_LEVS[sectmax] + (level - levmax)
323 | if idx <= z:
324 | return (SECTIONS[idx-1], level)
325 | else:
326 | return (SECTIONS[-1], level-(idx-z))
327 |
328 |
329 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_markdown.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_markdown.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for Markdown headers.
10 | See |voom-mode-markdown|, ../../../doc/voom.txt#*voom-mode-markdown*
11 | """
12 |
13 | import sys
14 | if sys.version_info[0] > 2:
15 | xrange = range
16 | def len_u(s, enc):
17 | return len(s)
18 | else:
19 | def len_u(s, enc):
20 | return len(unicode(s, enc, 'replace'))
21 |
22 | ### NOTES
23 | # When an outline operation changes level, it has to deal with two ambiguities:
24 | # a) Level 1 and 2 headline can use underline-style or hashes-style.
25 | # b) Hashes-style can have or not have closing hashes.
26 | # To determine current preferences: check first headline at level <3 and check
27 | # first headline with hashes. This must be done in hook_makeOutline().
28 | # (Save in VO, similar to reST mode.) Cannot be done during outline operation,
29 | # that is in hook_doBodyAfterOop().
30 | # Defaults: use underline, use closing hashes.
31 |
32 | LEVELS_ADS = {1:'=', 2:'-'}
33 | ADS_LEVELS = {'=':1, '-':2}
34 |
35 | def hook_makeOutline(VO, blines):
36 | """Return (tlines, bnodes, levels) for Body lines blines.
37 | blines is either Vim buffer object (Body) or list of buffer lines.
38 | """
39 | Z = len(blines)
40 | tlines, bnodes, levels = [], [], []
41 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
42 |
43 | # trailing whitespace is always removed with rstrip()
44 | #
45 | # underline-style, overrides hashes-style:
46 | # head L1, blines[i] -- current line, title line, not blank
47 | # ------ L2, blines[i+1] -- any number of = or - only
48 | #
49 | # hashes-style:
50 | # ## head L1, blines[i] -- current line
51 | # abcde L2, blines[i+1]
52 | #
53 |
54 | # Set this once when headline with level 1 or 2 is encountered.
55 | # 0 or 1 -- False, use underline-style (default); 2 -- True, use hashes-style
56 | useHash = 0
57 | # Set this once when headline with hashes is encountered.
58 | # 0 or 1 -- True, use closing hashes (default); 2 -- False, do not use closing hashes
59 | useCloseHash = 0
60 |
61 | L2 = blines[0].rstrip() # first Body line
62 | isHead = False
63 | for i in xrange(Z):
64 | L1 = L2
65 | j = i+1
66 | if j < Z:
67 | L2 = blines[j].rstrip()
68 | else:
69 | L2 = ''
70 |
71 | if not L1:
72 | continue
73 |
74 | if L2 and (L2[0] in ADS_LEVELS) and not L2.lstrip(L2[0]):
75 | isHead = True
76 | lev = ADS_LEVELS[L2[0]]
77 | head = L1.strip()
78 | L2 = ''
79 | if not useHash:
80 | useHash = 1
81 | elif L1.startswith('#'):
82 | isHead = True
83 | lev = len(L1) - len(L1.lstrip('#'))
84 | head = L1.strip('#').strip()
85 | if not useHash and lev < 3:
86 | useHash = 2
87 | if not useCloseHash:
88 | if L1.endswith('#'): useCloseHash = 1
89 | else: useCloseHash = 2
90 | else:
91 | continue
92 |
93 | if isHead:
94 | isHead = False
95 | tline = ' %s|%s' %('. '*(lev-1), head)
96 | tlines_add(tline)
97 | bnodes_add(j)
98 | levels_add(lev)
99 |
100 | # don't clobber these when parsing clipboard during Paste
101 | # which is the only time blines is not Body
102 | if blines is VO.Body:
103 | VO.useHash = useHash == 2
104 | VO.useCloseHash = useCloseHash < 2
105 |
106 | return (tlines, bnodes, levels)
107 |
108 | #------ the rest is identical to voom_mode_pandoc.py ------
109 |
110 |
111 | def hook_newHeadline(VO, level, blnum, tlnum):
112 | """Return (tree_head, bodyLines).
113 | tree_head is new headline string in Tree buffer (text after |).
114 | bodyLines is list of lines to insert in Body buffer.
115 | """
116 | tree_head = 'NewHeadline'
117 | if level < 3 and not VO.useHash:
118 | bodyLines = [tree_head, LEVELS_ADS[level]*11, '']
119 | else:
120 | lev = '#'*level
121 | if VO.useCloseHash:
122 | bodyLines = ['%s %s %s' %(lev, tree_head, lev), '']
123 | else:
124 | bodyLines = ['%s %s' %(lev, tree_head), '']
125 |
126 | # Add blank line when inserting after non-blank Body line.
127 | if VO.Body[blnum-1].strip():
128 | bodyLines[0:0] = ['']
129 |
130 | return (tree_head, bodyLines)
131 |
132 |
133 | #def hook_changeLevBodyHead(VO, h, levDelta):
134 | # DO NOT CREATE THIS HOOK
135 |
136 |
137 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
138 | # this is instead of hook_changeLevBodyHead()
139 |
140 | # Based on reST mode function. Insert blank separator lines if missing,
141 | # even though they are not important for Markdown headlines.
142 |
143 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
144 | Body = VO.Body
145 | Z = len(Body)
146 | bnodes, levels = VO.bnodes, VO.levels
147 | ENC = VO.enc
148 |
149 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
150 | # during up/down, or promoted/demoted.
151 | if blnum1:
152 | assert blnum1 == bnodes[tlnum1-1]
153 | if tlnum2 < len(bnodes):
154 | assert blnum2 == bnodes[tlnum2]-1
155 | else:
156 | assert blnum2 == Z
157 |
158 | # blnumCut is Body lnum after which a region was removed during 'cut',
159 | # 'up', 'down'. Need this to check if there is blank line between nodes
160 | # used to be separated by the cut/moved region.
161 | if blnumCut:
162 | if tlnumCut < len(bnodes):
163 | assert blnumCut == bnodes[tlnumCut]-1
164 | else:
165 | assert blnumCut == Z
166 |
167 | # Total number of added lines minus number of deleted lines.
168 | b_delta = 0
169 |
170 | ### After 'cut' or 'up': insert blank line if there is none
171 | # between the nodes used to be separated by the cut/moved region.
172 | if (oop=='cut' or oop=='up') and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
173 | Body[blnumCut:blnumCut] = ['']
174 | update_bnodes(VO, tlnumCut+1 ,1)
175 | b_delta+=1
176 |
177 | if oop=='cut':
178 | return
179 |
180 | ### Make sure there is blank line after the last node in the region:
181 | # insert blank line after blnum2 if blnum2 is not blank, that is insert
182 | # blank line before bnode at tlnum2+1.
183 | if blnum2 < Z and Body[blnum2-1].strip():
184 | Body[blnum2:blnum2] = ['']
185 | update_bnodes(VO, tlnum2+1 ,1)
186 | b_delta+=1
187 |
188 | ### Change levels and/or formats of headlines in the affected region.
189 | # Always do this after Paste, even if level is unchanged -- format can
190 | # be different when pasting from other outlines.
191 | # Examine each headline, from bottom to top, and change level and/or format.
192 | # To change from hashes to underline-style:
193 | # strip hashes, strip whitespace;
194 | # insert underline.
195 | # To change from underline to hashes-style:
196 | # delete underline or change it to blank if it is followed by another underline
197 | # insert hashes.
198 | # Update bnodes after inserting or deleting a line.
199 |
200 | # hash-style underline-style (overrides hash-style)
201 | #
202 | # ## head L1 head L1 <--bnode Body[bln-1]
203 | # L2 ---- L2 Body[bln]
204 | # L3 L3 Body[bln+1]
205 |
206 | if levDelta or oop=='paste':
207 | for i in xrange(tlnum2, tlnum1-1, -1):
208 | # required level (VO.levels has been updated)
209 | lev = levels[i-1]
210 | # current level from which to change to lev
211 | lev_ = lev - levDelta
212 |
213 | # Body headline (bnode) and next line
214 | bln = bnodes[i-1]
215 | L1 = Body[bln-1].rstrip()
216 | if bln < len(Body):
217 | L2 = Body[bln].rstrip()
218 | else:
219 | L2 = ''
220 |
221 | # get the current headline format
222 | hasHash, hasCloseHash = True, VO.useCloseHash
223 | if L2 and (L2.lstrip('=')=='' or L2.lstrip('-')==''):
224 | hasHash = False
225 | else:
226 | if L1.endswith('#'):
227 | hasCloseHash = True
228 | else:
229 | hasCloseHash = False
230 |
231 | # get the desired headline format
232 | if oop=='paste':
233 | if lev > 2:
234 | useHash = True
235 | else:
236 | useHash = VO.useHash
237 | useCloseHash = VO.useCloseHash
238 | elif lev < 3 and lev_ < 3:
239 | useHash = hasHash
240 | useCloseHash = hasCloseHash
241 | elif lev > 2 and lev_ > 2:
242 | useHash = True
243 | useCloseHash = hasCloseHash
244 | elif lev < 3 and lev_ > 2:
245 | useHash = VO.useHash
246 | useCloseHash = VO.useCloseHash
247 | elif lev > 2 and lev_ < 3:
248 | useHash = True
249 | useCloseHash = hasCloseHash
250 | else:
251 | assert False
252 | #print('useHash=%s hasHash=%s useCloseHash=%s hasCloseHash=%s' %(useHash, hasHash, useCloseHash, hasCloseHash))
253 | #print('%s %s' %(L1, L2))
254 |
255 | # change headline level and/or format
256 |
257 | # underline-style unchanged, only adjust level of underline
258 | if not useHash and not hasHash:
259 | if not levDelta: continue
260 | Body[bln] = LEVELS_ADS[lev]*len(L2)
261 | # hashes-style unchanged, adjust level of hashes and add/remove closing hashes
262 | elif useHash and hasHash:
263 | # no format change, there are closing hashes
264 | if useCloseHash and hasCloseHash:
265 | if not levDelta: continue
266 | Body[bln-1] = '%s%s%s' %('#'*lev, L1.strip('#'), '#'*lev)
267 | # no format change, there are no closing hashes
268 | elif not useCloseHash and not hasCloseHash:
269 | if not levDelta: continue
270 | Body[bln-1] = '%s%s' %('#'*lev, L1.lstrip('#'))
271 | # add closing hashes
272 | elif useCloseHash and not hasCloseHash:
273 | Body[bln-1] = '%s%s %s' %('#'*lev, L1.strip('#').rstrip(), '#'*lev)
274 | # remove closing hashes
275 | elif not useCloseHash and hasCloseHash:
276 | Body[bln-1] = '%s%s' %('#'*lev, L1.strip('#').rstrip())
277 | # insert underline, remove hashes
278 | elif not useHash and hasHash:
279 | L = L1.strip('#').strip()
280 | Body[bln-1] = L
281 | # insert underline
282 | Body[bln:bln] = [LEVELS_ADS[lev] * len_u(L, ENC)]
283 | update_bnodes(VO, i+1, 1)
284 | b_delta+=1
285 | # remove underline, insert hashes
286 | elif useHash and not hasHash:
287 | if L1[0].isspace():
288 | sp = ''
289 | else:
290 | sp = ' '
291 | if useCloseHash:
292 | Body[bln-1] = '%s%s%s %s' %('#'*lev, sp, L1, '#'*lev)
293 | else:
294 | Body[bln-1] = '%s%s%s' %('#'*lev, sp, L1)
295 | # check if the next line after underline is another underline
296 | if bln+1 < len(Body):
297 | L3 = Body[bln+1].rstrip()
298 | else:
299 | L3 = ''
300 | #print('%s %s %s' %(L1, L2, L3))
301 | # yes: do not delete underline, change it to a blank line
302 | if L3 and (L3.lstrip('=')=='' or L3.lstrip('-')==''):
303 | Body[bln] = ''
304 | # no: delete underline
305 | else:
306 | Body[bln:bln+1] = []
307 | update_bnodes(VO, i+1, -1)
308 | b_delta-=1
309 |
310 | ### Make sure first headline is preceded by a blank line.
311 | blnum1 = bnodes[tlnum1-1]
312 | if blnum1 > 1 and Body[blnum1-2].strip():
313 | Body[blnum1-1:blnum1-1] = ['']
314 | update_bnodes(VO, tlnum1 ,1)
315 | b_delta+=1
316 |
317 | ### After 'down' : insert blank line if there is none
318 | # between the nodes used to be separated by the moved region.
319 | if oop=='down' and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
320 | Body[blnumCut:blnumCut] = ['']
321 | update_bnodes(VO, tlnumCut+1 ,1)
322 | b_delta+=1
323 |
324 | assert len(Body) == Z + b_delta
325 |
326 |
327 | def update_bnodes(VO, tlnum, delta):
328 | """Update VO.bnodes by adding/substracting delta to each bnode
329 | starting with bnode at tlnum and to the end.
330 | """
331 | bnodes = VO.bnodes
332 | for i in xrange(tlnum, len(bnodes)+1):
333 | bnodes[i-1] += delta
334 |
335 |
336 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_org.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_org.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for Emacs Org-mode headline format.
10 | See |voom-mode-org|, ../../../doc/voom.txt#*voom-mode-org*
11 | """
12 |
13 | import sys
14 | if sys.version_info[0] > 2:
15 | xrange = range
16 |
17 | import re
18 | headline_match = re.compile(r'^(\*+)\s').match
19 |
20 |
21 | def hook_makeOutline(VO, blines):
22 | """Return (tlines, bnodes, levels) for Body lines blines.
23 | blines is either Vim buffer object (Body) or list of buffer lines.
24 | """
25 | Z = len(blines)
26 | tlines, bnodes, levels = [], [], []
27 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
28 | for i in xrange(Z):
29 | if not blines[i].startswith('*'):
30 | continue
31 | bline = blines[i]
32 | m = headline_match(bline)
33 | if not m:
34 | continue
35 | lev = len(m.group(1))
36 | head = bline[lev:].strip()
37 | tline = ' %s|%s' %('. '*(lev-1), head)
38 | tlines_add(tline)
39 | bnodes_add(i+1)
40 | levels_add(lev)
41 | return (tlines, bnodes, levels)
42 |
43 |
44 | def hook_newHeadline(VO, level, blnum, tlnum):
45 | """Return (tree_head, bodyLines).
46 | tree_head is new headline string in Tree buffer (text after |).
47 | bodyLines is list of lines to insert in Body buffer.
48 | """
49 | tree_head = 'NewHeadline'
50 | bodyLines = ['%s %s' %('*'*level, tree_head), '']
51 | return (tree_head, bodyLines)
52 |
53 |
54 | def hook_changeLevBodyHead(VO, h, levDelta):
55 | """Increase of decrease level number of Body headline by levDelta."""
56 | if levDelta==0: return h
57 | m = headline_match(h)
58 | level = len(m.group(1))
59 | return '%s%s' %('*'*(level+levDelta), h[m.end(1):])
60 |
61 |
62 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_pandoc.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_pandoc.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for Pandoc Markdown headers.
10 | See |voom-mode-pandoc|, ../../../doc/voom.txt#*voom-mode-pandoc*
11 | """
12 |
13 | import sys
14 | if sys.version_info[0] > 2:
15 | xrange = range
16 | def len_u(s, enc):
17 | return len(s)
18 | else:
19 | def len_u(s, enc):
20 | return len(unicode(s, enc, 'replace'))
21 |
22 | ### NOTES
23 | # The code is identical to voom_mode_markdown.py except that the parser ignores
24 | # headlines that:
25 | # - are not preceded by a blank line, or another headline, or an end of fenced block
26 | # - are inside fenced code blocks.
27 |
28 | LEVELS_ADS = {1:'=', 2:'-'}
29 | ADS_LEVELS = {'=':1, '-':2}
30 |
31 | def hook_makeOutline(VO, blines):
32 | """Return (tlines, bnodes, levels) for Body lines blines.
33 | blines is either Vim buffer object (Body) or list of buffer lines.
34 | """
35 | Z = len(blines)
36 | tlines, bnodes, levels = [], [], []
37 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
38 |
39 | # trailing whitespace is always removed with rstrip()
40 | #
41 | # underline-style, overrides hashes-style:
42 | # head L1, blines[i] -- current line, title line, not blank
43 | # ------ L2, blines[i+1] -- any number of = or - only
44 | #
45 | # hashes-style:
46 | # ## head L1, blines[i] -- current line
47 | # abcde L2, blines[i+1]
48 | #
49 |
50 | # Set this once when headline with level 1 or 2 is encountered.
51 | # 0 or 1 -- False, use underline-style (default); 2 -- True, use hashes-style
52 | useHash = 0
53 | # Set this once when headline with hashes is encountered.
54 | # 0 or 1 -- True, use closing hashes (default); 2 -- False, do not use closing hashes
55 | useCloseHash = 0
56 |
57 | # Keep track of fenced code blocks where headlines are ignored.
58 | isFenced = ''
59 | # Set True on lines after which a new headline is allowed: blank line,
60 | # headline, end-of-fenced-block. Also applies to start-of-fenced-block.
61 | ok = 1
62 | L2 = blines[0].rstrip() # first Body line
63 | isHead = False
64 | for i in xrange(Z):
65 | L1 = L2
66 | j = i+1
67 | if j < Z:
68 | L2 = blines[j].rstrip()
69 | else:
70 | L2 = ''
71 |
72 | if not L1:
73 | ok = 1
74 | continue
75 |
76 | # ignore headlines inside fenced code block
77 | if isFenced:
78 | if L1.startswith(isFenced) and L1.lstrip(isFenced[0])=='':
79 | isFenced = ''
80 | ok = 1
81 | continue
82 |
83 | # Headline is allowed only after a blank line, another headline,
84 | # end-of-fenced block. Same for start-of-fenced-block.
85 | if not ok:
86 | continue
87 |
88 | # new fenced code block
89 | if L1.startswith('~~~') or L1.startswith('```'):
90 | ch = L1[0]
91 | isFenced = ch*(len(L1)-len(L1.lstrip(ch)))
92 | continue
93 |
94 | if L2 and (L2[0] in ADS_LEVELS) and not L2.lstrip(L2[0]):
95 | isHead = True
96 | lev = ADS_LEVELS[L2[0]]
97 | head = L1.strip()
98 | L2 = '' # this will set ok=1 on the next line (underline)
99 | if not useHash:
100 | useHash = 1
101 | elif L1.startswith('#') and not L1.startswith('#. '):
102 | ok = 1
103 | isHead = True
104 | lev = len(L1) - len(L1.lstrip('#'))
105 | head = L1.strip('#').strip()
106 | if not useHash and lev < 3:
107 | useHash = 2
108 | if not useCloseHash:
109 | if L1.endswith('#'): useCloseHash = 1
110 | else: useCloseHash = 2
111 | else:
112 | ok = 0
113 | continue
114 |
115 | if isHead:
116 | isHead = False
117 | tline = ' %s|%s' %('. '*(lev-1), head)
118 | tlines_add(tline)
119 | bnodes_add(j)
120 | levels_add(lev)
121 |
122 | # don't clobber these when parsing clipboard during Paste
123 | # which is the only time blines is not Body
124 | if blines is VO.Body:
125 | VO.useHash = useHash == 2
126 | VO.useCloseHash = useCloseHash < 2
127 |
128 | return (tlines, bnodes, levels)
129 |
130 | #------ the rest is identical to voom_mode_markdown.py ------
131 |
132 |
133 | def hook_newHeadline(VO, level, blnum, tlnum):
134 | """Return (tree_head, bodyLines).
135 | tree_head is new headline string in Tree buffer (text after |).
136 | bodyLines is list of lines to insert in Body buffer.
137 | """
138 | tree_head = 'NewHeadline'
139 | if level < 3 and not VO.useHash:
140 | bodyLines = [tree_head, LEVELS_ADS[level]*11, '']
141 | else:
142 | lev = '#'*level
143 | if VO.useCloseHash:
144 | bodyLines = ['%s %s %s' %(lev, tree_head, lev), '']
145 | else:
146 | bodyLines = ['%s %s' %(lev, tree_head), '']
147 |
148 | # Add blank line when inserting after non-blank Body line.
149 | if VO.Body[blnum-1].strip():
150 | bodyLines[0:0] = ['']
151 |
152 | return (tree_head, bodyLines)
153 |
154 |
155 | #def hook_changeLevBodyHead(VO, h, levDelta):
156 | # DO NOT CREATE THIS HOOK
157 |
158 |
159 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
160 | # this is instead of hook_changeLevBodyHead()
161 |
162 | # Based on reST mode function. Insert blank separator lines if missing,
163 | # even though they are not important for Markdown headlines.
164 |
165 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
166 | Body = VO.Body
167 | Z = len(Body)
168 | bnodes, levels = VO.bnodes, VO.levels
169 | ENC = VO.enc
170 |
171 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
172 | # during up/down, or promoted/demoted.
173 | if blnum1:
174 | assert blnum1 == bnodes[tlnum1-1]
175 | if tlnum2 < len(bnodes):
176 | assert blnum2 == bnodes[tlnum2]-1
177 | else:
178 | assert blnum2 == Z
179 |
180 | # blnumCut is Body lnum after which a region was removed during 'cut',
181 | # 'up', 'down'. Need this to check if there is blank line between nodes
182 | # used to be separated by the cut/moved region.
183 | if blnumCut:
184 | if tlnumCut < len(bnodes):
185 | assert blnumCut == bnodes[tlnumCut]-1
186 | else:
187 | assert blnumCut == Z
188 |
189 | # Total number of added lines minus number of deleted lines.
190 | b_delta = 0
191 |
192 | ### After 'cut' or 'up': insert blank line if there is none
193 | # between the nodes used to be separated by the cut/moved region.
194 | if (oop=='cut' or oop=='up') and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
195 | Body[blnumCut:blnumCut] = ['']
196 | update_bnodes(VO, tlnumCut+1 ,1)
197 | b_delta+=1
198 |
199 | if oop=='cut':
200 | return
201 |
202 | ### Make sure there is blank line after the last node in the region:
203 | # insert blank line after blnum2 if blnum2 is not blank, that is insert
204 | # blank line before bnode at tlnum2+1.
205 | if blnum2 < Z and Body[blnum2-1].strip():
206 | Body[blnum2:blnum2] = ['']
207 | update_bnodes(VO, tlnum2+1 ,1)
208 | b_delta+=1
209 |
210 | ### Change levels and/or formats of headlines in the affected region.
211 | # Always do this after Paste, even if level is unchanged -- format can
212 | # be different when pasting from other outlines.
213 | # Examine each headline, from bottom to top, and change level and/or format.
214 | # To change from hashes to underline-style:
215 | # strip hashes, strip whitespace;
216 | # insert underline.
217 | # To change from underline to hashes-style:
218 | # delete underline or change it to blank if it is followed by another underline
219 | # insert hashes.
220 | # Update bnodes after inserting or deleting a line.
221 |
222 | # hash-style underline-style (overrides hash-style)
223 | #
224 | # ## head L1 head L1 <--bnode Body[bln-1]
225 | # L2 ---- L2 Body[bln]
226 | # L3 L3 Body[bln+1]
227 |
228 | if levDelta or oop=='paste':
229 | for i in xrange(tlnum2, tlnum1-1, -1):
230 | # required level (VO.levels has been updated)
231 | lev = levels[i-1]
232 | # current level from which to change to lev
233 | lev_ = lev - levDelta
234 |
235 | # Body headline (bnode) and next line
236 | bln = bnodes[i-1]
237 | L1 = Body[bln-1].rstrip()
238 | if bln < len(Body):
239 | L2 = Body[bln].rstrip()
240 | else:
241 | L2 = ''
242 |
243 | # get the current headline format
244 | hasHash, hasCloseHash = True, VO.useCloseHash
245 | if L2 and (L2.lstrip('=')=='' or L2.lstrip('-')==''):
246 | hasHash = False
247 | else:
248 | if L1.endswith('#'):
249 | hasCloseHash = True
250 | else:
251 | hasCloseHash = False
252 |
253 | # get the desired headline format
254 | if oop=='paste':
255 | if lev > 2:
256 | useHash = True
257 | else:
258 | useHash = VO.useHash
259 | useCloseHash = VO.useCloseHash
260 | elif lev < 3 and lev_ < 3:
261 | useHash = hasHash
262 | useCloseHash = hasCloseHash
263 | elif lev > 2 and lev_ > 2:
264 | useHash = True
265 | useCloseHash = hasCloseHash
266 | elif lev < 3 and lev_ > 2:
267 | useHash = VO.useHash
268 | useCloseHash = VO.useCloseHash
269 | elif lev > 2 and lev_ < 3:
270 | useHash = True
271 | useCloseHash = hasCloseHash
272 | else:
273 | assert False
274 | #print('useHash=%s hasHash=%s useCloseHash=%s hasCloseHash=%s' %(useHash, hasHash, useCloseHash, hasCloseHash))
275 | #print('%s %s' %(L1, L2))
276 |
277 | # change headline level and/or format
278 |
279 | # underline-style unchanged, only adjust level of underline
280 | if not useHash and not hasHash:
281 | if not levDelta: continue
282 | Body[bln] = LEVELS_ADS[lev]*len(L2)
283 | # hashes-style unchanged, adjust level of hashes and add/remove closing hashes
284 | elif useHash and hasHash:
285 | # no format change, there are closing hashes
286 | if useCloseHash and hasCloseHash:
287 | if not levDelta: continue
288 | Body[bln-1] = '%s%s%s' %('#'*lev, L1.strip('#'), '#'*lev)
289 | # no format change, there are no closing hashes
290 | elif not useCloseHash and not hasCloseHash:
291 | if not levDelta: continue
292 | Body[bln-1] = '%s%s' %('#'*lev, L1.lstrip('#'))
293 | # add closing hashes
294 | elif useCloseHash and not hasCloseHash:
295 | Body[bln-1] = '%s%s %s' %('#'*lev, L1.strip('#').rstrip(), '#'*lev)
296 | # remove closing hashes
297 | elif not useCloseHash and hasCloseHash:
298 | Body[bln-1] = '%s%s' %('#'*lev, L1.strip('#').rstrip())
299 | # insert underline, remove hashes
300 | elif not useHash and hasHash:
301 | L = L1.strip('#').strip()
302 | Body[bln-1] = L
303 | # insert underline
304 | Body[bln:bln] = [LEVELS_ADS[lev] * len_u(L, ENC)]
305 | update_bnodes(VO, i+1, 1)
306 | b_delta+=1
307 | # remove underline, insert hashes
308 | elif useHash and not hasHash:
309 | if L1[0].isspace():
310 | sp = ''
311 | else:
312 | sp = ' '
313 | if useCloseHash:
314 | Body[bln-1] = '%s%s%s %s' %('#'*lev, sp, L1, '#'*lev)
315 | else:
316 | Body[bln-1] = '%s%s%s' %('#'*lev, sp, L1)
317 | # check if the next line after underline is another underline
318 | if bln+1 < len(Body):
319 | L3 = Body[bln+1].rstrip()
320 | else:
321 | L3 = ''
322 | #print('%s %s %s' %(L1, L2, L3))
323 | # yes: do not delete underline, change it to a blank line
324 | if L3 and (L3.lstrip('=')=='' or L3.lstrip('-')==''):
325 | Body[bln] = ''
326 | # no: delete underline
327 | else:
328 | Body[bln:bln+1] = []
329 | update_bnodes(VO, i+1, -1)
330 | b_delta-=1
331 |
332 | ### Make sure first headline is preceded by a blank line.
333 | blnum1 = bnodes[tlnum1-1]
334 | if blnum1 > 1 and Body[blnum1-2].strip():
335 | Body[blnum1-1:blnum1-1] = ['']
336 | update_bnodes(VO, tlnum1 ,1)
337 | b_delta+=1
338 |
339 | ### After 'down' : insert blank line if there is none
340 | # between the nodes used to be separated by the moved region.
341 | if oop=='down' and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
342 | Body[blnumCut:blnumCut] = ['']
343 | update_bnodes(VO, tlnumCut+1 ,1)
344 | b_delta+=1
345 |
346 | assert len(Body) == Z + b_delta
347 |
348 |
349 | def update_bnodes(VO, tlnum, delta):
350 | """Update VO.bnodes by adding/substracting delta to each bnode
351 | starting with bnode at tlnum and to the end.
352 | """
353 | bnodes = VO.bnodes
354 | for i in xrange(tlnum, len(bnodes)+1):
355 | bnodes[i-1] += delta
356 |
357 |
358 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_paragraphBlank.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_paragraphBlank.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for paragraphs separated by blank lines. The first line of
10 | each paragraph is level 1 headline. That is the first non-blank line and any
11 | non-blank line preceded by a blank line is a headline.
12 |
13 | See |voom-mode-paragraphBlank|, ../../../doc/voom.txt#*voom-mode-paragraphBlank*
14 |
15 | Everything is at level 1. Levels >1 are not possible.
16 |
17 | There are must be a blank line after the last paragraph, that is end-of-file.
18 | Otherwise there are will be errors when the last paragraph is moved.
19 | """
20 |
21 | import sys
22 | if sys.version_info[0] > 2:
23 | xrange = range
24 |
25 | # Disable unsupported outline operations: special node marks, insert new headline as child, move right.
26 | MTYPE = 2
27 |
28 |
29 | def hook_makeOutline(VO, blines):
30 | """Return (tlines, bnodes, levels) for Body lines blines.
31 | blines is either Vim buffer object (Body) or list of buffer lines.
32 | """
33 | # A line is headline level 1 if it is: preceded by a blank line (or is
34 | # first buffer line) and is non-blank.
35 | Z = len(blines)
36 | tlines, bnodes, levels = [], [], []
37 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
38 | bline_ = ''
39 | for i in xrange(Z):
40 | bline = blines[i].strip()
41 | if bline_ or not bline:
42 | bline_ = bline
43 | continue
44 | bline_ = bline
45 | tlines_add(' |%s' %bline)
46 | bnodes_add(i+1)
47 | levels_add(1)
48 | return (tlines, bnodes, levels)
49 |
50 |
51 | def hook_newHeadline(VO, level, blnum, tlnum):
52 | """Return (tree_head, bodyLines).
53 | tree_head is new headline string in Tree buffer (text after |).
54 | bodyLines is list of lines to insert in Body buffer.
55 | """
56 | # Add blank line when inserting after non-blank Body line.
57 | if VO.Body[blnum-1].strip():
58 | return ('NewHeadline', ['', 'NewHeadline', ''])
59 | else:
60 | return ('NewHeadline', ['NewHeadline', ''])
61 |
62 |
63 | ### DO NOT DEFINE THIS HOOK -- level never changes, it is always 1
64 | #def hook_changeLevBodyHead(VO, h, levDelta):
65 | # """Increase of decrease level number of Body headline by levDelta."""
66 | # return h
67 |
68 |
69 | # This is needed to insert blank line missing from end-of-file. Code is from rest mode.
70 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
71 | # this is instead of hook_changeLevBodyHead()
72 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
73 | Body = VO.Body
74 | Z = len(Body)
75 | bnodes = VO.bnodes
76 |
77 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
78 | # during up/down, or promoted/demoted.
79 | if blnum1:
80 | assert blnum1 == bnodes[tlnum1-1]
81 | if tlnum2 < len(bnodes):
82 | assert blnum2 == bnodes[tlnum2]-1
83 | else:
84 | assert blnum2 == Z
85 |
86 | # blnumCut is Body lnum after which a region was removed during 'cut',
87 | # 'up', 'down'. We need to check if there is blank line between nodes
88 | # used to be separated by the cut/moved region to prevent headline loss.
89 | if blnumCut:
90 | if tlnumCut < len(bnodes):
91 | assert blnumCut == bnodes[tlnumCut]-1
92 | else:
93 | assert blnumCut == Z
94 |
95 | # Total number of added lines minus number of deleted lines.
96 | b_delta = 0
97 |
98 | # ### After 'cut' or 'up': insert blank line if there is none
99 | # # between the nodes used to be separated by the cut/moved region.
100 | # if (oop=='cut' or oop=='up') and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
101 | # Body[blnumCut:blnumCut] = ['']
102 | # update_bnodes(VO, tlnumCut+1 ,1)
103 | # b_delta+=1
104 |
105 | if oop=='cut':
106 | return
107 |
108 | ### Prevent loss of headline after last node in the region:
109 | # insert blank line after blnum2 if blnum2 is not blank, that is insert
110 | # blank line before bnode at tlnum2+1.
111 | if blnum2 < Z and Body[blnum2-1].strip():
112 | Body[blnum2:blnum2] = ['']
113 | update_bnodes(VO, tlnum2+1 ,1)
114 | b_delta+=1
115 |
116 | ### Prevent loss of first headline: make sure it is preceded by a blank line
117 | blnum1 = bnodes[tlnum1-1]
118 | if blnum1 > 1 and Body[blnum1-2].strip():
119 | Body[blnum1-1:blnum1-1] = ['']
120 | update_bnodes(VO, tlnum1 ,1)
121 | b_delta+=1
122 |
123 | # ### After 'down' : insert blank line if there is none
124 | # # between the nodes used to be separated by the moved region.
125 | # if oop=='down' and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
126 | # Body[blnumCut:blnumCut] = ['']
127 | # update_bnodes(VO, tlnumCut+1 ,1)
128 | # b_delta+=1
129 |
130 | assert len(Body) == Z + b_delta
131 |
132 |
133 | def update_bnodes(VO, tlnum, delta):
134 | """Update VO.bnodes by adding/substracting delta to each bnode
135 | starting with bnode at tlnum and to the end.
136 | """
137 | bnodes = VO.bnodes
138 | for i in xrange(tlnum, len(bnodes)+1):
139 | bnodes[i-1] += delta
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_paragraphIndent.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_paragraphIndent.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for paragraphs identified by indented lines.
10 | Any non-blank line that starts with a space or tab is a headline.
11 | Everything is at level 1. Levels >1 are not possible.
12 |
13 | See |voom-mode-paragraphIndent|, ../../../doc/voom.txt#*voom-mode-paragraphIndent*
14 | """
15 |
16 | import sys
17 | if sys.version_info[0] > 2:
18 | xrange = range
19 |
20 | # Disable unsupported outline operations: special node marks, insert new headline as child, move right.
21 | MTYPE = 2
22 |
23 | whitespace = ('\t', ' ')
24 |
25 | def hook_makeOutline(VO, blines):
26 | """Return (tlines, bnodes, levels) for Body lines blines.
27 | blines is either Vim buffer object (Body) or list of buffer lines.
28 | """
29 | # every line that doesn't start with a space or tab is level 1 headline
30 | Z = len(blines)
31 | tlines, bnodes, levels = [], [], []
32 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
33 | for i in xrange(Z):
34 | bline = blines[i]
35 | if not bline or not (bline[0] in whitespace): # THE ONLY DIFFERENCE FROM voom_mode_paragraphNoIndent.py
36 | continue
37 | bline = bline.strip()
38 | if not bline:
39 | continue
40 | tlines_add(' |%s' %bline)
41 | bnodes_add(i+1)
42 | levels_add(1)
43 | return (tlines, bnodes, levels)
44 |
45 |
46 | def hook_newHeadline(VO, level, blnum, tlnum):
47 | """Return (tree_head, bodyLines).
48 | tree_head is new headline string in Tree buffer (text after |).
49 | bodyLines is list of lines to insert in Body buffer.
50 | """
51 | # inserting after another headline: use indent of previous body headline
52 | if tlnum > 1:
53 | bheadline = VO.Body[VO.bnodes[tlnum-1]-1] # previous Body headline
54 | idx = len(bheadline) - len(bheadline.lstrip())
55 | indent = bheadline[: idx]
56 | # inserting as first headline and there are other headlines: use indent of next headline
57 | elif len(VO.bnodes) > 1:
58 | bheadline = VO.Body[VO.bnodes[tlnum]-1] # next Body headline
59 | idx = len(bheadline) - len(bheadline.lstrip())
60 | indent = bheadline[: idx]
61 | else:
62 | indent = ' '
63 | return ('NewHeadline', ['%sNewHeadline' %indent])
64 |
65 |
66 | ### DO NOT DEFINE THIS HOOK -- level never changes, it is always 1
67 | #def hook_changeLevBodyHead(VO, h, levDelta):
68 | # """Increase of decrease level number of Body headline by levDelta."""
69 | # return h
70 |
71 |
72 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_paragraphNoIndent.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_paragraphNoIndent.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for paragraphs identified by non-indented lines.
10 | Any line that starts with a character other than space or tab is a headline.
11 | Everything is at level 1. Levels >1 are not possible.
12 |
13 | See |voom-mode-paragraphNoIndent|, ../../../doc/voom.txt#*voom-mode-paragraphNoIndent*
14 | """
15 |
16 | import sys
17 | if sys.version_info[0] > 2:
18 | xrange = range
19 |
20 | # Disable unsupported outline operations: special node marks, insert new headline as child, move right.
21 | MTYPE = 2
22 |
23 | whitespace = ('\t', ' ')
24 |
25 | def hook_makeOutline(VO, blines):
26 | """Return (tlines, bnodes, levels) for Body lines blines.
27 | blines is either Vim buffer object (Body) or list of buffer lines.
28 | """
29 | # every line that doesn't start with a space or tab is level 1 headline
30 | Z = len(blines)
31 | tlines, bnodes, levels = [], [], []
32 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
33 | for i in xrange(Z):
34 | bline = blines[i]
35 | if not bline or bline[0] in whitespace: # THE ONLY DIFFERENCE FROM voom_mode_paragraphIndent.py
36 | continue
37 | bline = bline.strip()
38 | if not bline:
39 | continue
40 | tlines_add(' |%s' %bline)
41 | bnodes_add(i+1)
42 | levels_add(1)
43 | return (tlines, bnodes, levels)
44 |
45 |
46 | def hook_newHeadline(VO, level, blnum, tlnum):
47 | """Return (tree_head, bodyLines).
48 | tree_head is new headline string in Tree buffer (text after |).
49 | bodyLines is list of lines to insert in Body buffer.
50 | """
51 | return ('NewHeadline', ['NewHeadline'])
52 |
53 |
54 | ### DO NOT DEFINE THIS HOOK -- level never changes, it is always 1
55 | #def hook_changeLevBodyHead(VO, h, levDelta):
56 | # """Increase of decrease level number of Body headline by levDelta."""
57 | # return h
58 |
59 |
60 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_python.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_python.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for Python code.
10 | See |voom-mode-python|, ../../../doc/voom.txt#*voom-mode-python*
11 | """
12 |
13 | import sys
14 | if sys.version_info[0] > 2:
15 | xrange = range
16 |
17 | import token, tokenize
18 | import traceback
19 | import vim
20 |
21 |
22 | def hook_makeOutline(VO, blines):
23 | """Return (tlines, bnodes, levels) for Body lines blines.
24 | blines is either Vim buffer object (Body) or list of buffer lines.
25 | """
26 | Z = len(blines)
27 | tlines, bnodes, levels = [], [], []
28 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
29 |
30 | #ignore_lnums, func_lnums = get_lnums_from_tokenize(blines)
31 | try:
32 | ignore_lnums, func_lnums = get_lnums_from_tokenize(blines)
33 | except (IndentationError, tokenize.TokenError):
34 | vim.command("call voom#ErrorMsg('VOoM: EXCEPTION WHILE PARSING PYTHON OUTLINE')")
35 | # DO NOT print to sys.stderr -- triggers Vim error when default stderr (no PyLog)
36 | #traceback.print_exc() --this goes to sys.stderr
37 | #print traceback.format_exc() --ok but no highlighting
38 | lines = traceback.format_exc().replace("'","''").split('\n')
39 | for ln in lines:
40 | vim.command("call voom#ErrorMsg('%s')" %ln)
41 | return (['= |!!!ERROR: OUTLINE IS INVALID'], [1], [1])
42 |
43 | isHead = False # True if current line is a headline
44 | indents = [0,] # indents of previous levels
45 | funcLevels = [] # levels of previous def or class
46 | indentError = '' # inconsistent indent
47 | isDecor = 0 # keeps track of decorators, set to lnum of the first decorator
48 | X = ' ' # char in Tree's column 2 (marks)
49 | for i in xrange(Z):
50 | bnode = i + 1
51 | if bnode in ignore_lnums: continue
52 | bline = blines[i]
53 | bline_s = bline.strip()
54 | if not bline_s: continue
55 | if bline_s.startswith('#'):
56 | # ignore comment lines consisting only of #, -, =, spaces, tabs (separators, pretty headers)
57 | if not bline_s.lstrip('# \t-='): continue
58 | isComment = True
59 | else:
60 | isComment = False
61 | bline_ls = bline.lstrip()
62 |
63 | # compute indent and level
64 | indent = len(bline) - len(bline_ls)
65 | if indent > indents[-1]:
66 | indents.append(indent)
67 | elif indent < indents[-1]:
68 | while indents and (indents[-1] > indent):
69 | indents.pop()
70 | if indents[-1]==indent:
71 | indentError = ''
72 | else:
73 | indentError = '!!! '
74 | lev = len(indents)
75 |
76 | # First line after the end of a class or def block.
77 | if funcLevels and lev <= funcLevels[-1]:
78 | isHead = True
79 | while funcLevels and funcLevels[-1] >= lev:
80 | funcLevels.pop()
81 | # First line of a class or def block.
82 | if bnode in func_lnums:
83 | isHead = True
84 | if isDecor:
85 | bnode = isDecor
86 | isDecor = 0
87 | X = 'd'
88 | if not funcLevels or (lev > funcLevels[-1]):
89 | funcLevels.append(lev)
90 | # Line after a decorator. Not a def or class.
91 | elif isDecor:
92 | # ingore valid lines between the first decorator and function/class
93 | if bline_s.startswith('@') or isComment or not bline_s:
94 | isHead = False
95 | continue
96 | # Invalid line after a decorator (should be syntax error): anything
97 | # other than another decorator, comment, blank line, def/class.
98 | # If it looks like a headline, let it be a headline.
99 | else:
100 | isDecor = 0
101 | # Decorator line (the first one if a group of several).
102 | elif bline_s.startswith('@'):
103 | isDecor = bnode
104 | isHead = False
105 | continue
106 | # Special comment line (unconditional headline). Not a separator or pretty header line.
107 | elif isComment:
108 | if bline_s.startswith('###') or bline_s.startswith('#--') or bline_s.startswith('#=='):
109 | isHead = True
110 |
111 | if isHead:
112 | ##########################################
113 | # Take care of pretty headers like this. #
114 | ##########################################
115 | if isComment:
116 | # add preceding lines to the current node if they consist only of #, =, -, whitespace
117 | while bnode > 1:
118 | bline_p = blines[bnode-2].lstrip()
119 | if not bline_p.startswith('#') or bline_p.lstrip('# \t-='):
120 | break
121 | else:
122 | bnode -= 1
123 | # the end
124 | isHead = False
125 | tline = ' %s%s|%s%s' %(X, '. '*(lev-1), indentError, bline_s)
126 | X = ' '
127 | tlines_add(tline)
128 | bnodes_add(bnode)
129 | levels_add(lev)
130 |
131 | return (tlines, bnodes, levels)
132 |
133 |
134 | class BLines:
135 | """Wrapper around Vim buffer object or list of Body lines to provide
136 | readline() method for use with tokenize.generate_tokens().
137 | """
138 | def __init__(self, blines):
139 | self.blines = blines
140 | self.size = len(blines)
141 | self.idx = -1
142 |
143 | def readline(self):
144 | self.idx += 1
145 | if self.idx == self.size:
146 | return ''
147 | return "%s\n" %self.blines[self.idx]
148 |
149 |
150 | ### toktypes of tokens
151 | STRING = token.STRING
152 | NAME = token.NAME
153 | NEWLINE = token.NEWLINE
154 |
155 | def get_lnums_from_tokenize(blines):
156 | """Return dicts. Keys are Body lnums.
157 | The main purpose is to get list of lnums to ignore: multi-line strings and
158 | expressions.
159 | """
160 | # lnums to ignore: multi-line strings and expressions other than the first line
161 | ignore_lnums = {}
162 | # lnums of 'class' and 'def' tokens
163 | func_lnums = {}
164 |
165 | inName = False
166 |
167 | for tok in tokenize.generate_tokens(BLines(blines).readline):
168 | toktype, toktext, (srow, scol), (erow, ecol), line = tok
169 | #print('token.tok_name[toktype]=%s tok=%s' %(token.tok_name[toktype], tok))
170 | if toktype == NAME:
171 | if not inName:
172 | inName = True
173 | srow_name = srow
174 | if toktext in ('def','class'):
175 | func_lnums[srow] = toktext
176 | elif toktype == NEWLINE and inName:
177 | inName = False
178 | if srow_name != erow:
179 | for i in xrange(srow_name+1, erow+1):
180 | ignore_lnums[i] = 0
181 | elif toktype == STRING:
182 | if srow != erow:
183 | for i in xrange(srow+1, erow+1):
184 | ignore_lnums[i] = 0
185 |
186 | return (ignore_lnums, func_lnums)
187 |
188 |
189 | def get_body_indent(body):
190 | """Return string used for indenting Body lines."""
191 | et = int(vim.eval("getbufvar(%s,'&et')" %body))
192 | if et:
193 | ts = int(vim.eval("getbufvar(%s,'&ts')" %body))
194 | return ' '*ts
195 | else:
196 | return '\t'
197 |
198 |
199 | def hook_newHeadline(VO, level, blnum, tlnum):
200 | """Return (tree_head, bodyLines).
201 | tree_head is new headline string in Tree buffer (text after |).
202 | bodyLines is list of lines to insert in Body buffer.
203 | """
204 | tree_head = '### NewHeadline'
205 | indent = get_body_indent(VO.body)
206 | body_head = '%s%s' %(indent*(level-1), tree_head)
207 | return (tree_head, [body_head])
208 |
209 |
210 | #def hook_changeLevBodyHead(VO, h, levDelta):
211 | #"""Increase of decrease level number of Body headline by levDelta."""
212 | #if levDelta==0: return h
213 |
214 |
215 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
216 | # this is instead of hook_changeLevBodyHead()
217 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
218 | Body = VO.Body
219 | Z = len(Body)
220 |
221 | ind = get_body_indent(VO.body)
222 | # levDelta is wrong when pasting because hook_makeOutline() looks at relative indent
223 | # determine level of pasted region from indent of its first line
224 | if oop=='paste':
225 | bline1 = Body[blnum1-1]
226 | lev = int((len(bline1) - len(bline1.lstrip())) / len(ind)) + 1
227 | levDelta = VO.levels[tlnum1-1] - lev
228 |
229 | if not levDelta: return
230 |
231 | indent = abs(levDelta) * ind
232 | #--- copied from voom_mode_thevimoutliner.py -----------------------------
233 | if blnum1:
234 | assert blnum1 == VO.bnodes[tlnum1-1]
235 | if tlnum2 < len(VO.bnodes):
236 | assert blnum2 == VO.bnodes[tlnum2]-1
237 | else:
238 | assert blnum2 == Z
239 |
240 | # dedent (if possible) or indent every non-blank line in Body region blnum1,blnum2
241 | blines = []
242 | for i in xrange(blnum1-1,blnum2):
243 | line = Body[i]
244 | if not line.strip():
245 | blines.append(line)
246 | continue
247 | if levDelta > 0:
248 | line = '%s%s' %(indent,line)
249 | elif levDelta < 0 and line.startswith(indent):
250 | line = line[len(indent):]
251 | blines.append(line)
252 |
253 | # replace Body region
254 | Body[blnum1-1:blnum2] = blines
255 | assert len(Body)==Z
256 |
257 |
258 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_rest.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_rest.py
2 | # Last Modified: 2016-08-20
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for reStructuredText.
10 | See |voom-mode-rest|, ../../../doc/voom.txt#*voom-mode-rest*
11 |
12 | http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections
13 | The following are all valid section title adornment characters:
14 | ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
15 |
16 | Some characters are more suitable than others. The following are recommended:
17 | = - ` : . ' " ~ ^ _ * + #
18 |
19 | http://docs.python.org/documenting/rest.html#sections
20 | Python recommended styles: ## ** = - ^ "
21 | """
22 |
23 | import sys
24 | if sys.version_info[0] > 2:
25 | xrange = range
26 | def len_u(s, enc):
27 | return len(s)
28 | else:
29 | def len_u(s, enc):
30 | return len(unicode(s, enc, 'replace'))
31 |
32 |
33 | # All valid section title adornment characters.
34 | AD_CHARS = """ ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ """
35 | AD_CHARS = AD_CHARS.split()
36 |
37 | # List of adornment styles, in order of preference.
38 | # Adornment style (ad) is a char or double char: '=', '==', '-', '--', '*', etc.
39 | # Char is adornment char, double if there is overline.
40 | AD_STYLES = """ == -- = - * " ' ` ~ : ^ + # . _ """
41 | AD_STYLES = AD_STYLES.split()
42 |
43 | # add all other possible styles to AD_STYLES
44 | d = {}.fromkeys(AD_STYLES)
45 | for c in AD_CHARS:
46 | if not c*2 in d:
47 | AD_STYLES.append(c*2)
48 | if not c in d:
49 | AD_STYLES.append(c)
50 | assert len(AD_STYLES)==64
51 |
52 | # convert AD_CHARS to dict for faster lookups
53 | AD_CHARS = {}.fromkeys(AD_CHARS)
54 |
55 |
56 | def hook_makeOutline(VO, blines):
57 | """Return (tlines, bnodes, levels) for Body lines blines.
58 | blines is either Vim buffer object (Body) or list of buffer lines.
59 | """
60 | Z = len(blines)
61 | tlines, bnodes, levels = [], [], []
62 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
63 | ENC = VO.enc
64 |
65 | # {adornment style: level, ...}
66 | # Level indicates when the first instance of this style was found.
67 | ads_levels = {}
68 |
69 | # diagram of Body lines when a headline is detected
70 | # trailing whitespace always removed with rstrip()
71 | # a b c
72 | # ------ L3, blines[i-2] -- an overline or a blank line
73 | # head L2, blines[i-1] -- title line, not blank, <= than underline, can be inset only if overline
74 | # ------ L1, blines[i] -- current line, always an underline
75 | # x y z
76 | L1, L2, L3 = '','',''
77 |
78 | # An underline can be only the 2nd or 3rd line of a block after a blank
79 | # line or previous underline. Thus, index of the next underline must be ok or ok+1.
80 | ok = 1
81 | isHead = False
82 | for i in xrange(Z):
83 | L2, L3 = L1, L2
84 | L1 = blines[i].rstrip()
85 | if not L1:
86 | ok = i+2
87 | continue
88 | if i < ok or not L2:
89 | continue
90 | # At this point both the current line (underline) and previous line (title) are not blank.
91 |
92 | # current line must be an underline
93 | if not ((L1[0] in AD_CHARS) and L1.lstrip(L1[0])==''):
94 | if i > ok: ok = Z
95 | continue
96 | # underline must be as long as headline text
97 | if len(L1) < len_u(L2, ENC):
98 | if i > ok: ok = Z
99 | continue
100 | head = L2.lstrip()
101 | # headline text cannot look like an underline unless it's shorter than underline
102 | if (head[0] in AD_CHARS) and head.lstrip(head[0])=='' and len(head)==len(L1):
103 | if i > ok: ok = Z
104 | continue
105 | # there is no overline; L3 must be blank line; L2 must be not inset
106 | if not L3 and len(L2)==len(head):
107 | #if len(L1) < len_u(L2, ENC): continue
108 | isHead = True
109 | ad = L1[0]
110 | bnode = i
111 | # there is overline -- bnode is lnum of overline!
112 | elif L3==L1:
113 | #if len(L1) < len_u(L2, ENC): continue
114 | isHead = True
115 | ad = L1[0]*2
116 | bnode = i-1
117 | else:
118 | if i > ok: ok = Z
119 | continue
120 |
121 | if isHead:
122 | if not ad in ads_levels:
123 | ads_levels[ad] = len(ads_levels)+1
124 | lev = ads_levels[ad]
125 | isHead = False
126 | L1, L2, L3 = '','',''
127 | ok = i+2
128 |
129 | tline = ' %s|%s' %('. '*(lev-1), head)
130 | tlines_add(tline)
131 | bnodes_add(bnode)
132 | levels_add(lev)
133 |
134 | # save ads_levels for outline operations
135 | # don't clobber VO.ads_levels when parsing clipboard during Paste
136 | # which is the only time blines is not Body
137 | if blines is VO.Body:
138 | VO.ads_levels = ads_levels
139 |
140 | return (tlines, bnodes, levels)
141 |
142 |
143 | def hook_newHeadline(VO, level, blnum, tlnum):
144 | """Return (tree_head, bodyLines).
145 | tree_head is new headline string in Tree buffer (text after |).
146 | bodyLines is list of lines to insert in Body buffer.
147 | """
148 | tree_head = 'NewHeadline'
149 | ads_levels = VO.ads_levels
150 | levels_ads = dict([[v,k] for k,v in ads_levels.items()])
151 |
152 | if level in levels_ads:
153 | ad = levels_ads[level]
154 | else:
155 | ad = get_new_ad(levels_ads, ads_levels, level)
156 |
157 | if len(ad)==1:
158 | bodyLines = [tree_head, ad*11, '']
159 | elif len(ad)==2:
160 | ad = ad[0]
161 | bodyLines = [ad*11, tree_head, ad*11, '']
162 |
163 | # Add blank line when inserting after non-blank Body line.
164 | if VO.Body[blnum-1].strip():
165 | bodyLines[0:0] = ['']
166 |
167 | return (tree_head, bodyLines)
168 |
169 |
170 | #def hook_changeLevBodyHead(VO, h, levDelta):
171 | # DO NOT CREATE THIS HOOK
172 |
173 |
174 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
175 | # this is instead of hook_changeLevBodyHead()
176 | #print('oop=%s levDelta=%s blnum1=%s tlnum1=%s blnum2=%s tlnum2=%s tlnumCut=%s blnumCut=%s' % (oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, tlnumCut, blnumCut))
177 | Body = VO.Body
178 | Z = len(Body)
179 | bnodes, levels = VO.bnodes, VO.levels
180 | ENC = VO.enc
181 |
182 | # blnum1 blnum2 is first and last lnums of Body region pasted, inserted
183 | # during up/down, or promoted/demoted.
184 | if blnum1:
185 | assert blnum1 == bnodes[tlnum1-1]
186 | if tlnum2 < len(bnodes):
187 | assert blnum2 == bnodes[tlnum2]-1
188 | else:
189 | assert blnum2 == Z
190 |
191 | # blnumCut is Body lnum after which a region was removed during 'cut',
192 | # 'up', 'down'. We need to check if there is blank line between nodes
193 | # used to be separated by the cut/moved region to prevent headline loss.
194 | if blnumCut:
195 | if tlnumCut < len(bnodes):
196 | assert blnumCut == bnodes[tlnumCut]-1
197 | else:
198 | assert blnumCut == Z
199 |
200 | # Total number of added lines minus number of deleted lines.
201 | b_delta = 0
202 |
203 | ### After 'cut' or 'up': insert blank line if there is none
204 | # between the nodes used to be separated by the cut/moved region.
205 | if (oop=='cut' or oop=='up') and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
206 | Body[blnumCut:blnumCut] = ['']
207 | update_bnodes(VO, tlnumCut+1 ,1)
208 | b_delta+=1
209 |
210 | if oop=='cut':
211 | return
212 |
213 | ### Prevent loss of headline after last node in the region:
214 | # insert blank line after blnum2 if blnum2 is not blank, that is insert
215 | # blank line before bnode at tlnum2+1.
216 | if blnum2 < Z and Body[blnum2-1].strip():
217 | Body[blnum2:blnum2] = ['']
218 | update_bnodes(VO, tlnum2+1 ,1)
219 | b_delta+=1
220 |
221 | ### Change levels and/or styles of headlines in the affected region.
222 | # Always do this after Paste, even if level is unchanged -- adornments can
223 | # be different when pasting from other outlines.
224 | # Examine each headline, from bottom to top, and change adornment style.
225 | # To change from underline to overline style:
226 | # insert overline.
227 | # To change from overline to underline style:
228 | # delete overline if there is blank before it;
229 | # otherwise change overline to blank line;
230 | # remove inset from headline text.
231 | # Update bnodes after inserting or deleting a line.
232 | if levDelta or oop=='paste':
233 | ads_levels = VO.ads_levels
234 | levels_ads = dict([[v,k] for k,v in ads_levels.items()])
235 | # Add adornment styles for new levels. Can't do this in the main loop
236 | # because it goes backwards and thus will add styles in reverse order.
237 | for i in xrange(tlnum1, tlnum2+1):
238 | lev = levels[i-1]
239 | if not lev in levels_ads:
240 | ad = get_new_ad(levels_ads, ads_levels, lev)
241 | levels_ads[lev] = ad
242 | ads_levels[ad] = lev
243 | for i in xrange(tlnum2, tlnum1-1, -1):
244 | # required level (VO.levels has been updated)
245 | lev = levels[i-1]
246 | # required adornment style
247 | ad = levels_ads[lev]
248 |
249 | # deduce current adornment style
250 | bln = bnodes[i-1]
251 | L1 = Body[bln-1].rstrip()
252 | L2 = Body[bln].rstrip()
253 | if bln+1 < len(Body):
254 | L3 = Body[bln+1].rstrip()
255 | else:
256 | L3 = ''
257 | ad_ = deduce_ad_style(L1,L2,L3,ENC)
258 |
259 | # change adornment style
260 | # see deduce_ad_style() for diagram
261 | if ad_==ad:
262 | continue
263 | elif len(ad_)==1 and len(ad)==1:
264 | Body[bln] = ad*len(L2)
265 | elif len(ad_)==2 and len(ad)==2:
266 | Body[bln-1] = ad[0]*len(L1)
267 | Body[bln+1] = ad[0]*len(L3)
268 | elif len(ad_)==1 and len(ad)==2:
269 | # change underline if different
270 | if not ad_ == ad[0]:
271 | Body[bln] = ad[0]*len(L2)
272 | # insert overline; current bnode doesn't change
273 | Body[bln-1:bln-1] = [ad[0]*len(L2)]
274 | update_bnodes(VO, i+1, 1)
275 | b_delta+=1
276 | elif len(ad_)==2 and len(ad)==1:
277 | # change underline if different
278 | if not ad_[0] == ad:
279 | Body[bln+1] = ad*len(L3)
280 | # remove headline inset if any
281 | if not len(L2) == len(L2.lstrip()):
282 | Body[bln] = L2.lstrip()
283 | # check if line before overline is blank
284 | if bln >1:
285 | L0 = Body[bln-2].rstrip()
286 | else:
287 | L0 = ''
288 | # there is blank before overline
289 | # delete overline; current bnode doesn't change
290 | if not L0:
291 | Body[bln-1:bln] = []
292 | update_bnodes(VO, i+1, -1)
293 | b_delta-=1
294 | # there is no blank before overline
295 | # change overline to blank; only current bnode needs updating
296 | else:
297 | Body[bln-1] = ''
298 | bnodes[i-1]+=1
299 |
300 | ### Prevent loss of first headline: make sure it is preceded by a blank line
301 | blnum1 = bnodes[tlnum1-1]
302 | if blnum1 > 1 and Body[blnum1-2].strip():
303 | Body[blnum1-1:blnum1-1] = ['']
304 | update_bnodes(VO, tlnum1 ,1)
305 | b_delta+=1
306 |
307 | ### After 'down' : insert blank line if there is none
308 | # between the nodes used to be separated by the moved region.
309 | if oop=='down' and (0 < blnumCut < Z) and Body[blnumCut-1].strip():
310 | Body[blnumCut:blnumCut] = ['']
311 | update_bnodes(VO, tlnumCut+1 ,1)
312 | b_delta+=1
313 |
314 | assert len(Body) == Z + b_delta
315 |
316 |
317 | def update_bnodes(VO, tlnum, delta):
318 | """Update VO.bnodes by adding/substracting delta to each bnode
319 | starting with bnode at tlnum and to the end.
320 | """
321 | bnodes = VO.bnodes
322 | for i in xrange(tlnum, len(bnodes)+1):
323 | bnodes[i-1] += delta
324 |
325 |
326 | def get_new_ad(levels_ads, ads_levels, level):
327 | """Return adornment style for new level, that is level missing from
328 | levels_ads and ads_levels.
329 | """
330 | for ad in AD_STYLES:
331 | if not ad in ads_levels:
332 | return ad
333 | # all 64 adornment styles are in use, return style for level 64
334 | assert len(levels_ads)==64
335 | return levels_ads[64]
336 |
337 |
338 | def deduce_ad_style(L1,L2,L3,ENC):
339 | """Deduce adornment style given first 3 lines of Body node.
340 | 1st line is bnode line. Lines must be rstripped. L1 and L2 are not blank.
341 | """
342 | # '--' style '-' style
343 | #
344 | # L0 L0 Body[bln-2]
345 | # ---- L1 head L1 <--bnode Body[bln-1]
346 | # head L2 ---- L2 Body[bln]
347 | # ---- L3 text L3 Body[bln+1]
348 |
349 | # bnode is headline text, L2 is underline
350 | if (L2[0] in AD_CHARS) and L2.lstrip(L2[0])=='' and (len(L2) >= len_u(L1, ENC)):
351 | ad = L2[0]
352 | # bnode is overline
353 | elif L1==L3 and (L1[0] in AD_CHARS) and L1.lstrip(L1[0])=='' and (len(L1) >= len_u(L2, ENC)):
354 | ad = 2*L1[0]
355 | else:
356 | print(L1)
357 | print(L2)
358 | print(L3)
359 | print(ENC)
360 | assert None
361 |
362 | return ad
363 |
364 |
365 | def test_deduce_ad_style(VO):
366 | """ A test to verify deduce_ad_style(). Execute from Vim
367 | :py _VOoM2657.VOOMS[1].mModule.test_deduce_ad_style(_VOoM2657.VOOMS[1])
368 | """
369 | bnodes, levels, Body = VO.bnodes, VO.levels, VO.Body
370 | ads_levels = VO.ads_levels
371 | levels_ads = dict([[v,k] for k,v in ads_levels.items()])
372 | ENC = VO.enc
373 |
374 | for i in xrange(2, len(bnodes)+1):
375 | bln = bnodes[i-1]
376 | L1 = Body[bln-1].rstrip()
377 | L2 = Body[bln].rstrip()
378 | if bln+1 < len(Body):
379 | L3 = Body[bln+1].rstrip()
380 | else:
381 | L3 = ''
382 | ad = deduce_ad_style(L1,L2,L3,ENC)
383 | lev = levels[i-1]
384 | print('%s %s %s' %(i, ad, levels_ads[lev]))
385 | assert ad == levels_ads[lev]
386 |
387 |
388 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_taskpaper.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_taskpaper.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for TaskPaper format.
10 | See |voom-mode-taskpaper|, ../../../doc/voom.txt#*voom-mode-taskpaper*
11 | """
12 |
13 | import sys
14 | if sys.version_info[0] > 2:
15 | xrange = range
16 |
17 | import re
18 | # match for Project line, as in syntax/taskpaper.vim
19 | project_match = re.compile(r'^.+:(\s+@[^ \t(]+(\([^)]*\))?)*$').match
20 |
21 | def hook_makeOutline(VO, blines):
22 | """Return (tlines, bnodes, levels) for Body lines blines.
23 | blines is either Vim buffer object (Body) or list of buffer lines.
24 | """
25 | Z = len(blines)
26 | tlines, bnodes, levels = [], [], []
27 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
28 | for i in xrange(Z):
29 | bline = blines[i]
30 | h = bline.lstrip('\t')
31 | # line is a Task
32 | if h.startswith('- '):
33 | head = h[2:]
34 | mark = ' '
35 | # line is a Project
36 | # the "in" test is for efficiency sake in case there is lots of Notes
37 | elif h.endswith(':') or (':' in h and project_match(h)):
38 | head = h
39 | mark = 'x'
40 | else:
41 | continue
42 | lev = len(bline) - len(h) + 1
43 |
44 | tline = ' %s%s|%s' %(mark, '. '*(lev-1), head)
45 | tlines_add(tline)
46 | bnodes_add(i+1)
47 | levels_add(lev)
48 | return (tlines, bnodes, levels)
49 |
50 |
51 | def hook_newHeadline(VO, level, blnum, tlnum):
52 | """Return (tree_head, bodyLines).
53 | tree_head is new headline string in Tree buffer (text after |).
54 | bodyLines is list of lines to insert in Body buffer.
55 | """
56 | tree_head = 'NewHeadline'
57 | bodyLines = ['%s- %s' %('\t'*(level-1), tree_head),]
58 | return (tree_head, bodyLines)
59 |
60 |
61 | # ---- The rest is identical to vimoutliner/thevimoutliner modes. -----------
62 |
63 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
64 | # this is instead of hook_changeLevBodyHead()
65 | if not levDelta: return
66 |
67 | indent = abs(levDelta) * '\t'
68 |
69 | Body = VO.Body
70 | Z = len(Body)
71 |
72 | # ---- identical to voom_mode_python.py code ----------------------------
73 | if blnum1:
74 | assert blnum1 == VO.bnodes[tlnum1-1]
75 | if tlnum2 < len(VO.bnodes):
76 | assert blnum2 == VO.bnodes[tlnum2]-1
77 | else:
78 | assert blnum2 == Z
79 |
80 | # dedent (if possible) or indent every non-blank line in Body region blnum1,blnum2
81 | blines = []
82 | for i in xrange(blnum1-1,blnum2):
83 | line = Body[i]
84 | if not line.strip():
85 | blines.append(line)
86 | continue
87 | if levDelta > 0:
88 | line = '%s%s' %(indent,line)
89 | elif levDelta < 0 and line.startswith(indent):
90 | line = line[len(indent):]
91 | blines.append(line)
92 |
93 | # replace Body region
94 | Body[blnum1-1:blnum2] = blines
95 | assert len(Body)==Z
96 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_thevimoutliner.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_thevimoutliner.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for The Vim Outliner format.
10 | See |voom-mode-thevimoutliner|, ../../../doc/voom.txt#*voom-mode-thevimoutliner*
11 |
12 | Headlines and body lines are indented with Tabs. Number of tabs indicates
13 | level. 0 Tabs means level 1.
14 |
15 | Headlines are lines with >=0 Tabs followed by any character except '|'.
16 |
17 | Blank lines are not headlines.
18 | """
19 |
20 | import sys
21 | if sys.version_info[0] > 2:
22 | xrange = range
23 |
24 | # Body lines start with these chars
25 | BODY_CHARS = {'|':0,}
26 |
27 | # ------ the rest is identical to voom_mode_vimoutliner.py -------------------
28 | def hook_makeOutline(VO, blines):
29 | """Return (tlines, bnodes, levels) for Body lines blines.
30 | blines is either Vim buffer object (Body) or list of buffer lines.
31 | """
32 | Z = len(blines)
33 | tlines, bnodes, levels = [], [], []
34 | tlines_add, bnodes_add, levels_add = tlines.append, bnodes.append, levels.append
35 | for i in xrange(Z):
36 | bline = blines[i].rstrip()
37 | if not bline:
38 | continue
39 | head = bline.lstrip('\t')
40 | if head[0] in BODY_CHARS:
41 | continue
42 | lev = len(bline) - len(head) + 1
43 |
44 | tline = ' %s|%s' %('. '*(lev-1), head)
45 | tlines_add(tline)
46 | bnodes_add(i+1)
47 | levels_add(lev)
48 | return (tlines, bnodes, levels)
49 |
50 |
51 | def hook_newHeadline(VO, level, blnum, tlnum):
52 | """Return (tree_head, bodyLines).
53 | tree_head is new headline string in Tree buffer (text after |).
54 | bodyLines is list of lines to insert in Body buffer.
55 | """
56 | tree_head = 'NewHeadline'
57 | bodyLines = ['%s%s' %('\t'*(level-1), tree_head),]
58 | return (tree_head, bodyLines)
59 |
60 |
61 | #def hook_changeLevBodyHead(VO, h, levDelta):
62 | #"""Increase of decrease level number of Body headline by levDelta."""
63 | #if levDelta==0: return h
64 |
65 | def hook_doBodyAfterOop(VO, oop, levDelta, blnum1, tlnum1, blnum2, tlnum2, blnumCut, tlnumCut):
66 | # this is instead of hook_changeLevBodyHead()
67 | if not levDelta: return
68 |
69 | indent = abs(levDelta) * '\t'
70 |
71 | Body = VO.Body
72 | Z = len(Body)
73 |
74 | # ---- identical to voom_mode_python.py code ----------------------------
75 | if blnum1:
76 | assert blnum1 == VO.bnodes[tlnum1-1]
77 | if tlnum2 < len(VO.bnodes):
78 | assert blnum2 == VO.bnodes[tlnum2]-1
79 | else:
80 | assert blnum2 == Z
81 |
82 | # dedent (if possible) or indent every non-blank line in Body region blnum1,blnum2
83 | blines = []
84 | for i in xrange(blnum1-1,blnum2):
85 | line = Body[i]
86 | if not line.strip():
87 | blines.append(line)
88 | continue
89 | if levDelta > 0:
90 | line = '%s%s' %(indent,line)
91 | elif levDelta < 0 and line.startswith(indent):
92 | line = line[len(indent):]
93 | blines.append(line)
94 |
95 | # replace Body region
96 | Body[blnum1-1:blnum2] = blines
97 | assert len(Body)==Z
98 |
--------------------------------------------------------------------------------
/autoload/voom/voom_vimplugin2657/voom_mode_txt2tags.py:
--------------------------------------------------------------------------------
1 | # File: voom_mode_txt2tags.py
2 | # Last Modified: 2017-01-07
3 | # Description: VOoM -- two-pane outliner plugin for Python-enabled Vim
4 | # Website: http://www.vim.org/scripts/script.php?script_id=2657
5 | # Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
6 | # License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/
7 |
8 | """
9 | VOoM markup mode for txt2tags titles.
10 | See |voom-mode-txt2tags|, ../../../doc/voom.txt#*voom-mode-txt2tags*
11 | """
12 |
13 | import sys
14 | if sys.version_info[0] > 2:
15 | xrange = range
16 |
17 | import re
18 | # headline regexps from txt2tags.py:
19 | # titskel = r'^ *(?P%s)(?P%s)\1(\[(?P