def render_text(text, autocompletes=None, comment=None, unwrap_p=False):
    # Render comment text into HTML.

    import re

    # Put @-mentions in bold.
    if autocompletes:
        text, _ = match_autocompletes(text, autocompletes,
                                      lambda text: "**" + text + "**")

    # Rewrite attachment:### URLs.
    if comment is not None:

        def get_attachment_url(attachment_id):
            try:
                return Attachment.objects.get(
                    id=attachment_id.group(1)).get_absolute_url()
            except:
                return "about:blank"

        text = re.sub("(?<=\()attachment:(\d+)(?=\))", get_attachment_url,
                      text)

    # Render to HTML as if CommonMark.
    import CommonMark
    parsed = CommonMark.Parser().parse(text)
    text = CommonMark.HtmlRenderer({"safe": True}).render(parsed)

    if unwrap_p:
        # If it's a single paragraph, unwrap it.
        text = re.sub(r"^<p>(.*)</p>$", r"\1", text)

    return text
def markdown(text, escape=True):
    parser = CommonMark.Parser()
    ast = parser.parse(text)

    renderer = CommonMark.HtmlRenderer()
    html = renderer.render(ast)
    return html
Example #3
0
    def to_json(self, user=None):
        parser = CommonMark.Parser()
        renderer = CommonMark.HtmlRenderer()
        ast = parser.parse(self.event.abstract)
        abstract = renderer.render(ast)

        data = {
            'title': self.event.title,
            'event_slug': self.event.slug,
            'abstract': abstract,
            'from': self.when.lower.isoformat(),
            'to': self.when.upper.isoformat(),
            'url': str(self.event.get_absolute_url()),
            'id': self.id,
            'speakers': [
                { 'name': speaker.name
                , 'url': str(speaker.get_absolute_url())
                } for speaker in self.event.speakers.all()
            ],
            'bg-color': self.event.event_type.color,
            'fg-color': '#fff' if self.event.event_type.light_text else '#000',
            'event_type': self.event.event_type.slug,
            'location': self.location.slug,
            'location_icon': self.location.icon,
            'timeslots': self.timeslots,
        }

        if user and user.is_authenticated:
            is_favorited = user.favorites.filter(event_instance=self).exists()
            data['is_favorited'] = is_favorited

        return data
Example #4
0
def neomarkdown(markdown_content):
    parser = CommonMark.Parser()
    renderer = CommonMark.HtmlRenderer()
    ast = parser.parse(markdown_content)
    html = renderer.render(ast)
    # json = CommonMark.dumpJSON(ast)
    # CommonMark.dumpAST(ast)
    return html
Example #5
0
 def test_smart_dashes(self):
     md = 'a - b -- c --- d ---- e ----- f'
     EM = '\u2014'
     EN = '\u2013'
     expected_html = ('<p>' + 'a - ' + 'b ' + EN + ' ' + 'c ' + EM + ' ' +
                      'd ' + EN + EN + ' ' + 'e ' + EM + EN + ' ' +
                      'f</p>\n')
     parser = CommonMark.Parser(options=dict(smart=True))
     ast = parser.parse(md)
     renderer = CommonMark.HtmlRenderer()
     html = renderer.render(ast)
     self.assertEqual(html, expected_html)
Example #6
0
def page(name='teemo'):
    exodus_dir = os.path.dirname(os.path.realpath(__file__))
    page = 'pages/%s.md' % name
    path = os.path.join(exodus_dir, page)
    if path.startswith(exodus_dir) and os.path.exists(path):
        with open(str(path)) as p: 
            c = p.read()
            parser = CommonMark.Parser()
            ast = parser.parse(unicode(c, 'utf-8'))
            renderer = CommonMark.HtmlRenderer()
            html = renderer.render(ast)
            return render_template('page.html', page=html)
    else:
        return render_template('404.html'), 404
