diff --git a/app.py b/app.py
index 960e63a..0a8c01c 100644
--- a/app.py
+++ b/app.py
@@ -31,12 +31,8 @@ try:
from slugify import slugify
except ImportError:
slugify = None
-try:
- import markdown_strikethrough
-except Exception:
- markdown_strikethrough = None
-__version__ = '0.4'
+__version__ = '0.5-dev'
#### CONSTANTS ####
@@ -93,6 +89,28 @@ def _makelist(l):
else:
return []
+
+#### MARKDOWN EXTENSIONS ####
+
+class StrikethroughExtension(markdown.extensions.Extension):
+ def extendMarkdown(self, md, md_globals):
+ postprocessor = StrikethroughPostprocessor(md)
+ md.postprocessors.add('strikethrough', postprocessor, '>raw_html')
+
+class StrikethroughPostprocessor(markdown.postprocessors.Postprocessor):
+ pattern = re.compile(r"~~(((?!~~).)+)~~", re.DOTALL)
+
+ def run(self, html):
+ return re.sub(self.pattern, self.convert, html)
+
+ def convert(self, match):
+ return '' + match.group(1) + ''
+
+### XXX it currently only detects spoilers that are not at the beginning of the line. To be fixed.
+class SpoilerExtension(markdown.extensions.Extension):
+ def extendMarkdown(self, md, md_globals):
+ md.inlinePatterns.register(markdown.inlinepatterns.SimpleTagInlineProcessor(r'()>!(.*?)!<', 'span class="spoiler"'), 'spoiler', 14)
+
#### DATABASE SCHEMA ####
database = SqliteDatabase(_getconf("config", "database_dir") + '/data.sqlite')
@@ -321,6 +339,9 @@ class PagePolicy(BaseModel):
(('page', 'key'), True),
)
+# DEPRECATED
+# It will be possibly removed in v0.6.
+# Use external image URL instead.
class Upload(BaseModel):
name = CharField(256)
url_name = CharField(256, null=True)
@@ -382,34 +403,11 @@ def init_db():
#### WIKI SYNTAX ####
-magic_word_filters = {}
-
-def _replace_magic_word(match):
- name = match.group(1)
- if name not in magic_word_filters:
- return match.group()
- f = magic_word_filters[name]
- try:
- return f(*(x.strip() for x in match.group(2).split('|')))
- except Exception:
- return ''
-
-def expand_magic_words(text):
- '''
- Replace the special markups in double curly brackets.
-
- Unknown keywords are not replaced. Valid keywords with invalid arguments are replaced with nothing.
- '''
- return re.sub(MAGIC_RE, _replace_magic_word, text)
-
def md(text, expand_magic=False, toc=True):
if expand_magic:
# DEPRECATED seeking for a better solution.
warnings.warn('Magic words are no more supported.', DeprecationWarning)
- text = expand_magic_words(text)
- extensions = ['tables', 'footnotes', 'fenced_code', 'sane_lists']
- if markdown_strikethrough:
- extensions.append("markdown_strikethrough.extension")
+ extensions = ['tables', 'footnotes', 'fenced_code', 'sane_lists', StrikethroughExtension(), SpoilerExtension()]
if toc:
extensions.append('toc')
return markdown.Markdown(extensions=extensions).convert(text)
@@ -418,59 +416,9 @@ def remove_tags(text, convert=True, headings=True):
if headings:
text = re.sub(r'\#[^\n]*', '', text)
if convert:
- text = md(text, expand_magic=False, toc=False)
+ text = md(text, toc=False)
return re.sub(r'<.*?>|\{\{.*?\}\}', '', text)
-
-### Magic words (deprecated!) ###
-
-def expand_backto(pageid):
- p = Page[pageid]
- return '*« Main article: [{}]({}).*'.format(html.escape(p.title), p.get_url())
-
-magic_word_filters['backto'] = expand_backto
-
-def expand_upload(id, *opt):
- try:
- upload = Upload[id]
- except Upload.DoesNotExist:
- return ''
- if opt:
- desc = opt[-1]
- else:
- desc = None
- classname = 'fig-right'
- return ' {3} '.format(
- classname, html.escape(upload.name), upload.url,
- '{0} '.format(md(desc, expand_magic=False)) if desc else '',
- upload.id)
-
-magic_word_filters['media'] = expand_upload
-
-def make_gallery(items):
- result = []
- for upload, desc in items:
- result.append(' {3} '.format(
- upload.id, html.escape(upload.name), upload.url,
- '{0} '.format(md(desc, expand_magic=False)) if desc else ''))
- return '
' + ''.join(result) + '
'
-
-def expand_gallery(*ids):
- items = []
- for i in ids:
- if ' ' in i:
- id, desc = i.split(' ', 1)
- else:
- id, desc = i, ''
- try:
- upload = Upload[id]
- except Upload.DoesNotExist:
- continue
- items.append((upload, desc))
- return make_gallery(items)
-
-magic_word_filters['gallery'] = expand_gallery
-
#### I18N ####
lang_poses = {'en': 1, 'en-US': 1, 'it': 2, 'it-IT': 2}
@@ -549,8 +497,7 @@ def linebreaks(text):
def homepage():
page_limit = _getconf("appearance","items_per_page",20,cast=int)
return render_template('home.html', new_notes=Page.select()
- .order_by(Page.touched.desc()).limit(page_limit),
- gallery=make_gallery((x, '') for x in Upload.select().order_by(Upload.upload_date.desc()).limit(3)))
+ .order_by(Page.touched.desc()).limit(page_limit))
@app.route('/robots.txt')
def robots():
@@ -795,28 +742,11 @@ def listtag(tag, page=1):
def media(fp):
return send_from_directory(UPLOAD_DIR, fp)
-@app.route('/upload/', methods=['GET', 'POST'])
+# symbolic route as of v0.5
+@app.route('/upload/', methods=['GET'])
def upload():
- if request.method == 'POST':
- name = request.form['name']
- file = request.files['file']
- filename = file.filename
- ext = os.path.splitext(filename)[1]
- content = file.read()
- try:
- upl = Upload.create_content(name, ext, content)
- flash('File uploaded successfully')
- return redirect('/upload-info/{}/'.format(upl.id))
- except Exception:
- sys.excepthook(*sys.exc_info())
- flash('Unable to upload file. Try again later.')
return render_template('upload.html')
-@app.route('/upload-info//')
-def upload_info(id):
- upl = Upload[id]
- return render_template('uploadinfo.html', upl=upl, type_list=upload_types_rev)
-
@app.route('/stats/')
def stats():
return render_template('stats.html',
@@ -881,7 +811,14 @@ def easter_y(y=None):
#### EXTENSIONS ####
-active_extensions = ['contactnova']
+active_extensions = []
+
+_i = 1
+_extension_name = _getconf('extensions', 'ext.{}'.format(_i))
+while _extension_name:
+ active_extensions.append(_extension_name)
+ _i += 1
+ _extension_name = _getconf('extensions', 'ext.{}'.format(_i))
for ext in active_extensions:
try:
diff --git a/static/content.js b/static/content.js
new file mode 100644
index 0000000..53859c2
--- /dev/null
+++ b/static/content.js
@@ -0,0 +1,8 @@
+(function() {
+
+ for (let i of document.getElementsByClassName('spoiler')) {
+ i.onclick = function() {
+ this.classList.toggle('revealed');
+ }
+ };
+})();
diff --git a/static/style.css b/static/style.css
index 4dd390e..04ec6d3 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1,13 +1,14 @@
/* basic styles */
-body{font-family:sans-serif}
+body{font-family:sans-serif;background-color:#faf5e9}
.content{margin: 3em 1.3em}
/* content styles */
-#firstHeading {font-family: 'Oswald','Anton','Impact',sans-serif; text-align: center;font-size:3em}
+#firstHeading {font-family:sans-serif; text-align: center;font-size:3em; font-weight: normal}
.inner-content{font-family:serif; margin: 1.7em auto; max-width: 1280px; line-height: 1.9; color: #1f2528}
.inner-content em,.inner-content strong{color: black}
.inner-content h1{color: #99081f}
-.inner-content table, .inner-content h2, .inner-content h3, .inner-content h4, .inner-content h5, .inner-content h6{font-family:sans-serif; color: black}
+.inner-content table {font-family: sans-serif}
+.inner-content h2, .inner-content h3, .inner-content h4, .inner-content h5, .inner-content h6{font-family:sans-serif; color: black; font-weight: normal}
.inner-content h3{margin:0.8em 0}
.inner-content h4{margin:0.6em 0}
.inner-content h5{margin:0.5em 0}
@@ -19,6 +20,9 @@ body{font-family:sans-serif}
.inner-content table > * > tr > th, .inner-content table > tr > th {background-color:#f9f9f9;border:#ccc 1px solid;padding:2px}
.inner-content table > * > tr > td, .inner-content table > tr > td {border:#ccc 1px solid;padding:2px}
+/* spoiler styles */
+.spoiler {color: black; background-color:black}
+.spoiler.revealed {color: #1f2528; background-color: transparent}
/* interface styles */
.nl-list{list-style:none}
@@ -143,6 +147,8 @@ body.dark, .dark input, .dark textarea{background-color: #1f1f1f; color: white}
a.dark-theme-toggle-off{display: none}
.dark a.dark-theme-toggle-off{display: inline}
.dark a.dark-theme-toggle-on{display: none}
+.dark .spoiler {color: white; background-color: white}
+.dark .spoiler.revealed {color: white; background-color: transparent}
/* ?????? */
.wrap_responsive_cells {
diff --git a/templates/edit.html b/templates/edit.html
index eb24311..b7a6089 100644
--- a/templates/edit.html
+++ b/templates/edit.html
@@ -56,4 +56,5 @@
{% block scripts %}
+
{% endblock %}
diff --git a/templates/home.html b/templates/home.html
index f2643aa..c0d4691 100644
--- a/templates/home.html
+++ b/templates/home.html
@@ -7,7 +7,6 @@
{{ T('latest-notes') }}
@@ -31,8 +30,4 @@
{{ T('show-all') }}
-{{ T('latest-uploads') }}
-
-{# TODO security flaw; find a way to do this in a more safe manner! #}
-{{ gallery|safe }}
{% endblock %}
diff --git a/templates/stats.html b/templates/stats.html
index 34ca3ae..1e7ee93 100644
--- a/templates/stats.html
+++ b/templates/stats.html
@@ -8,7 +8,6 @@
Number of pages: {{ notes_count }}
Number of pages with URL set: {{ notes_with_url }}
- Number of uploads: {{ upload_count }}
Number of revisions: {{ revision_count }}
Average revisions per page: {{ (revision_count / notes_count)|round(2) }}
diff --git a/templates/upload.html b/templates/upload.html
index 153c6f8..e3f2266 100644
--- a/templates/upload.html
+++ b/templates/upload.html
@@ -3,41 +3,19 @@
{% block content %}
Upload new file
-Types supported: .jpeg , .jpg , .png .
+Uploads are no more supported. Please use this syntax instead for external images: .
{% endblock %}
-
-{% block scripts %}
-
-{% endblock %}
diff --git a/templates/view.html b/templates/view.html
index eb15f68..cf10fc7 100644
--- a/templates/view.html
+++ b/templates/view.html
@@ -5,29 +5,32 @@
{% block json_info %}{% endblock %}
{% block content %}
-{{ p.title }}
+
+ {{ p.title }}
+
+
-
+ {% block history_nav %}{% endblock %}
-{% block history_nav %}{% endblock %}
+
+ {{ rev.html()|safe }}
+
-
- {{ rev.html()|safe }}
-
+ {% if p.tags %}
+
+
{{ T('tags') }}:
+
+ {% for tag in p.tags %}
+ #{{ tag.name }} ({{ tag.popularity() }})
+ {% endfor %}
+
+
+ {% endif %}
+
-{% if p.tags %}
-
-
{{ T('tags') }}:
-
- {% for tag in p.tags %}
- #{{ tag.name }} ({{ tag.popularity() }})
- {% endfor %}
-
-
-{% endif %}
{% endblock %}
{% block actions %}
@@ -36,3 +39,7 @@
{{ T('last-changed') }} {{ rev.pub_date.strftime('%B %-d, %Y at %H:%M:%S') }} -
{{ T('page-id') }}: {{ p.id }}
{% endblock %}
+
+{% block scripts %}
+
+{% endblock %}