-
Notifications
You must be signed in to change notification settings - Fork 15
/
orgdynamicblock.py
97 lines (89 loc) · 3.2 KB
/
orgdynamicblock.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import sublime
import sublime_plugin
import datetime
import re
from pathlib import Path
import os
import fnmatch
import OrgExtended.orgparse.node as node
from OrgExtended.orgparse.sublimenode import *
import OrgExtended.orgutil.util as util
import OrgExtended.orgutil.navigation as nav
import OrgExtended.orgutil.template as templateEngine
import logging
import sys
import traceback
import OrgExtended.orgfolding as folding
import OrgExtended.orgdb as db
import OrgExtended.asettings as sets
import OrgExtended.orgcapture as capture
import OrgExtended.orglinks as links
import OrgExtended.orgclocking as clocking
import OrgExtended.orgextension as ext
import OrgExtended.pymitter as evt
from OrgExtended.orgplist import *
import importlib
log = logging.getLogger(__name__)
RE_END = re.compile(r"^\s*\#\+(END|end)[:]")
RE_DYN_BLOCK = re.compile(r"^\s*\#\+(BEGIN|begin)[:]\s+(?P<name>[^: ]+)\s*")
RE_FN_MATCH = re.compile(r"\s+[:]([a-zA-Z][a-zA-Z0-9-_]+)\s+(([^ ()]+)|([(][^)]+[)]))")
def IsDynamicBlock(view):
line = view.getLine(view.curRow())
return RE_DYN_BLOCK.search(line) or RE_END.search(line)
class OrgExecuteDynamicBlockCommand(sublime_plugin.TextCommand):
def on_replaced(self):
if(hasattr(self.curmod,"PostExecute")):
self.curmod.PostExecute(self.view, self.params, self.region)
def run(self, edit):
view = self.view
at = view.sel()[0]
if(view.match_selector(at.begin(),'orgmode.fence.dynamicblock')):
# Okay we have a dynamic block, now we need to know where it ends.
start = at.begin()
end = None
erow = view.endRow()
row = view.curRow()
for rw in range(row,erow+1):
line = view.substr(view.line(view.text_point(rw,0)))
if(RE_END.search(line)):
end = rw
break
if(not end):
log.debug("Could not locate #+END: tag")
return
# Okay now we have a start and end to build a region out of.
# time to run a command and try to get the output.
dynamic = ext.find_extension_modules('orgdynamic', ["insertdatetime", "clocktable", "columnview"])
line = view.substr(view.line(start))
m = RE_DYN_BLOCK.search(line)
if(not m):
log.error("FAILED TO PARSE DYNAMIC BLOCK: " + line)
return
fnname = m.group('name')
#log.debug("DYN NAME: " + fnname)
params = PList.createPList(line[len(m.group(0)):])
# Now find me that function!
if(fnname not in dynamic):
log.error("Function not found in dynamic folder! Cannot execute!")
return
# Run the "writer"
if(hasattr(dynamic[fnname],"Execute")):
self.curmod = dynamic[fnname]
self.params = params
outputs = self.curmod.Execute(view, params)
#log.debug("OUTPUT: " + str(outputs))
# Okay now time to replace the contents of the block
s = view.text_point(row+1,0)
e = view.text_point(end,0)
self.region = sublime.Region(s,e)
# Reformat adding indents to each line!
# No bad formatting allowed!
n = db.Get().AtInView(view)
level = n.level
indent = "\n"+ (" " * level) + " "
#outputs = output.split('\n')
output = indent.join(outputs)
print(output)
self.view.run_command("org_internal_replace", {"start": s, "end": e, "text": (" " * level + " ") + output+"\n","onDone": evt.Make(self.on_replaced)})
else:
log.error("NOT in A DynamicBlock, nothing to run")