Example #7
0
def markdown(value):
    # Renders the string using CommonMark in safe mode, which blocks
    # raw HTML in the input and also some links using a blacklist,
    # plus a second pass filtering using a whitelist for allowed
    # tags and URL schemes.

    import CommonMark
    ast = CommonMark.Parser().parse(force_unicode(value))
    html = CommonMark.HtmlRenderer({'safe': True}).render(ast)

    import html5lib, urlparse

    def filter_url(url):
        try:
            urlp = urlparse.urlparse(url)
        except Exception as e:
            # invalid URL
            return None
        if urlp.scheme not in ("http", "https"):
            return None
        return url

    valid_tags = set(
        'strong em a code p h1 h2 h3 h4 h5 h6 pre br hr img ul ol li span blockquote'
        .split())
    valid_tags = set('{http://www.w3.org/1999/xhtml}' + tag
                     for tag in valid_tags)
    dom = html5lib.HTMLParser().parseFragment(html)
    for node in dom.iter():
        if node.tag not in valid_tags and node.tag != 'DOCUMENT_FRAGMENT':
            node.tag = '{http://www.w3.org/1999/xhtml}span'
        for name, val in node.attrib.items():
            if name.lower() in ("href", "src"):
                val = filter_url(val)
                if val is None:
                    node.attrib.pop(name)
                else:
                    node.set(name, val)
            else:
                # No other attributes are permitted.
                node.attrib.pop(name)
    html = html5lib.serialize(dom,
                              quote_attr_values="always",
                              omit_optional_tags=False,
                              alphabetical_attributes=True)

    return safestring.mark_safe(html)
Example #8
0
def main():
    parser = argparse.ArgumentParser(
        description="Process Markdown according to "
        "the CommonMark specification.")
    if sys.version_info < (3, 0):
        reload(sys)  # noqa
        sys.setdefaultencoding('utf-8')
    parser.add_argument('infile',
                        nargs="?",
                        type=argparse.FileType('r'),
                        default=sys.stdin,
                        help="Input Markdown file to parse, defaults to STDIN")
    parser.add_argument('-o',
                        nargs="?",
                        type=argparse.FileType('w'),
                        default=sys.stdout,
                        help="Output HTML/JSON file, defaults to STDOUT")
    parser.add_argument('-a', action="store_true", help="Print formatted AST")
    parser.add_argument('-aj', action="store_true", help="Output JSON AST")
    args = parser.parse_args()
    parser = CommonMark.Parser()
    f = args.infile
    o = args.o
    lines = []
    for line in f:
        lines.append(line)
    data = "".join(lines)
    ast = parser.parse(data)
    if not args.a and not args.aj:
        renderer = CommonMark.HtmlRenderer()
        o.write(renderer.render(ast))
        exit()
    if args.a:
        # print ast
        CommonMark.dumpAST(ast)
        exit()

    # o.write(ast.to_JSON())
    o.write(CommonMark.dumpJSON(ast))
    exit()
Example #9
0
def render_commonmark_template(template, context):
  # Render a CommonMark template to HTML.

  # Replace template tags with Unicode sentinels so that
  # the template tags do not impact CommonMark rendering.
  substitutions = []
  import re
  def replace(m):
      # Record the substitution.
      index = len(substitutions)
      substitutions.append(m.group(0))
      return "\uE000%d\uE001" % index # use Unicode private use area code points
  template = re.sub("{%.*?%}|{{.*?}}", replace, template)

  # Render the CommonMark.

  # Prevent CommonMark from mucking with our sentinels
  # in URLs though - it would otherwise add escaping.
  from CommonMark import inlines
  def urlencode_special(uri):
      import urllib.parse
      return "".join(
          urllib.parse.quote(c, safe="/@:+?=&()%#*,") # this is what CommonMark does
          if c not in "\uE000\uE001" else c # but keep our special codes
          for c in uri)
  inlines.normalize_uri = urlencode_special

  # Render.
  import CommonMark
  template = CommonMark.HtmlRenderer().render(CommonMark.Parser().parse(template))

  # Put the template tags back that we removed prior to running
  # the CommonMark renderer.
  def replace(m):
      return substitutions[int(m.group(1))]
  template = re.sub("\uE000(\d+)\uE001", replace, template)

  # And finally render the Django template.
  return Template(template).render(Context(context))
Example #10
0
 def create(self, options):
     self.parser = CommonMark.Parser()
     self.renderer = CommonMark.HtmlRenderer()
Example #11
0
def init_app(app):
    parser = CommonMark.Parser  # Not an instance because not thread-safe(?)
    renderer = CommonMark.HtmlRenderer({'softbreak': '<br/>'})
    app.extensions['markdown'] = UDataMarkdown(app, parser, renderer)

    app.add_template_filter(mdstrip)
Example #12
0
parser.add_argument('-i',
                    action="store_true",
                    help="Interactive Markdown input mode")
parser.add_argument('-d', action="store_true", help="Debug, trace calls")
parser.add_argument('-np',
                    action="store_true",
                    help="Only print section header, tick, or cross")
parser.add_argument('-s',
                    action="store_true",
                    help="Print percent of tests passed by category")
