summaryrefslogtreecommitdiff
path: root/fsm.py
diff options
context:
space:
mode:
authorMatt Singleton <matt@xcolour.net>2022-01-14 10:30:10 -0600
committerMatt Singleton <matt@xcolour.net>2022-01-16 13:04:41 -0600
commit09c7b7abbdbf5b12f908d4a88fe5c0098094b2c7 (patch)
treec6b45c831eef7fd4f31ad48a0e0525fad6ab3a08 /fsm.py
parent5499319fa66d677d2ec0d39b077c4f42af4d1296 (diff)
switch to fsm implementation of gem2html
Diffstat (limited to 'fsm.py')
-rw-r--r--fsm.py86
1 files changed, 14 insertions, 72 deletions
diff --git a/fsm.py b/fsm.py
index 40f9c2d..901e114 100644
--- a/fsm.py
+++ b/fsm.py
@@ -1,4 +1,6 @@
import sys
+import urllib.parse
+
class StackFSM(object):
"""
@@ -25,6 +27,7 @@ class StackFSM(object):
def pop_state(self):
return self._state_stack.pop()
+
class Parser(object):
def __init__(self, document, output=None):
@@ -38,29 +41,23 @@ class Parser(object):
def parse(self):
self._fsm.push_state(self.text_state)
- while self._fsm._current_state() is not None:
+ while self._fsm._current_state() is not None and len(self._document) > self._offset:
self._fsm.update()
def text_state(self):
- if len(self._document) <= self._offset:
- self._fsm.pop_state()
- return
line = self._document[self._offset]
if line.strip() == '':
self._blanks += 1
else:
self._blanks = 0
if line.strip() == '```':
- self._fsm.pop_state()
self._fsm.push_state(self.pre_state)
self._output.write('<pre>\n')
self._offset += 1
elif line.startswith('* '):
- self._fsm.pop_state()
self._fsm.push_state(self.list_state)
self._output.write('<ul>\n')
elif line.startswith('=>'):
- self._fsm.pop_state()
self._fsm.push_state(self.link_state)
self._output.write('<ul>\n')
else:
@@ -80,95 +77,40 @@ class Parser(object):
self._offset += 1
def pre_state(self):
- if len(self._document) < self._offset:
- self.pop_state()
- return
line = self._document[self._offset]
if line.strip() == '```':
self._fsm.pop_state()
- self._fsm.push_state(self.text_state)
self._output.write('</pre>\n')
self._offset += 1
- elif line.startswith('* '):
- self._fsm.pop_state()
- self._fsm.push_state(self.list_state)
- self._output.write('<ul>\n')
- elif line.startswith('=>'):
- self._fsm.pop_state()
- self._fsm.push_state(self.link_state)
- self._output.write('<ul>\n')
else:
self._output.write(line + '\n')
self._offset += 1
def list_state(self):
- if len(self._document) < self._offset:
- self.pop_state()
- return
line = self._document[self._offset]
if line.startswith('* '):
self._output.write('<li>{}</li>\n'.format(line[2:]))
self._offset += 1
else:
self._fsm.pop_state()
- self._fsm.push_state(self.text_state)
self._output.write('</ul>\n')
def link_state(self):
- if len(self._document) < self._offset:
- self.pop_state()
- return
line = self._document[self._offset]
if line.startswith('=>'):
- parts = line[2:].split(None, 2)
+ parts = line[2:].split(None, 1)
+ url = parts[0]
+ url_parts = urllib.parse.urlsplit(url)
+ if url_parts.scheme in ('gemini', ''):
+ external = ''
+ else:
+ external = ' class="external"'
if len(parts) == 1:
- self._output.write('<li><a href="{}">{}</a></li>\n'.format(parts[0], parts[0]))
+ text = url
else:
- self._output.write('<li><a href="{}">{}</a></li>\n'.format(parts[0], parts[1]))
+ text = parts[1]
+ self._output.write('<li{}><a href="{}">{}</a></li>\n'.format(external, url, text))
self._offset += 1
else:
self._fsm.pop_state()
- self._fsm.push_state(self.text_state)
self._output.write('</ul>\n')
-
-document = """
-# h1
-hello
-hello
-
-## h2
-```
-code
-code
-```
-### h3
-hello
-
-
-hello
-
-### lists
-* hello
-* two
-* three
-
-text
-
-* one
-* two
-* three
-
-### links
-=>https://example.com hello
-=> https://example.com two
-=> https://example.com three
-
-text
-
-=>https://example.com
-=> https://example.com
-=> https://example.com
-"""
-
-p = Parser(document.split('\n'))
-p.parse()