예제 #1
0
 def render_gfm_to_html(self, markdown_text: str) -> str:
     """Render given Github Flavored Markdown to HTML."""
     try:
         html = cmarkgfm.github_flavored_markdown_to_html(markdown_text)
         return html
     except ValueError as e:
         raise TrestleError(f'Not a valid Github Flavored markdown: {e}.')
예제 #2
0
def markdownify(content):
    html = cmarkgfm.github_flavored_markdown_to_html(content)

    return bleach.clean(
        text=html,
        tags=settings.BLEACH_ALLOWED_TAGS,
        attributes=settings.BLEACH_ALLOWED_ATTRIBUTES,
        strip_comments=False,
    )
예제 #3
0
파일: action.py 프로젝트: ctreffe/alfred
 def template_data(self):
     d = super().template_data
     text = emojize(self.text, use_aliases=True)
     text = cmarkgfm.github_flavored_markdown_to_html(
         text, options=cmarkgfmOptions.CMARK_OPT_UNSAFE)
     d["text"] = text
     d["button_block"] = "btn-block" if self.button_block else ""
     d["button_style"] = self.button_style
     return d
예제 #4
0
    def post(self, request, invitation_id=None):
        '''
        - Takes an invitation
        - generates an email with a link to the registration form that will redeem that invitation
        - sends the email
        - sets the sent_time on the invitation
        '''
        invitation = get_object_or_404(models.Invitation, id=invitation_id)
        to_name = invitation.recipient_name
        to_email = invitation.recipient_email
        event = invitation.registration_type.event
        invitation_body_text = chevron.render(
            invitation.registration_type.invitation_email_template, {
                'recipient_name': to_name or to_email,
                'recipient_email': to_email,
                'invitation_code': invitation.invitation_code,
                'register_link': register_page_url(request, event.id,
                                                   invitation)
            })
        invitation_body_html = cmarkgfm.github_flavored_markdown_to_html(
            invitation_body_text)

        email_error = None
        sent = False
        try:
            if '@dontsend.com' in to_email:
                email_error = 'invitation email contains @dontsend.com'
                logger.error(invitation_body_html)
            else:
                msg = EmailMultiAlternatives(
                    invitation.registration_type.invitation_email_subject,
                    invitation_body_text,
                    event.
                    confirmation_email_from,  # TODO: figure out what this should be
                    [f'"{to_name}" <{to_email}>' if to_name else to_email])
                msg.attach_alternative(invitation_body_html, "text/html")
                sent = msg.send(fail_silently=False)
                if not sent:
                    email_error = 'mail not sent'
        except SMTPException as e:
            email_error = str(e)

        if email_error:
            return Response({"detail": email_error},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        invitation.sent_time = timezone.now()
        invitation.save()

        return Response({
            'success': True,
        })
예제 #5
0
    def render_text(self, text: str) -> str:
        """
        Renders the markdown and emoji shortcodes in :attr:`.text`

        Returns:
            str: Text rendered to html code
        """

        if self.emojize:
            text = emojize(text, use_aliases=True)
        if self.render_markdown:
            text = cmarkgfm.github_flavored_markdown_to_html(
                text, options=cmarkgfmOptions.CMARK_OPT_UNSAFE
            )
        return text
예제 #6
0
    def view_writeup(writeup_id: int):
        user = get_current_user()
        writeup = db.session.query(Submissions).get(writeup_id)
        error = {}
        content = ''
        editable = False

        if writeup.challenge.type != 'writeup':
            return redirect(url_for('writeups.writeups'))

        challenge = (db.session.query(Challenges).filter(
            Challenges.type != 'writeup').filter(
                Challenges.writeup_challenge ==
                writeup.challenge).one_or_none())

        if not challenge or not challenge.writeup_challenge:
            return redirect(url_for('writeups.writeups'))

        if (user.type == 'admin' or not challenge.writeup_challenge.solve_req
                or (user.team and
                    (challenge.id in (s.challenge_id
                                      for s in user.team.solves)))
                or (challenge.id in (s.challenge_id for s in user.solves))
                or writeup.user.id == user.id):
            content = cmarkgfm.github_flavored_markdown_to_html(
                writeup.provided, options=cmarkgfmOptions.CMARK_OPT_SAFE)
            if writeup.user.id == user.id or user.type == 'admin':
                editable = True
        else:
            error = {
                'heading':
                '403',
                'msg':
                'Sorry, you must solve this challenge before viewing write-ups for it'
            }
        return render_template("view_writeup.html",
                               challenge=challenge,
                               content=content,
                               error=error,
                               user=writeup.user,
                               editable=editable)
예제 #7
0
파일: messages.py 프로젝트: ctreffe/alfred
 def title(self):
     text = emojize(self._title)
     return cmarkgfm.github_flavored_markdown_to_html(
         text, options=cmarkgfmOptions.CMARK_OPT_UNSAFE)
예제 #8
0
import pygments.formatters

from .clean import clean

_EXTRA_WARNING = (
    "Markdown renderers are not available. "
    "Install 'readme_renderer[md]' to enable Markdown rendering.")

try:
    import cmarkgfm
    from cmarkgfm.cmark import Options as cmarkgfmOptions
    variants: Dict[str, Callable[[str], str]] = {
        "GFM":
        lambda raw: cast(
            str,
            cmarkgfm.github_flavored_markdown_to_html(
                raw, options=cmarkgfmOptions.CMARK_OPT_UNSAFE)),
        "CommonMark":
        lambda raw: cast(
            str,
            cmarkgfm.markdown_to_html(
                raw, options=cmarkgfmOptions.CMARK_OPT_UNSAFE)),
    }
except ImportError:
    warnings.warn(_EXTRA_WARNING)
    variants = {}

# Make code fences with `python` as the language default to highlighting as
# Python 3.
_LANG_ALIASES = {
    'python': 'python3',
}
예제 #9
0
#!/usr/bin/env python
import cmarkgfm
import sys

fname = sys.argv[1]
f = open(fname, 'r')
md_text = f.read()
html = cmarkgfm.github_flavored_markdown_to_html(md_text).encode('utf8')
print(html)
예제 #10
0
                    dest='in_file',
                    required=True,
                    help='Input file')