args = parser.parse_args()

if args.d:
    sys.settrace(trace_calls)

renderer = CommonMark.HtmlRenderer()
parser = CommonMark.Parser()

f = codecs.open("spec.txt", encoding="utf-8")
datalist = []
for line in f:
    datalist.append(line)
data = "".join(datalist)
passed = 0
failed = 0
catStats = {}
examples = []
example_number = 0
current_section = ""
tabChar = '\u2192'
spaceChar = '\u2423'
Example #13
0
def commonmark(value):
    parser = CommonMark.Parser()
    renderer = CommonMark.HtmlRenderer()
    ast = parser.parse(force_text(value))
    return mark_safe(force_text(renderer.render(ast)))
Example #14
0
def show_question(request, task, answered, context, q, EncryptionProvider, set_ephemeral_encryption_cookies):
    # Always hide the fill-out-your-profile blurb on all question pages - it's
    # distracting from answering the question at hand. See task_view.
    request.suppress_prompt_banner = True

    # If this question cannot currently be answered (i.e. dependencies are unmet),
    # then redirect away from this page. If the user is allowed to use the authoring
    # tool, then allow seeing this question so they can edit all questions.
    authoring_tool_enabled = task.module.is_authoring_tool_enabled(request.user)
    is_answerable = (((q not in answered.unanswered) or (q in answered.can_answer)) and (q.key not in answered.was_imputed))
    if not is_answerable and not authoring_tool_enabled:
        return HttpResponseRedirect(task.get_absolute_url())

    # Is there a TaskAnswer for this yet?
    taskq = TaskAnswer.objects.filter(task=task, question=q).first()

    # Display requested question.

    # Is there an answer already? (If this question isn't answerable, i.e. if we're
    # only here because the user is using the authoring tool, then there is no
    # real answer to load.)
    answer = None
    if taskq and is_answerable:
        answer = taskq.get_current_answer()
        if answer and answer.cleared:
            # If the answer is cleared, treat as if it had not been answered.
            answer = None

    # For "module"-type questions, get the Module instance of the tasks that can
    # be an answer to this question, and get the existing Tasks that the user can
    # choose as an answer.
    answer_module = q.answer_type_module
    answer_tasks = []
    if answer_module:
        # The user can choose from any Task instances they have read permission on
        # and that are of the correct Module type.
        answer_tasks = Task.get_all_tasks_readable_by(request.user, request.organization, recursive=True)\
            .filter(module=answer_module)

        # Annotate the instances with whether the user also has write permission.
        for t in answer_tasks:
            t.can_write = t.has_write_priv(request.user)

        # Sort the instances:
        #  first: the current answer, if any
        #  then: tasks defined in the same project as this task
        #  later: tasks defined in projects in the same folder as this task's project
        #  last: everything else by reverse update date
        now = timezone.now()
        current_answer = answer.answered_by_task.first() if answer else None
        answer_tasks = sorted(answer_tasks, key = lambda t : (
            not (t == current_answer),
            not (t.project == task.project),
            not (set(t.project.contained_in_folders.all()) & set(task.project.contained_in_folders.all())),
            now-t.updated,
            ))

    # Add instrumentation event.
    # How many times has this question been shown?
    i_prev_view = InstrumentationEvent.objects\
        .filter(user=request.user, event_type="task-question-show", task=task, question=q)\
        .order_by('-event_time')\
        .first()
    # Save.
    InstrumentationEvent.objects.create(
        user=request.user,
        event_type="task-question-show",
        event_value=(i_prev_view.event_value+1) if i_prev_view else 1,
        module=task.module,
        question=q,
        project=task.project,
        task=task,
        answer=taskq,
    )

    # Indicate for the InstrumentQuestionPageLoadTimes middleware that this is
    # a question page load.
    request._instrument_page_load = {
        "event_type": "task-question-request-duration",
        "module": task.module,
        "question": q,
        "project": task.project,
        "task": task,
        "answer": taskq,
    }

    # Construct the page.
    def render_markdown_field(field, output_format, **kwargs):
        template = q.spec.get(field)
        if not template:
            return None
        if not isinstance(template, str):
            raise ValueError("%s question %s %s is not a string" % (repr(q.module), q.key, field))
        return module_logic.render_content({
                "template": template,
                "format": "markdown",
            },
            answered,
            output_format,
            "%s question %s %s" % (repr(q.module), q.key, field),
            **kwargs
        )

    # Get any existing answer for this question.
    existing_answer = None
    if answer:
        existing_answer = answer.get_value(decryption_provider=EncryptionProvider())

        # For longtext questions, because the WYSIWYG editor is initialized with HTML,
        # render the value as HTML.
        if existing_answer and q.spec["type"] == "longtext":
            import CommonMark
            existing_answer = CommonMark.HtmlRenderer().render(CommonMark.Parser().parse(existing_answer))

    # What's the title/h1 of the page and the rest of the prompt? Render the
    # prompt field. If it starts with a paragraph, turn that paragraph into
    # the title.
    title = q.spec["title"]
    prompt = render_markdown_field("prompt", "html")
    m = re.match(r"^<p>([\w\W]*?)</p>\s*", prompt)
    if m:
        title = m.group(1)
        prompt = prompt[m.end():]

    # Get a default answer for this question. Render Jinja2 template, but don't turn
    # Markdown into HTML for plain text fields. For longtext fields, turn it into
    # HTML because the WYSIWYG editor is initialized with HTML.
    default_answer = render_markdown_field("default",
        "text" if q.spec["type"] != "longtext" else "html",
        demote_headings=False)

    context.update({
        "header_col_active": "start" if (len(answered.as_dict()) == 0 and q.spec["type"] == "interstitial") else "questions",
        "q": q,
        "title": title,
        "prompt": prompt,
        "placeholder_answer": render_markdown_field("placeholder", "text") or "", # Render Jinja2 template but don't turn Markdown into HTML.
        "reference_text": render_markdown_field("reference_text", "html"),
        "history": taskq.get_history() if taskq else None,
        "answer_obj": answer,
        "answer": existing_answer,
        "default_answer": default_answer,
        "review_choices": [(0, 'Not Reviewed'), (1, 'Reviewed'), (2, 'Approved')],
        "discussion": Discussion.get_for(request.organization, taskq) if taskq else None,
        "show_discussion_members_count": True,

        "answer_module": answer_module,
        "answer_tasks": answer_tasks,
        "answer_tasks_show_user": len([ t for t in answer_tasks if t.editor != request.user ]) > 0,

        "context": module_logic.get_question_context(answered, q),

        # Helpers for showing date month, day, year dropdowns, with
        # localized strings and integer values. Default selections
        # are done in the template & client-side so that we can use
        # the client browser's timezone to determine the current date.
        "date_l8n": lambda : {
            "months": [
                (timezone.now().replace(2016,m,1).strftime("%B"), m)
                for m in range(1, 12+1)],
            "days": [
                d
                for d in range(1, 31+1)],
            "years": [
                y
                for y in reversed(range(timezone.now().year-100, timezone.now().year+101))],
        },

        "is_answerable": is_answerable, # only false if authoring tool is enabled, otherwise this page is not renderable
        "authoring_tool_enabled": authoring_tool_enabled,
    })
    return render(request, "question.html", context)
