summaryrefslogtreecommitdiff
path: root/fsm.py
diff options
context:
space:
mode:
authorMatt Singleton <matt@xcolour.net>2022-01-19 18:58:02 -0600
committerMatt Singleton <matt@xcolour.net>2022-01-19 18:58:02 -0600
commit0abf3511646446ee64f21d551dd0d2214fd624b7 (patch)
tree84276e8a1288cb378e93a18d406d05d362c7ee53 /fsm.py
parent704be7d2e7db33635fc9de684c8b3916cd798c68 (diff)
organizing the repo a bit
Diffstat (limited to 'fsm.py')
-rw-r--r--fsm.py117
1 files changed, 0 insertions, 117 deletions
diff --git a/fsm.py b/fsm.py
deleted file mode 100644
index eccfc6e..0000000
--- a/fsm.py
+++ /dev/null
@@ -1,117 +0,0 @@
-import html
-import sys
-import urllib.parse
-
-
-class StackFSM(object):
- """
- Implement a finite state machine that uses a stack to
- manage state.
- """
-
- def __init__(self):
- self._state_stack = []
-
- def _current_state(self):
- if len(self._state_stack) > 0:
- return self._state_stack[-1]
- return None
-
- def update(self):
- fn = self._current_state()
- if fn is not None:
- fn()
-
- def push_state(self, state):
- self._state_stack.append(state)
-
- def pop_state(self):
- return self._state_stack.pop()
-
-
-class Parser(object):
-
- def __init__(self, document, output=None):
- self._document = document
- if output is None:
- output = sys.stdout
- self._output = output
- self._offset = 0
- self._blanks = 0
- self._fsm = StackFSM()
-
- def parse(self):
- self._fsm.push_state(self.text_state)
- while self._fsm._current_state() is not None and len(self._document) > self._offset:
- self._fsm.update()
-
- def text_state(self):
- line = self._document[self._offset]
- if line.strip() == '':
- self._blanks += 1
- else:
- self._blanks = 0
- if line.startswith('```'):
- self._fsm.push_state(self.pre_state)
- self._output.write('<pre>\n')
- self._offset += 1
- elif line.startswith('* '):
- self._fsm.push_state(self.list_state)
- self._output.write('<ul>\n')
- elif line.startswith('=>'):
- self._fsm.push_state(self.link_state)
- self._output.write('<ul>\n')
- else:
- if line.startswith('# '):
- self._output.write('<h1>{}</h1>\n'.format(html.escape(line[2:])))
- elif line.startswith('## '):
- self._output.write('<h2>{}</h2>\n'.format(html.escape(line[3:])))
- elif line.startswith('### '):
- self._output.write('<h3>{}</h3>\n'.format(html.escape(line[4:])))
- elif line.startswith('> '):
- self._output.write('<blockquote>{}</blockquote>\n'.format(html.escape(line[2:])))
- elif line.strip() == '':
- if self._blanks > 1:
- self._output.write('<br/>\n')
- else:
- self._output.write('<p>{}</p>\n'.format(html.escape(line)))
- self._offset += 1
-
- def pre_state(self):
- line = self._document[self._offset]
- if line.startswith('```'):
- self._fsm.pop_state()
- self._output.write('</pre>\n')
- self._offset += 1
- else:
- self._output.write(line + '\n')
- self._offset += 1
-
- def list_state(self):
- line = self._document[self._offset]
- if line.startswith('* '):
- self._output.write('<li>{}</li>\n'.format(html.escape(line[2:])))
- self._offset += 1
- else:
- self._fsm.pop_state()
- self._output.write('</ul>\n')
-
- def link_state(self):
- line = self._document[self._offset]
- if line.startswith('=>'):
- parts = line[2:].split(None, 1)
- url = parts[0]
- url_parts = urllib.parse.urlsplit(url)
- if url_parts.scheme in ('gemini', ''):
- external = ''
- else:
- external = open('external_link.svg').read()
- if len(parts) == 1:
- text = url
- else:
- text = html.escape(parts[1])
- self._output.write('<li class="link"><a href="{}">{}</a>{}</li>\n'.format(url, text, external))
- self._offset += 1
- else:
- self._fsm.pop_state()
- self._output.write('</ul>\n')