aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2018-04-10 19:39:35 +0200
committerGravatar Leon Sandøy <[email protected]>2018-04-10 19:39:35 +0200
commitf9f1fec758f280d99f33ab9f141c839d0542d5ee (patch)
treed09f85b3c82b8ad54dd4b82f49af48f5d38b5b74
parentFlash of Unstyled Content fix (diff)
parent[Wiki] Improve editor preview (diff)
Merge branch 'master' of github.com:discord-python/site
-rw-r--r--pysite/rst/__init__.py5
-rw-r--r--pysite/rst/roles.py37
-rw-r--r--requirements.txt1
-rw-r--r--static/css/pygments-monokai.css70
-rw-r--r--templates/main/base.html1
-rw-r--r--templates/wiki/base.html3
-rw-r--r--templates/wiki/page_edit.html20
7 files changed, 129 insertions, 8 deletions
diff --git a/pysite/rst/__init__.py b/pysite/rst/__init__.py
index 0e5f6ffe..815ad058 100644
--- a/pysite/rst/__init__.py
+++ b/pysite/rst/__init__.py
@@ -2,13 +2,14 @@
from docutils.core import publish_parts
from docutils.parsers.rst.roles import register_canonical_role
-from pysite.rst.roles import icon_role
+from pysite.rst.roles import icon_role, url_for_role
def render(rst: str):
return publish_parts(
- source=rst, writer_name="html5", settings_overrides={"halt_level": 2}
+ source=rst, writer_name="html5", settings_overrides={"halt_level": 2, "syntax_highlight": "short"}
)["html_body"]
register_canonical_role("icon", icon_role)
+register_canonical_role("url_for", url_for_role)
diff --git a/pysite/rst/roles.py b/pysite/rst/roles.py
index bff00533..414832df 100644
--- a/pysite/rst/roles.py
+++ b/pysite/rst/roles.py
@@ -2,6 +2,7 @@
from docutils import nodes
from docutils.parsers.rst.roles import set_classes
from docutils.parsers.rst.states import Inliner
+from flask import url_for
from jinja2 import escape
@@ -44,3 +45,39 @@ def icon_role(_role: str, rawtext: str, text: str, lineno: int, inliner: Inliner
node = nodes.raw(html, html, format="html", **options)
return [node], []
+
+
+def url_for_role(_role: str, rawtext: str, text: str, lineno: int, inliner: Inliner,
+ options: dict = None, _content: dict = None):
+ if options is None:
+ options = {}
+
+ set_classes(options)
+
+ if "/" in text:
+ parts = [escape(x) for x in text.split("/")]
+ else:
+ msg = inliner.reporter.error("URL specification must be in the form <page.name>/<text>", line=lineno)
+ prb = inliner.problematic(text, rawtext, msg)
+
+ return [prb], [msg]
+
+ if len(parts) != 2:
+ msg = inliner.reporter.error("URL specification must be in the form <page.name>/<text>", line=lineno)
+ prb = inliner.problematic(text, rawtext, msg)
+
+ return [prb], [msg]
+ else:
+ try:
+ url = url_for(parts[0])
+ name = parts[1]
+
+ html = f"""<a href="{url}">{name}</a>"""
+
+ node = nodes.raw(html, html, format="html", **options)
+ return [node], []
+ except Exception as e:
+ msg = inliner.reporter.error(str(e), line=lineno)
+ prb = inliner.problematic(text, rawtext, msg)
+
+ return [prb], [msg]
diff --git a/requirements.txt b/requirements.txt
index f7afea00..bb66b59d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,3 +11,4 @@ Flask-Dance
logmatic-python
flask-wtf
docutils
+pygments
diff --git a/static/css/pygments-monokai.css b/static/css/pygments-monokai.css
new file mode 100644
index 00000000..250c8d44
--- /dev/null
+++ b/static/css/pygments-monokai.css
@@ -0,0 +1,70 @@
+.code .hll { background-color: #49483e }
+.code { background: #272822; color: #f8f8f2 }
+.code .c { color: #75715e } /* Comment */
+.code .err { color: #960050; background-color: #1e0010 } /* Error */
+.code .k { color: #66d9ef } /* Keyword */
+.code .l { color: #ae81ff } /* Literal */
+.code .n { color: #f8f8f2 } /* Name */
+.code .o { color: #f92672 } /* Operator */
+.code .p { color: #f8f8f2 } /* Punctuation */
+.code .ch { color: #75715e } /* Comment.Hashbang */
+.code .cm { color: #75715e } /* Comment.Multiline */
+.code .cp { color: #75715e } /* Comment.Preproc */
+.code .cpf { color: #75715e } /* Comment.PreprocFile */
+.code .c1 { color: #75715e } /* Comment.Single */
+.code .cs { color: #75715e } /* Comment.Special */
+.code .gd { color: #f92672 } /* Generic.Deleted */
+.code .ge { font-style: italic } /* Generic.Emph */
+.code .gi { color: #a6e22e } /* Generic.Inserted */
+.code .gs { font-weight: bold } /* Generic.Strong */
+.code .gu { color: #75715e } /* Generic.Subheading */
+.code .kc { color: #66d9ef } /* Keyword.Constant */
+.code .kd { color: #66d9ef } /* Keyword.Declaration */
+.code .kn { color: #f92672 } /* Keyword.Namespace */
+.code .kp { color: #66d9ef } /* Keyword.Pseudo */
+.code .kr { color: #66d9ef } /* Keyword.Reserved */
+.code .kt { color: #66d9ef } /* Keyword.Type */
+.code .ld { color: #e6db74 } /* Literal.Date */
+.code .m { color: #ae81ff } /* Literal.Number */
+.code .s { color: #e6db74 } /* Literal.String */
+.code .na { color: #a6e22e } /* Name.Attribute */
+.code .nb { color: #f8f8f2 } /* Name.Builtin */
+.code .nc { color: #a6e22e } /* Name.Class */
+.code .no { color: #66d9ef } /* Name.Constant */
+.code .nd { color: #a6e22e } /* Name.Decorator */
+.code .ni { color: #f8f8f2 } /* Name.Entity */
+.code .ne { color: #a6e22e } /* Name.Exception */
+.code .nf { color: #a6e22e } /* Name.Function */
+.code .nl { color: #f8f8f2 } /* Name.Label */
+.code .nn { color: #f8f8f2 } /* Name.Namespace */
+.code .nx { color: #a6e22e } /* Name.Other */
+.code .py { color: #f8f8f2 } /* Name.Property */
+.code .nt { color: #f92672 } /* Name.Tag */
+.code .nv { color: #f8f8f2 } /* Name.Variable */
+.code .ow { color: #f92672 } /* Operator.Word */
+.code .w { color: #f8f8f2 } /* Text.Whitespace */
+.code .mb { color: #ae81ff } /* Literal.Number.Bin */
+.code .mf { color: #ae81ff } /* Literal.Number.Float */
+.code .mh { color: #ae81ff } /* Literal.Number.Hex */
+.code .mi { color: #ae81ff } /* Literal.Number.Integer */
+.code .mo { color: #ae81ff } /* Literal.Number.Oct */
+.code .sa { color: #e6db74 } /* Literal.String.Affix */
+.code .sb { color: #e6db74 } /* Literal.String.Backtick */
+.code .sc { color: #e6db74 } /* Literal.String.Char */
+.code .dl { color: #e6db74 } /* Literal.String.Delimiter */
+.code .sd { color: #e6db74 } /* Literal.String.Doc */
+.code .s2 { color: #e6db74 } /* Literal.String.Double */
+.code .se { color: #ae81ff } /* Literal.String.Escape */
+.code .sh { color: #e6db74 } /* Literal.String.Heredoc */
+.code .si { color: #e6db74 } /* Literal.String.Interpol */
+.code .sx { color: #e6db74 } /* Literal.String.Other */
+.code .sr { color: #e6db74 } /* Literal.String.Regex */
+.code .s1 { color: #e6db74 } /* Literal.String.Single */
+.code .ss { color: #e6db74 } /* Literal.String.Symbol */
+.code .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
+.code .fm { color: #a6e22e } /* Name.Function.Magic */
+.code .vc { color: #f8f8f2 } /* Name.Variable.Class */
+.code .vg { color: #f8f8f2 } /* Name.Variable.Global */
+.code .vi { color: #f8f8f2 } /* Name.Variable.Instance */
+.code .vm { color: #f8f8f2 } /* Name.Variable.Magic */
+.code .il { color: #ae81ff } /* Literal.Number.Integer.Long */
diff --git a/templates/main/base.html b/templates/main/base.html
index cbdd937b..cfe41099 100644
--- a/templates/main/base.html
+++ b/templates/main/base.html
@@ -17,6 +17,7 @@
<link rel="shortcut icon" href="{{ static_file('favicon.ico') }}">
<link rel="stylesheet" href="{{ static_file('uikit_blurple.css') }}"/>
<link rel="stylesheet" href="{{ static_file('style.css') }}"/>
+ <link rel="stylesheet" href="{{ static_file('css/pygments-monokai.css') }}"/>
<!-- OpenGraph metadata -->
<meta property="og:title" content="Python Discord | {% block og_title %}{% endblock %}">
diff --git a/templates/wiki/base.html b/templates/wiki/base.html
index 02ab1b55..4bb227df 100644
--- a/templates/wiki/base.html
+++ b/templates/wiki/base.html
@@ -16,6 +16,7 @@
<link rel="shortcut icon" href="{{ static_file('favicon.ico') }}">
<link rel="stylesheet" href="{{ static_file('uikit_blurple.css') }}"/>
<link rel="stylesheet" href="{{ static_file('style.css') }}"/>
+ <link rel="stylesheet" href="{{ static_file('css/pygments-monokai.css') }}"/>
<!-- OpenGraph metadata -->
<meta property="og:title" content="Python Discord | {% block og_title %}{% endblock %}">
@@ -30,7 +31,7 @@
<div class="uk-offcanvas-content uk-flex uk-flex-column">
{% include "main/navigation.html" %}
<div class="uk-flex uk-flex-row uk-flex-1">
- <div class="uk-card uk-card-body uk-flex-left uk-flex">
+ <div class="uk-card uk-card-body uk-flex-left uk-flex uk-card-primary">
<ul class="uk-nav-default uk-nav-parent-icon" uk-nav>
{% if (can_edit or debug) and current_page == "page" %}
<li>
diff --git a/templates/wiki/page_edit.html b/templates/wiki/page_edit.html
index 7664511e..b797577d 100644
--- a/templates/wiki/page_edit.html
+++ b/templates/wiki/page_edit.html
@@ -14,7 +14,7 @@
<button class="uk-button uk-button-secondary" type="button" value="Preview" id="preview">Preview</button>
</div>
<div class="uk-width-auto">
- <input class="uk-button uk-button-primary" type="submit" value="Save" />
+ <input class="uk-button uk-button-primary" type="submit" id="submit" value="Save" />
</div>
<div class="uk-width-1-1">
<div id="editor" class="uk-textarea" style="resize: vertical; min-height: 15rem;">{{ rst }}</div>
@@ -24,10 +24,12 @@
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
</form>
- <h2>Preview</h2>
+ <div class="uk-container uk-container-small" style="padding: 1rem 1rem 0.1rem;">
+ <h2 id="preview-title">{{ title }}</h2>
- <div class="uk-alert" id="preview-div" style="padding: 1rem 1rem 0.1rem;">
- {{ preview | safe }}
+ <div id="preview-div">
+ {{ preview | safe }}
+ </div>
</div>
<script type="application/javascript">
@@ -42,6 +44,8 @@
let response = JSON.parse(this.responseText);
if (response.error !== undefined) {
+ document.getElementById("submit").disabled = true;
+
if (response.error_lines !== undefined) {
editor.session.setAnnotations(response.error_lines);
document.getElementById("preview-div").innerHTML ="<h3>Error - see editor margin</h3>";
@@ -50,7 +54,9 @@
document.getElementById("preview-div").innerHTML ="<h3>Error</h3><p>" + response.error + "<p>";
}
} else {
+ document.getElementById("submit").disabled = false;
document.getElementById("preview-div").innerHTML = response.data;
+
editor.session.setAnnotations([]);
}
});
@@ -81,6 +87,10 @@
clearTimeout(timer);
}
timer = setTimeout(function() {document.getElementById("preview").click()}, 1000);
- })
+ });
+
+ document.getElementById("title").oninput = function() {
+ document.getElementById("preview-title").textContent = document.getElementById("title").value;
+ }
</script>
{% endblock %} \ No newline at end of file