parser.add_argument('-o,--output',
                    dest='out_file',
                    required=True,
                    help='Output file')

args = parser.parse_args()

# Read the markdown document
with open(args.in_file, 'r') as f:
    markdown = f.read()

# Convert to HTML
html = cmarkgfm.github_flavored_markdown_to_html(markdown)

# TODO: Get lexer name from class name and dynamically import the lexer (probably need a name-to-lexer map)
soup = BeautifulSoup(html, features="html.parser")
r = re.compile('language-(.+)')
for m in soup.find_all('code', class_=r):
    # [idx for idx, c in enumerate(m.attrs['class']) if r.match(c)][0]
    lexer_from_class = [
        r.match(i)[1] for i in m.attrs['class'] if 'language' in i
    ][0]

    # Try to find the lexer
    try:
        lexer = get_lexer_by_name(lexer_from_class)
    except:
        print('Lexer {0} not found'.format(lexer_from_clas))
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 cmarkgfm
    from cmarkgfm.cmark import Options as cmarkgfmOptions

    html = cmarkgfm.github_flavored_markdown_to_html(
        value, options=cmarkgfmOptions.CMARK_OPT_SAFE)

    import html5lib, urllib.parse

    def filter_url(url):
        try:
            urlp = urllib.parse.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 list(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)

    # If there is an h1 in the output, demote all of the headings
    # so we don't create something that interfere's with the page h1.
    hash1 = False
    for node in dom.iter():
        if node.tag in ("h1", "{http://www.w3.org/1999/xhtml}h1"):
            hash1 = True
    if hash1:
        for node in dom.iter():
            m = re.match("(\{http://www.w3.org/1999/xhtml\})?h(\d)$", node.tag)
            if m:
                node.tag = (m.group(1) or "") + "h" + str(int(m.group(2)) + 1)

    html = html5lib.serialize(dom,
                              quote_attr_values="always",
                              omit_optional_tags=False,
                              alphabetical_attributes=True)

    return safestring.mark_safe(html)
예제 #12
0
    def post(self, request, event_id=None, format=None):
        event = get_object_or_404(models.Event, id=event_id)

        form_data = request.data.get('formData')
        if form_data is None:
            raise ValidationError({'formData': 'This field is required.'})
        client_reported_pricing = request.data.get('pricingResults')
        if client_reported_pricing is None:
            raise ValidationError(
                {'pricingResults': 'This field is required.'})
        self.validate_form_data(event, form_data)

        registration, campers = self.deserialize_form_data(event, form_data)

        invitation = None
        try:
            invitation = self.find_invitation(request)
        except InvitationError as e:
            raise ValidationError(e.user_message)
        if invitation:
            registration.registration_type = invitation.registration_type

        server_pricing_results = pricing.calculate_price(registration, campers)
        registration.server_pricing_results = server_pricing_results
        registration.client_reported_pricing = client_reported_pricing
        registration.save()

        if invitation:
            invitation.registration = registration
            invitation.save()

        campers_template_value = []
        for camper_index, camper in enumerate(campers):
            campers_template_value.append({
                **camper.attributes,
                'pricing_result':
                server_pricing_results['campers'][camper_index],
            })
            camper.save()

        confirmation_email_body_text = chevron.render(
            event.confirmation_email_template, {
                'registration': registration.attributes,
                'campers': campers_template_value,
                'pricing_results': server_pricing_results,
            })

        confirmation_email_body_html = cmarkgfm.github_flavored_markdown_to_html(
            confirmation_email_body_text)
        email_error = None
        sent = False
        try:
            if '@dontsend.com' in registration.registrant_email:
                email_error = 'registration email contains @dontsend.com'
                logger.error(confirmation_email_body_html)
            else:
                msg = EmailMultiAlternatives(event.confirmation_email_subject,
                                             confirmation_email_body_text,
                                             event.confirmation_email_from,
                                             [registration.registrant_email])
                msg.attach_alternative(confirmation_email_body_html,
                                       "text/html")
                sent = msg.send(fail_silently=False)

            if not sent:
                email_error = email_error or 'mail not sent'
        except SMTPException as e:
            email_error = str(e)

        if email_error:
            logger.error(f'error sending confirmation email: {email_error}')

        return Response({
            'confirmationPageTemplate': event.confirmation_page_template,
            'serverPricingResults': server_pricing_results,
            'emailError': bool(email_error),
        })