Example #15
0
 def __init__(self, *args, **kwargs):
     super(CompileCommonMark, self).__init__(*args, **kwargs)
     if CommonMark is not None:
         self.parser = CommonMark.Parser()
         self.renderer = CommonMark.HtmlRenderer()
Example #16
0
def commonmark(value):
    """Returns HTML given some CommonMark Markdown. Does not clean HTML, not for use with untrusted input."""
    parser = CommonMark.Parser()
    renderer = CommonMark.HtmlRenderer()
    ast = parser.parse(value)
    return mark_safe(renderer.render(ast))
Example #17
0
def unsafecommonmark(value):
    """Returns HTML given some CommonMark Markdown. Cleans HTML from input using bleach, suitable for use with untrusted input."""
    parser = CommonMark.Parser()
    renderer = CommonMark.HtmlRenderer()
    ast = parser.parse(bleach.clean(value))
    return mark_safe(renderer.render(ast))
 def __init__(self):
     self.path = os.path.join(settings.BASE_DIR, 'NEWS.md')
     self.parser = CommonMark.Parser()
     self.renderer = CommonMark.HtmlRenderer()
     self.cookie_name = 'news_current'
Example #19
0
def trustedcommonmark(value):
    """Returns HTML given some CommonMark Markdown. Also allows real HTML, so do not use this with untrusted input."""
    parser = CommonMark.Parser()
    renderer = CommonMark.HtmlRenderer()
    ast = parser.parse(value)
    return mark_safe(renderer.render(ast))
Example #20
0
 def __init__(self):
     self.parser = CommonMark.Parser()
     self.renderer = CommonMark.HtmlRenderer()