commit 5d2fad6de080f0c3b9544855ab2f4d29f72746f6 Author: Dustin C. Hatch Date: Sat Mar 7 10:37:27 2015 -0600 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14c71f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.egg-info/ +__pycache__/ +*.py[co] diff --git a/debug.py b/debug.py new file mode 100644 index 0000000..70b7b93 --- /dev/null +++ b/debug.py @@ -0,0 +1,19 @@ +from werkzeug import serving +import rstpreview +import os.path + + +app = rstpreview.make_app() + + +try: + serving.run_simple( + hostname='::', + port=8080, + application=app, + static_files={ + '/static': os.path.join(os.path.dirname(__file__), 'static'), + }, + ) +except KeyboardInterrupt: + print('Exiting...') diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..1b48402 --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +from setuptools import find_packages, setup + +setup( + name='RstPreview', + version='0.1', + description='Simple browser-based lightweight markup language previewer', + author='Dustin C. Hatch', + author_email='dustin@hatch.name', + url='https://bitbucket.org/AdmiralNemo/rstpreview', + license='APACHE-2', + packages=find_packages('src'), + package_dir={'': 'src'}, +) diff --git a/src/rstpreview/__init__.py b/src/rstpreview/__init__.py new file mode 100644 index 0000000..40e88b9 --- /dev/null +++ b/src/rstpreview/__init__.py @@ -0,0 +1,8 @@ +from . import routes +import milla + + +def make_app(): + app = milla.Application(routes.router) + app.config.setdefault('milla.static_root', '/static/') + return app diff --git a/src/rstpreview/controllers.py b/src/rstpreview/controllers.py new file mode 100644 index 0000000..0148ef0 --- /dev/null +++ b/src/rstpreview/controllers.py @@ -0,0 +1,57 @@ +import docutils.core +import jinja2 +import milla.controllers + + +class BaseController(milla.controllers.Controller): + + TMPL_LOADER = jinja2.PackageLoader(__name__.rsplit('.', 1)[0]) + + def __before__(self, request): + super(BaseController, self).__before__(request) + env = jinja2.Environment(loader=self.TMPL_LOADER) + env.globals.update( + url=request.create_href, + static=request.static_resource, + ) + self.render = lambda t, **k: env.get_template(t).render(**k) + + def __after__(self, request): + super(BaseController, self).__after__(request) + del self.render + + +class IndexController(BaseController): + + DOCUTILS_SETTINGS = { + 'syntax_highlight': 'short', + } + + allowed_methods = ('GET', 'HEAD', 'POST') + + def __call__(self, request): + return getattr(self, request.method)(request) + + def GET(self, request): + response = request.ResponseClass() + response.text = self.render('index.html.j2') + return response + + def POST(self, request): + response = request.ResponseClass() + data = dict(request.POST) + content = data.get('content') + if content: + parts = docutils.core.publish_parts( + source=content, + writer_name='html4css1', + settings_overrides=self.DOCUTILS_SETTINGS, + ) + preview = parts['html_body'] + else: + preview = '' + response.text = self.render('index.html.j2', **dict( + content=content, + preview=preview, + )) + return response diff --git a/src/rstpreview/routes.py b/src/rstpreview/routes.py new file mode 100644 index 0000000..9e4b013 --- /dev/null +++ b/src/rstpreview/routes.py @@ -0,0 +1,7 @@ +from . import controllers +from milla.dispatch import routing + + +router = routing.Router() + +router.add_route('/', controllers.IndexController()) diff --git a/src/rstpreview/templates/index.html.j2 b/src/rstpreview/templates/index.html.j2 new file mode 100644 index 0000000..3b3a1f6 --- /dev/null +++ b/src/rstpreview/templates/index.html.j2 @@ -0,0 +1,60 @@ +{#- vim: set sw=2 ts=2 sts=2 et : -#} + + + + +RstPreview + + + + + + + + +
+

RstPreview

+
+ +
+
+
+ +
+ +
+
+
+
+{{ preview|d('') }} +
+
+ + + + + diff --git a/static/style/pygments.css b/static/style/pygments.css new file mode 100644 index 0000000..63f3193 --- /dev/null +++ b/static/style/pygments.css @@ -0,0 +1,62 @@ +.code .hll { background-color: #ffffcc } +.code { background: #f8f8f8; } +.code .c { color: #408080; font-style: italic } /* Comment */ +.code .err { border: 1px solid #FF0000 } /* Error */ +.code .k { color: #008000; font-weight: bold } /* Keyword */ +.code .o { color: #666666 } /* Operator */ +.code .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.code .cp { color: #BC7A00 } /* Comment.Preproc */ +.code .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.code .cs { color: #408080; font-style: italic } /* Comment.Special */ +.code .gd { color: #A00000 } /* Generic.Deleted */ +.code .ge { font-style: italic } /* Generic.Emph */ +.code .gr { color: #FF0000 } /* Generic.Error */ +.code .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.code .gi { color: #00A000 } /* Generic.Inserted */ +.code .go { color: #888888 } /* Generic.Output */ +.code .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.code .gs { font-weight: bold } /* Generic.Strong */ +.code .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.code .gt { color: #0044DD } /* Generic.Traceback */ +.code .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.code .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.code .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.code .kp { color: #008000 } /* Keyword.Pseudo */ +.code .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.code .kt { color: #B00040 } /* Keyword.Type */ +.code .m { color: #666666 } /* Literal.Number */ +.code .s { color: #BA2121 } /* Literal.String */ +.code .na { color: #7D9029 } /* Name.Attribute */ +.code .nb { color: #008000 } /* Name.Builtin */ +.code .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.code .no { color: #880000 } /* Name.Constant */ +.code .nd { color: #AA22FF } /* Name.Decorator */ +.code .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.code .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.code .nf { color: #0000FF } /* Name.Function */ +.code .nl { color: #A0A000 } /* Name.Label */ +.code .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.code .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.code .nv { color: #19177C } /* Name.Variable */ +.code .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.code .w { color: #bbbbbb } /* Text.Whitespace */ +.code .mf { color: #666666 } /* Literal.Number.Float */ +.code .mh { color: #666666 } /* Literal.Number.Hex */ +.code .mi { color: #666666 } /* Literal.Number.Integer */ +.code .mo { color: #666666 } /* Literal.Number.Oct */ +.code .sb { color: #BA2121 } /* Literal.String.Backtick */ +.code .sc { color: #BA2121 } /* Literal.String.Char */ +.code .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.code .s2 { color: #BA2121 } /* Literal.String.Double */ +.code .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.code .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.code .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.code .sx { color: #008000 } /* Literal.String.Other */ +.code .sr { color: #BB6688 } /* Literal.String.Regex */ +.code .s1 { color: #BA2121 } /* Literal.String.Single */ +.code .ss { color: #19177C } /* Literal.String.Symbol */ +.code .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.code .vc { color: #19177C } /* Name.Variable.Class */ +.code .vg { color: #19177C } /* Name.Variable.Global */ +.code .vi { color: #19177C } /* Name.Variable.Instance */ +.code .il { color: #666666 } /* Literal.Number.Integer.Long */