Skip to content

Commit 6d9c6e9

Browse files
committed
add files
1 parent 15eb615 commit 6d9c6e9

8 files changed

Lines changed: 1155 additions & 0 deletions

Default (Linux).sublime-keymap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{ "keys": ["ctrl+k", "m"], "command": "markmon_toggle", "args":
3+
{
4+
"enable": true
5+
}
6+
}
7+
]

Default (OSX).sublime-keymap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{ "keys": ["ctrl+super+m"], "command": "markmon_toggle", "args":
3+
{
4+
"enable": true
5+
}
6+
}
7+
]

Default (Windows).sublime-keymap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{ "keys": ["ctrl+k", "m"], "command": "markmon_toggle", "args":
3+
{
4+
"enable": true
5+
}
6+
}
7+
]

MarkmonListener.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sublime
2+
import sublime_plugin
3+
4+
class MarkmonListener(sublime_plugin.EventListener):
5+
@classmethod
6+
def shared_plugin(cls):
7+
"""Return the plugin instance."""
8+
return cls.shared_instance
9+
10+
def __init__(self, *args, **kwargs):
11+
"""Initialize a new instance."""
12+
super().__init__(*args, **kwargs)
13+
14+
self.settings = None
15+
self.on_setting_change_callbacks = []
16+
self.on_modified_callbacks = []
17+
18+
self.__class__.shared_instance = self
19+
20+
21+
def add_on_settings_change(self, callback):
22+
self.on_setting_change_callbacks.append(callback)
23+
callback(self.settings)
24+
25+
def add_on_modified(self, callback):
26+
self.on_modified_callbacks.append(callback)
27+
28+
def load_settings(self):
29+
self.settings = sublime.load_settings('sublime-text-markmon.sublime-settings')
30+
self.settings.add_on_change("*", self.settings_updated)
31+
32+
def settings_updated(self):
33+
for callback in self.on_setting_change_callbacks:
34+
callback(self.settings)
35+
36+
def on_modified_async(self, view):
37+
for callback in self.on_modified_callbacks:
38+
callback(view)
39+
40+
def on_activated_async(self, view):
41+
for callback in self.on_modified_callbacks:
42+
callback(view)

commands.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import sublime
2+
import time
3+
import sublime_plugin
4+
import webbrowser
5+
import subprocess
6+
import atexit
7+
import re
8+
from .MarkmonListener import MarkmonListener
9+
import http.client
10+
from . import util, markmon
11+
import os
12+
13+
class MarkmonToggleCommand(sublime_plugin.WindowCommand):
14+
def __init__(self, window):
15+
"""Initialize a new instance."""
16+
super().__init__(window)
17+
self.server = None
18+
19+
def run(self, **args):
20+
if args['enable']:
21+
markmon.markmon.set_running(True)
22+
else:
23+
markmon.markmon.set_running(False)
24+
25+
def is_enabled(self):
26+
return True

markmon.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import sublime
2+
import time
3+
import sublime_plugin
4+
import webbrowser
5+
import subprocess
6+
import atexit
7+
import re
8+
from .MarkmonListener import MarkmonListener
9+
import http.client
10+
from . import util
11+
import os
12+
from threading import Timer
13+
14+
MARKDOWN_SYNTAX = re.compile(r'.*[Mm]arkdown.*')
15+
16+
markmon = None
17+
def plugin_loaded():
18+
"""The ST3 entry point for plugins."""
19+
global markmon
20+
markmon = Markmon(MarkmonListener.shared_plugin())
21+
22+
class Markmon:
23+
def __init__(self, listener):
24+
listener = MarkmonListener.shared_plugin()
25+
listener.load_settings()
26+
27+
self.settings = MarkmonSettings()
28+
self.client = MarkmonClient(self.settings)
29+
self.server = MarkmonServer(self.settings)
30+
self.client.set_server(self.server)
31+
32+
listener.add_on_settings_change(self.settings_updated)
33+
listener.add_on_modified(self.client.view_updated)
34+
35+
def settings_updated(self, settings):
36+
self.settings.update(settings)
37+
self.server.setup_server()
38+
39+
def display(self):
40+
current_view = sublime.active_window().active_view()
41+
self.client.view_updated(current_view)
42+
webbrowser.open("http://" + self.settings.client_url)
43+
44+
def set_running(self, running):
45+
if running != self.settings.running:
46+
self.settings.running = running
47+
if running:
48+
self.server.setup_server()
49+
# need a delay to wait for the server to set up
50+
Timer(1.0, self.display).start()
51+
else:
52+
self.server.cleanup_server()
53+
elif running:
54+
self.display()
55+
56+
57+
class MarkmonSettings:
58+
def __init__(self):
59+
self.running = False
60+
self.settings = {}
61+
self.server_command = []
62+
self.client_url = ""
63+
64+
def update(self, settings):
65+
self.settings = {
66+
"port": settings.get("port", 3000),
67+
"command": settings.get("command", "pandoc -t HTML5"),
68+
"stylesheet": settings.get("stylesheet", None),
69+
"projectdir": settings.get("projectdir", None)
70+
}
71+
self.build_strings()
72+
73+
def build_strings(self):
74+
self.client_url = "localhost:{:d}".format(self.settings['port'])
75+
self.server_command = ['markmon',
76+
"--port", str(self.settings['port']),
77+
"--command", self.settings['command']]
78+
if self.settings['stylesheet']:
79+
self.server_command.append("--stylesheet")
80+
self.server_command.append(self.settings['stylesheet'])
81+
82+
if self.settings['projectdir']:
83+
self.server_command.append("--projectdir")
84+
self.server_command.append(self.settings['projectdir'])
85+
86+
class MarkmonClient:
87+
def __init__(self, settings):
88+
self.settings = settings
89+
self.server = None
90+
91+
def set_server(self, server):
92+
self.server = server
93+
94+
def view_updated(self, view, try_server=True):
95+
if self.settings.running and MARKDOWN_SYNTAX.match(view.scope_name(0)):
96+
try:
97+
connection = http.client.HTTPConnection(self.settings.client_url)
98+
connection.request('PUT', '/', view.substr(sublime.Region(0, view.size())))
99+
connection.getresponse()
100+
except ConnectionRefusedError:
101+
if self.server:
102+
if try_server:
103+
self.server.setup_server()
104+
time.sleep(1)
105+
self.view_updated(view, False)
106+
else:
107+
print("Markmon server is down. Check your preferences.")
108+
109+
class MarkmonServer:
110+
def __init__(self, settings):
111+
self.server_url = None
112+
self.settings = settings
113+
atexit.register(self.cleanup_server)
114+
115+
def setup_server(self, _=None):
116+
try:
117+
self.cleanup_server()
118+
except:
119+
pass
120+
if not self.settings.running:
121+
return
122+
self.server_url = self.settings.client_url
123+
env = os.environ.copy()
124+
betterenv = util.create_environment()
125+
env["PATH"] = betterenv["PATH"]
126+
subprocess.Popen(self.settings.server_command, env=env)
127+
128+
def cleanup_server(self):
129+
if self.server_url:
130+
connection = http.client.HTTPConnection(self.server_url)
131+
connection.request('DELETE', '/')
132+
connection.getresponse()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"port": 3002,
3+
"command": "pandoc -t HTML5",
4+
"stylesheet": null,
5+
"projectdir": null
6+
}

0 commit comments

Comments
 (0)