Initial commit

This commit is contained in:
Folkert Kevelam 2025-08-23 20:32:20 +02:00
parent 1b867fddfe
commit 9616a1b514
5 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,8 @@
from .server import main
import asyncio
import argparse
import sys
def launcher():
print(sys.argv)
asyncio.run(main())

View File

@ -0,0 +1,94 @@
# Render pipeline for markdown documents.
# Allows filtering and mapping based on blocks and meta keys.
#
import pandoc
class MetaCallback:
def __init__(self, key, callback, replace=False):
self.key = key
self.callback = callback
self.replace = replace
def __call__(self, data):
return self.callback(data)
class MultiCallback:
def __init__(self, filter):
self.filter = filter
self.callbacks = dict()
def AddCallback(self, key, callback):
self.callbacks[key] = callback
def __call__(self, block):
filter_key = self.filter(block)
if filter_key is None:
return block
if filter_key in self.callbacks.keys():
return self.callbacks[filter_key](block)
else:
return block
class RenderPipeline:
def __init__(self):
self.pandoc = pandoc.Pandoc()
self.metacallbacks = dict()
self.callbacks = dict()
def AddMetaCallback(self, key, callback, replace=False):
self.metacallbacks[key] = MetaCallback(key, callback, replace)
def AddCallback(self, key, callback, replace=False):
self.callbacks[key] = {'cb' : callback, 'replace' : replace}
def ParseBlock(self, block):
if 'c' not in block:
return block
if isinstance(block['c'], dict):
content = self.ParseBlock(block['c'])
elif isinstance(block['c'], list):
content = self.ParseList(block['c'])
else:
return block
if block['t'] in self.callbacks.keys():
if self.callbacks[block['t']]['replace'] == True:
return self.callbacks[block['t']]['cb'](block)
else:
self.callbacks[block['t']]['cb'](block)
return block
def ParseList(self, pandoc_list):
output_list = list()
for item in pandoc_list:
if isinstance(item, dict):
output_list.append(self.ParseBlock(item))
else:
output_list.append(item)
return output_list
def __call__(self, data):
json_data = self.pandoc.ConvertToJson(data)
for meta_key, meta_value in json_data['meta'].items():
if meta_key in self.metacallbacks.keys():
if self.metacallbacks[meta_key].replace == True:
json_data['meta'][meta_key] = \
self.metacallbacks[meta_key](meta_value)
else:
self.metacallbacks[meta_key](meta_value)
json_data['blocks'] = self.ParseList(json_data['blocks'])
return_data = self.pandoc.ConvertFromJson(json_data)
return return_data

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="highlight/styles/tokyo-night-dark.min.css">
<script src="highlight/highlight.min.js"></script>
<link href="katex/katex.min.css" rel="stylesheet" type="text/css">
<script src="katex/katex.min.js"></script>
<script src="katex/contrib/auto-render.min.js"></script>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="page-container">
<header class="page-header">
<h1 class="page-title">Your Note Title</h1>
<div class="page-subtitle">
<div class="page-author">Author: Your Name</div>
<div class="page-date">Date: August 1, 2025</div>
</div>
</header>
<div id="page-content" class="page-content">
{% raw body_content %}
</div>
<script>
hljs.highlightAll();
renderMathInElement(
document.body,
{
delimiters : [
{left: "$$", right: "$$", display: true},
{left: "\\[", right: "\\]", display: true},
{left: "$", right: "$", display: false},
{left: "\\(", right: "\\)", display: false}
]
});
const socket = new WebSocket("ws://localhost:8888/ws");
socket.addEventListener("open", (event) => {
socket.send("ping");
});
socket.addEventListener("message", (event) => {
var data = JSON.parse(event.data);
var node = document.getElementById("page-content");
var wrapper = document.createElement('div');
wrapper.innerHTML = data['show'];
node.replaceChildren(wrapper);
hljs.highlightAll();
renderMathInElement(
node,
{
delimiters : [
{left: "$$", right: "$$", display: true},
{left: "\\[", right: "\\]", display: true},
{left: "$", right: "$", display: false},
{left: "\\(", right: "\\)", display: false}
]
});
});
</script>
</body>
</html>

2
Server/requirements.txt Normal file
View File

@ -0,0 +1,2 @@
tornado
msgpack

20
Server/setup.py Normal file
View File

@ -0,0 +1,20 @@
from setuptools import setup, find_packages
with open('requirements.txt') as f:
requirements = f.read().splitlines()
setup(
name="MarkdownPreviewer",
version="0.0.1",
include_pacakge_data=True,
python_requires=">=3.8",
setup_requires=['setuptools-git-versioning'],
install_requires=requirements,
author="Folkert Kevelam",
author_email="folkert@pyllr.nl",
description="A markdown previewer",
long_description="",
long_description_content_type="text/markdown",
classifiers=[],
version_config={}
)