added static folder
switch to fancy css
This commit is contained in:
@@ -5,81 +5,37 @@ import hashlib
|
|||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
|
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
|
||||||
from os.path import basename, dirname, abspath
|
from os.path import basename, dirname, abspath, join
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import markdown
|
import markdown
|
||||||
|
|
||||||
TEMPLATE = """
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
{css}
|
|
||||||
<style>
|
|
||||||
body {{
|
|
||||||
font-family: sans-serif;
|
|
||||||
}}
|
|
||||||
code, pre {{
|
|
||||||
font-family: monospace;
|
|
||||||
}}
|
|
||||||
h1 code,
|
|
||||||
h2 code,
|
|
||||||
h3 code,
|
|
||||||
h4 code,
|
|
||||||
h5 code,
|
|
||||||
h6 code {{
|
|
||||||
font-size: inherit;
|
|
||||||
}}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script type=\"text/javascript\">
|
|
||||||
function req(first) {{
|
|
||||||
var xmlhttp = new XMLHttpRequest();
|
|
||||||
xmlhttp.onload = function() {{
|
|
||||||
if (xmlhttp.status == 200) {{
|
|
||||||
document.querySelector("div.container").innerHTML = xmlhttp.responseText;
|
|
||||||
}} else if(xmlhttp.status == 304) {{
|
|
||||||
}} else {{
|
|
||||||
console.log(xmlhttp.status, xmlhttp.statusText);
|
|
||||||
}}
|
|
||||||
req(false);
|
|
||||||
}};
|
|
||||||
xmlhttp.onerror = function() {{
|
|
||||||
console.log(xmlhttp.status, xmlhttp.statusText);
|
|
||||||
setTimeout(req, 1000, false);
|
|
||||||
}};
|
|
||||||
xmlhttp.open("GET", first ? "/markdown" : "/reload", true);
|
|
||||||
xmlhttp.send();
|
|
||||||
}}
|
|
||||||
req(true);
|
|
||||||
</script>
|
|
||||||
<div class="container">
|
|
||||||
{content}
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
def create_css_tag(url_list):
|
STATIC_CACHE = {}
|
||||||
result = ''
|
def load_from_cache(path):
|
||||||
for url in url_list:
|
global STATIC_CACHE
|
||||||
result += '<link href="%s" rel="stylesheet">' % url
|
if path not in STATIC_CACHE:
|
||||||
return result
|
with open(join(dirname(__file__), 'static') + path, 'r') as static_file:
|
||||||
|
STATIC_CACHE[path] = static_file.read()
|
||||||
|
return STATIC_CACHE[path]
|
||||||
|
|
||||||
def compile_html(mdfile=None, extensions=None, raw=None, stylesheet=(), **kwargs):
|
def compile_html(mdfile=None, extensions=None, raw=None, **kwargs):
|
||||||
html = None
|
html = None
|
||||||
with mdfile and open(mdfile, 'r') or sys.stdin as instream:
|
with mdfile and open(mdfile, 'r') or sys.stdin as instream:
|
||||||
html = markdown.markdown(instream.read(), extensions=extensions, output_format='html5')
|
html = markdown.markdown(instream.read(), extensions=extensions, output_format='html5')
|
||||||
if raw:
|
if raw:
|
||||||
doc = html
|
doc = html
|
||||||
else:
|
else:
|
||||||
doc = TEMPLATE.format(content=html, css=create_css_tag(stylesheet))
|
css = ' <style>%s\n%s\n </style>' % (
|
||||||
|
load_from_cache('/github-markdown.css'),
|
||||||
|
load_from_cache('/custom.css')
|
||||||
|
)
|
||||||
|
doc = load_from_cache('/template.html').format(content=html, script='', css=css)
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
class MarkdownHTTPServer(ThreadingHTTPServer):
|
class MarkdownHTTPServer(ThreadingHTTPServer):
|
||||||
|
|
||||||
def __init__(self, mdfile, extensions=(), stylesheet=(), handler=BaseHTTPRequestHandler, interface="127.0.0.1", port=8080):
|
def __init__(self, mdfile, extensions=(), handler=BaseHTTPRequestHandler, interface="127.0.0.1", port=8080):
|
||||||
import inotify
|
import inotify
|
||||||
import inotify.adapters
|
import inotify.adapters
|
||||||
import signal
|
import signal
|
||||||
@@ -93,7 +49,6 @@ class MarkdownHTTPServer(ThreadingHTTPServer):
|
|||||||
|
|
||||||
self.mdfile = mdfile
|
self.mdfile = mdfile
|
||||||
self.extensions = extensions
|
self.extensions = extensions
|
||||||
self.stylesheet = stylesheet
|
|
||||||
self.condition_variable = threading.Condition()
|
self.condition_variable = threading.Condition()
|
||||||
self.hash = None
|
self.hash = None
|
||||||
self.etag = None
|
self.etag = None
|
||||||
@@ -134,6 +89,7 @@ class MarkdownHTTPServer(ThreadingHTTPServer):
|
|||||||
|
|
||||||
class MarkdownRequestHandler(BaseHTTPRequestHandler):
|
class MarkdownRequestHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
|
|
||||||
status_map = {
|
status_map = {
|
||||||
200: "OK",
|
200: "OK",
|
||||||
204: "No Content",
|
204: "No Content",
|
||||||
@@ -176,8 +132,13 @@ class MarkdownRequestHandler(BaseHTTPRequestHandler):
|
|||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
path = urlparse(self.path)
|
path = urlparse(self.path)
|
||||||
if path.path == '/':
|
if path.path == '/':
|
||||||
self.answer(200, reply=TEMPLATE.format(content='', css=create_css_tag(self.server.stylesheet)),
|
self.answer(200, reply=load_from_cache('/template.html').format(content='',
|
||||||
|
script='<script src="/hot-reload.js", type="text/javascript"></script>',
|
||||||
|
css='<link rel="stylesheet" href="github-markdown.css">'
|
||||||
|
'<link rel="stylesheet" href="custom.css">'),
|
||||||
content_type='text/html')
|
content_type='text/html')
|
||||||
|
elif path.path in {'/github-markdown.css', '/custom.css', '/hot-reload.js'}:
|
||||||
|
self.answer(200, load_from_cache(path.path), content_type='text/css')
|
||||||
elif path.path == '/markdown':
|
elif path.path == '/markdown':
|
||||||
self.markdown_answer()
|
self.markdown_answer()
|
||||||
elif path.path == '/reload':
|
elif path.path == '/reload':
|
||||||
@@ -219,9 +180,6 @@ def parse_args(args=None):
|
|||||||
help='Specify http server port (defaults to 5000)')
|
help='Specify http server port (defaults to 5000)')
|
||||||
parser.add_argument('-i', '--interface', default='',
|
parser.add_argument('-i', '--interface', default='',
|
||||||
help='Specify http server listen interface (defaults to localhost)')
|
help='Specify http server listen interface (defaults to localhost)')
|
||||||
parser.add_argument('-s', '--stylesheet', nargs='+',
|
|
||||||
default=['http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css'],
|
|
||||||
help='Specify a list of stylesheet URLs to add to the html page')
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
return parser.parse_args(args)
|
return parser.parse_args(args)
|
||||||
@@ -236,7 +194,6 @@ def main(args=None):
|
|||||||
if hasattr(args, 'watch') and args.watch:
|
if hasattr(args, 'watch') and args.watch:
|
||||||
server = MarkdownHTTPServer(args.mdfile,
|
server = MarkdownHTTPServer(args.mdfile,
|
||||||
extensions=args.extensions,
|
extensions=args.extensions,
|
||||||
stylesheet=args.stylesheet,
|
|
||||||
interface=args.interface,
|
interface=args.interface,
|
||||||
port=args.port,
|
port=args.port,
|
||||||
handler=MarkdownRequestHandler)
|
handler=MarkdownRequestHandler)
|
||||||
|
13
md2html/static/custom.css
Normal file
13
md2html/static/custom.css
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.markdown-body {
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 980px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.markdown-body {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
}
|
19
md2html/static/hot-reload.js
Normal file
19
md2html/static/hot-reload.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
function req(first) {
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
xmlhttp.onload = function() {
|
||||||
|
if (xmlhttp.status == 200) {
|
||||||
|
document.querySelector("article.markdown-body").innerHTML = xmlhttp.responseText;
|
||||||
|
} else if(xmlhttp.status == 304) {
|
||||||
|
} else {
|
||||||
|
console.log(xmlhttp.status, xmlhttp.statusText);
|
||||||
|
}
|
||||||
|
req(false);
|
||||||
|
};
|
||||||
|
xmlhttp.onerror = function() {
|
||||||
|
console.log(xmlhttp.status, xmlhttp.statusText);
|
||||||
|
setTimeout(req, 1000, false);
|
||||||
|
};
|
||||||
|
xmlhttp.open("GET", first ? "/markdown" : "/reload", true);
|
||||||
|
xmlhttp.send();
|
||||||
|
}
|
||||||
|
req(true);
|
13
md2html/static/template.html
Normal file
13
md2html/static/template.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
{css}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{script}
|
||||||
|
<article class="markdown-body">
|
||||||
|
{content}
|
||||||
|
</article>
|
||||||
|
</body>
|
||||||
|
</html>
|
5
setup.py
5
setup.py
@@ -8,7 +8,7 @@ def read(fname):
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
'name': "md2html",
|
'name': "md2html",
|
||||||
'version': "0.1",
|
'version': "0.2",
|
||||||
'author': "Walter Oggioni",
|
'author': "Walter Oggioni",
|
||||||
'author_email': "oggioni.walter@gmail.com",
|
'author_email': "oggioni.walter@gmail.com",
|
||||||
'description': ("Various development utility scripts"),
|
'description': ("Various development utility scripts"),
|
||||||
@@ -17,6 +17,9 @@ config = {
|
|||||||
'keywords': "build",
|
'keywords': "build",
|
||||||
'url': "https://github.com/oggio88/md2html",
|
'url': "https://github.com/oggio88/md2html",
|
||||||
'packages': ['md2html'],
|
'packages': ['md2html'],
|
||||||
|
'package_data': {
|
||||||
|
'': ['*.html', '*.css', '*.js'],
|
||||||
|
},
|
||||||
'include_package_data': True,
|
'include_package_data': True,
|
||||||
'classifiers': [
|
'classifiers': [
|
||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
|
Reference in New Issue
Block a user