diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..0942a76 --- /dev/null +++ b/__init__.py @@ -0,0 +1,103 @@ +import creole +from django.conf import settings +from django.urls.base import reverse +from .help import MYCREOLE_HELP +import importlib +import os +import shutil + + +def get_full_path(rel_path): + try: + return os.path.join(settings.MYCREOLE_ROOT, *rel_path.split('/')) + except AttributeError: + raise AttributeError("You need to define a root directory for mycreole in settings.py: MYCREOLE_ROOT") + + +def delete_attachment_target_path(attachment_target_path): + shutil.rmtree(get_full_path(attachment_target_path), True) + + +def mycreole_help_pagecontent(): + return creole.creole2html(MYCREOLE_HELP) + + +def render_simple(text): + return creole.creole2html(text) + + +def render(request, text, attachment_target_path, next_anchor=''): + def get_attachment_name(text, state): + end_idx = text.index(']]' if state == '[' else '}}') + try: + split_idx = text.index('|') + except ValueError: + split_idx = len(text) + return text[:min(end_idx, split_idx)] + + # Call the additional filters before rendering + try: + ext_filters = settings.MYCREOLE_EXT_FILTERS + except AttributeError: + pass # No filters defined + else: + for function_string in ext_filters: + m_name, f_name = function_string.rsplit('.', 1) + try: + mod = importlib.import_module(m_name) + except ModuleNotFoundError: + pass + else: + try: + func = getattr(mod, f_name) + except AttributeError: + pass + else: + text = func(text) + + if not attachment_target_path.endswith('/'): + attachment_target_path += '/' + try: + render_txt = '' + while len(text) > 0: + try: + link_pos = text.index('[[attachment:') + except ValueError: + link_pos = len(text) + try: + embed_pos = text.index('{{attachment:') + except ValueError: + embed_pos = len(text) + pos = min(link_pos, embed_pos) + render_txt += text[:pos] + text = text[pos + 13:] + if link_pos != embed_pos: + if link_pos < embed_pos: + state = '[' + else: + state = '{' + attachment_name = get_attachment_name(text, state) + text = text[len(attachment_name):] + rel_path = attachment_target_path + attachment_name + if os.path.isfile(get_full_path(rel_path)): + render_txt += 2 * state + url_attachment(rel_path) + else: + render_txt += '[[%s|Upload]]' % url_upload(request, rel_path, next_anchor) + text = text[text.index(']]' if state == '[' else '}}') + 2:] + return creole.creole2html(render_txt) + except: + return creole.creole2html(text) + + +def url_upload(request, rel_path, next_anchor=''): + nxt = request.GET.get('next', request.get_full_path()) + return reverse('mycreole-upload', kwargs={'rel_path': rel_path}) + '?next=%s' % nxt + ('' if not next_anchor else '#%s' % next_anchor) + + +def url_attachment(rel_path): + return reverse('mycreole-attachment', kwargs={'rel_path': rel_path}) + + +def url_manage_uploads(request, rel_path): + nxt = request.GET.get('next', request.get_full_path()) + return reverse('mycreole-manageuploads', kwargs={'rel_path': rel_path}) + '?next=%s' % nxt diff --git a/admin.py b/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps.py b/apps.py new file mode 100644 index 0000000..edccf61 --- /dev/null +++ b/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class MycreoleConfig(AppConfig): + name = 'mycreole' diff --git a/context.py b/context.py new file mode 100644 index 0000000..298ca0a --- /dev/null +++ b/context.py @@ -0,0 +1,11 @@ +from users.context import menubar as user_menubar +import themes + + +def context_adaption(context, request, title, **kwargs): + context.set_additional_title(title) + user_menubar(context[context.MENUBAR], request) + context[context.NAVIGATIONBAR].append_entry(*themes.empty_entry_parameters(request)) + context[context.ACTIONBAR].append_entry(*themes.empty_entry_parameters(request)) + for key in kwargs: + context[key] = kwargs[key] diff --git a/help.py b/help.py new file mode 100644 index 0000000..961d8e9 --- /dev/null +++ b/help.py @@ -0,0 +1,118 @@ +MYCREOLE_HELP = """\ += Creole Markup + +The Fields //"Description"// and //"Name"// of Tasks and Projects are interpreted as creole. \ +See http://www.wikicreole.org for more details. + +== Text Markup +| =Name | =Syntax | =Result | +| Normal | {{{text}}} | text | +| Bold | {{{**text**}}} | **text** | +| Italics | {{{//text//}}} | //text// | +| Underline | {{{__text__}}} | __text__ | +| Raw Link | {{{https://python.org}}} | https://python.org | +| Text Link | {{{[[https://python.org|Python]]}}} | [[https://python.org|Python]] | +| Image | {{{ {{/media/theme/logo.png|logo}} }}} | {{/media/theme/logo.png|logo}} | +| Attachment Text Link | {{{[[attachment:file.ext|Python]]}}} | | +| Attachment Image | {{{ {{attachment:logo.png|logo}} }}} | | + +== Paragraph Markup +=== Bullet List +{{{ +* Entry One +* Entry Two +** Subentry Two.One +}}} +results in: +* Entry One +* Entry Two +** Subentry Two.One + +=== Numbered List +{{{ +# Entry One +# Entry Two +## Subentry Two.One +}}} +results in: +# Entry One +# Entry Two +## Subentry Two.One + +=== Headings +{{{ = Large Heading }}} +results in: += Large Heading + +{{{ == Medium Heading }}} +results in: +== Medium Heading + +{{{ === Small Heading }}} +results in: +=== Small Heading + +=== Line Break +{{{ +Multiple +line text +}}} +results in: + +Multiple +line text + +=== No Line Break +{{{ +Single \\ +Line +}}} +results in: + +Single \ +Line + +=== Paragraph +{{{ +Part 1 + +Part 2 +}}} +results in: + +Part 1 + +Part 2 + +=== Horizontal Line +{{{ +---- +}}} +results in: +---- + +=== Table +{{{ +| =Header 1 | =Header 2 | =Header 3 | +| body row 1 | column 2 | column 3 | +| body row 2 | - | - | + +}}} +results in: + +| =Header 1 | =Header 2 | =Header 3 | +| body row 1 | column 2 | column 3 | +| body row 2 | - | - | + +=== Unprocessed (raw) Text +{{{ +{{{ +unprocessde data!