QString HoedownMarkdownConverter::renderAsHtml(MarkdownDocument *document)
{
    QString html;

    if (document) {
        HoedownMarkdownDocument *doc = dynamic_cast<HoedownMarkdownDocument*>(document);

        if (doc->document()) {
            hoedown_buffer *in = doc->document();
            hoedown_buffer *out = hoedown_buffer_new(64);

            hoedown_renderer *renderer = hoedown_html_renderer_new(0, 16);
            hoedown_markdown *markdown = hoedown_markdown_new(doc->options(), 16, renderer);

            hoedown_markdown_render(out, in->data, in->size, markdown);

            hoedown_markdown_free(markdown);
            hoedown_html_renderer_free(renderer);

            html = QString::fromUtf8(hoedown_buffer_cstr(out));

            hoedown_buffer_free(out);
        }
    }

    return html;
}
Exemplo n.º 2
0
char*
OxMarkDownToHtml(char* sMarkDown)
{
	hoedown_renderer *renderer;
	hoedown_document *document;
	hoedown_buffer *buffer;
	unsigned int extensions = 0, render_flags = 0;
	const uint8_t *sHtml;

	renderer = hoedown_html_renderer_new(render_flags, 0);
	document = hoedown_document_new(renderer, extensions, 16);
	buffer = hoedown_buffer_new(16);
    
	hoedown_document_render(document, buffer, (const uint8_t *)sMarkDown, strlen(sMarkDown));
	sHtml = (char*)OxAllocate(buffer->size + 1);
	StringCchCopyA(sHtml, buffer->size + 1, buffer->data);
	hoedown_buffer_reset(buffer);
	hoedown_html_smartypants(buffer, sHtml, buffer->size);
	
	hoedown_buffer_free(buffer);
	hoedown_document_free(document);
	hoedown_html_renderer_free(renderer);

	return sHtml;
}
void mdRenderer::render(const QString markdownText)
{
    if(markdownText.isEmpty())
    {
        html ="";
        return;
    }

    QByteArray utf8Data = markdownText.toUtf8();
    hoedown_buffer *doc = hoedown_buffer_new(utf8Data.length());
    hoedown_buffer_puts(doc, utf8Data.data());
    hoedown_buffer *out = hoedown_buffer_new(64);

    hoedown_renderer *renderer = hoedown_html_renderer_new(0, 16);
    hoedown_markdown *markdown = hoedown_markdown_new(0, 16, renderer);

    hoedown_markdown_render(out, doc->data, doc->size, markdown);

    hoedown_markdown_free(markdown);
    hoedown_html_renderer_free(renderer);

    html = QString::fromUtf8(hoedown_buffer_cstr(out));

    hoedown_buffer_free(out);

    html="<!DOCTYPE html> <html> <head> <style type=\"text/css\">"+
            style+
            "</style>"+
            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"+
            "</head> <body>"+
            html+
            "</body> </html>";
}
Exemplo n.º 4
0
// Converts markdown to html
QString
Markdown::convert2html(const QString& markdown)
{
    QString html;

    if ( !markdown.isEmpty() ) {
        QString markdownClean = parseCustomLinksForHTML(markdown);

        hoedown_html_flags flags = HOEDOWN_HTML_USE_XHTML;
        hoedown_extensions extensions = (hoedown_extensions)(HOEDOWN_EXT_BLOCK|HOEDOWN_EXT_SPAN|HOEDOWN_EXT_FLAGS);
        size_t max_nesting = 16;
        hoedown_renderer *renderer = hoedown_html_renderer_new(flags, 0);
        hoedown_document *document = hoedown_document_new(renderer, extensions, max_nesting);
        hoedown_buffer *result = hoedown_buffer_new(max_nesting);
        std::string markdownStr = markdownClean.toStdString();
        hoedown_document_render( document, result, reinterpret_cast<const uint8_t*>(&markdownStr[0]), markdownStr.size() );

        std::ostringstream convert;
        for (size_t x = 0; x < result->size; x++) {
            convert << result->data[x];
        }

        html = QString::fromStdString( convert.str() );

        hoedown_buffer_free(result);
        hoedown_document_free(document);
        hoedown_html_renderer_free(renderer);
    }

    return html;
}
Exemplo n.º 5
0
//
// return html rendered markdown of note text
//
QString Note::toMarkdownHtml() {
    hoedown_renderer *renderer = hoedown_html_renderer_new( HOEDOWN_HTML_USE_XHTML, 16 );
    hoedown_document *document = hoedown_document_new(renderer, (hoedown_extensions) HOEDOWN_EXT_SPAN, 16);

    QString str = this->noteText;

    unsigned char *sequence = (unsigned char*)qstrdup( str.toUtf8().constData() );
    int length = strlen( (char*) sequence );

    // return an empty string if the note is empty
    if ( length == 0 )
    {
        return "";
    }

    hoedown_buffer *html = hoedown_buffer_new( length );

    // render markdown html
    hoedown_document_render( document, html, sequence, length );

    // get markdown html
    QString result = QString::fromUtf8( (char*) html->data, html->size );

    /* Cleanup */
    free(sequence);
    hoedown_buffer_free(html);

    hoedown_document_free(document);
    hoedown_html_renderer_free(renderer);

    return result;
}
Exemplo n.º 6
0
QByteArray HoedownMarkdownConverterPrivate::markdown2Html(const QByteArray &markdownText) const {

    int markdownLength = markdownText.size();

    if(markdownLength == 0) {
        return QByteArray("");
    }

    hoedown_buffer *ib, *ob;
    hoedown_renderer *renderer = NULL;
    hoedown_document *document;

    // malloc
    ob = hoedown_buffer_new(markdownLength);
    ib = hoedown_buffer_new(markdownLength);
    renderer = hoedown_html_renderer_new(HOEDOWN_HTML_USE_XHTML, 0);

/*
typedef enum hoedown_extensions {
    // block-level extensions
    HOEDOWN_EXT_TABLES = (1 << 0),
    HOEDOWN_EXT_FENCED_CODE = (1 << 1),
    HOEDOWN_EXT_FOOTNOTES = (1 << 2),

    // span-level extensions
    HOEDOWN_EXT_AUTOLINK = (1 << 3),
    HOEDOWN_EXT_STRIKETHROUGH = (1 << 4),
    HOEDOWN_EXT_UNDERLINE = (1 << 5),
    HOEDOWN_EXT_HIGHLIGHT = (1 << 6),
    HOEDOWN_EXT_QUOTE = (1 << 7),
    HOEDOWN_EXT_SUPERSCRIPT = (1 << 8),
    HOEDOWN_EXT_MATH = (1 << 9),

    // other flags
    HOEDOWN_EXT_NO_INTRA_EMPHASIS = (1 << 11),
    HOEDOWN_EXT_SPACE_HEADERS = (1 << 12),
    HOEDOWN_EXT_MATH_EXPLICIT = (1 << 13),

    // negative flags
    HOEDOWN_EXT_DISABLE_INDENTED_CODE = (1 << 14)
} hoedown_extensions;
*/
    // 尽可能的指定
    document = hoedown_document_new(renderer, HOEDOWN_EXT_TABLES, 16);

    // put data
    hoedown_buffer_put(ib, (const uint8_t *) markdownText.toStdString().c_str(), markdownText.size());

    // render markdown to html
    hoedown_document_render(document, ob, ib->data, ib->size);

    QByteArray html((const char*)ob->data, ob->size);

    // free
    hoedown_buffer_free(ib);
    hoedown_document_free(document);
    hoedown_html_renderer_free(renderer);
    hoedown_buffer_free(ob);

    return html;
}
Exemplo n.º 7
0
/**
 * @brief Returns html rendered markdown of the note text
 * @param notesPath for transforming relative local urls to absolute ones
 * @param maxImageWidth defined maximum image width (ignored if forExport is true)
 * @param forExport defines whether the export or preview stylesheet
 * @return
 */
QString Note::toMarkdownHtml(QString notesPath, int maxImageWidth, bool forExport) {
    hoedown_renderer *renderer =
            hoedown_html_renderer_new(HOEDOWN_HTML_USE_XHTML, 16);
    hoedown_extensions extensions =
            (hoedown_extensions) (HOEDOWN_EXT_BLOCK | HOEDOWN_EXT_SPAN);
    hoedown_document *document = hoedown_document_new(renderer, extensions, 16);

    // get the decrypted note text (or the normal note text if there isn't any)
    QString str = getDecryptedNoteText();

    QString windowsSlash = "";

#ifdef Q_OS_WIN32
    // we need an other slash for Windows
    windowsSlash = "/";
#endif

    // parse for relative file urls and make them absolute
    // (for example to show images under the note path)
    str.replace(
            QRegularExpression("\\(file:\\/\\/([^\\/].+)\\)"),
            "(file://" + windowsSlash + notesPath + "/\\1)");

    unsigned char *sequence = (unsigned char *) qstrdup(
            str.toUtf8().constData());
    qint64 length = strlen((char *) sequence);

    // return an empty string if the note is empty
    if (length == 0) {
        return "";
    }

    hoedown_buffer *html = hoedown_buffer_new(length);

    // render markdown html
    hoedown_document_render(document, html, sequence, length);

    // get markdown html
    QString result = QString::fromUtf8((char *) html->data, html->size);

    /* Cleanup */
    free(sequence);
    hoedown_buffer_free(html);

    hoedown_document_free(document);
    hoedown_html_renderer_free(renderer);

    QSettings(settings);
    QString fontString = settings.value("MainWindow/noteTextView.code.font")
            .toString();

    // set the stylesheet for the <code> blocks
    QString codeStyleSheet = "";
    if (fontString != "") {
        // set the note text view font
        QFont font;
        font.fromString(fontString);

        // add the font for the code block
        codeStyleSheet = QString(
                "pre, code { %1; }").arg(encodeCssFont(font));
    }

    bool darkModeColors = settings.value("darkModeColors").toBool();

    QString codeBackgroundColor = darkModeColors ? "#444444" : "#f1f1f1";

    // do some more code formatting
    codeStyleSheet += QString(
            "pre, code { padding: 16px; overflow: auto;"
                    " line-height: 1.45em; background-color: %1;"
                    " border-radius: 3px; }").arg(codeBackgroundColor);

    // remove double code blocks
    result.replace("<pre><code>", "<pre>")
            .replace("</code></pre>", "</pre>");

    if (forExport) {
        // get defined body font from settings
        QString bodyfontString = settings.value("MainWindow/noteTextView.font")
                .toString();

        // create export stylesheet
        QString exportStyleSheet = "";
        if (bodyfontString != "") {
            QFont bodyFont;
            bodyFont.fromString(bodyfontString);

            exportStyleSheet = QString(
                    "body { %1; }").arg(encodeCssFont(bodyFont));
        }

        result = QString("<html><head><meta charset=\"utf-8\"/><style>"
                    "h1 { margin: 5px 0 20px 0; }"
                    "h2, h3 { margin: 10px 0 15px 0; }"
                    "img { max-width: 100%; }"
                    "a { color: #FF9137; text-decoration: none; } %1 %2"
                    "</style></head><body>%3</body></html>")
            .arg(codeStyleSheet, exportStyleSheet, result);
    } else {
        // for preview
        result = QString("<html><head><style>"
                    "h1 { margin: 5px 0 20px 0; }"
                    "h2, h3 { margin: 10px 0 15px 0; }"
                    "a { color: #FF9137; text-decoration: none; } %1"
                    "</style></head><body>%2</body></html>")
            .arg(codeStyleSheet, result);
    }

    // check if width of embedded local images is too high
    QRegularExpression re("<img src=\"file:\\/\\/([^\"]+)\"");
    QRegularExpressionMatchIterator i = re.globalMatch(result);
    while (i.hasNext()) {
        QRegularExpressionMatch match = i.next();
        QString fileName = match.captured(1);

#ifdef Q_OS_WIN
        // remove the leading slash under Windows to get a more correct filename
        QImage image(Utils::Misc::removeIfStartsWith(fileName, "/"));
#else
        QImage image(fileName);
#endif

        if (forExport) {
            result.replace(
                    QRegularExpression("<img src=\"file:\\/\\/" +
                                       QRegularExpression::escape(fileName) +
                                       "\""),
                    QString("<img src=\"file://%2\"").arg(fileName));
        } else {
            // for preview
            // cap the image width at 980px or the note text view width
            if (image.width() > maxImageWidth) {
                result.replace(
                        QRegularExpression("<img src=\"file:\\/\\/" +
                                           QRegularExpression::escape(fileName) +
                                           "\""),
                        QString("<img width=\"%1\" src=\"file://%2\"").arg(
                                QString::number(maxImageWidth), fileName));
            }
        }
    }

    // check if there is a script that wants to modify the content
    QString scriptResult = ScriptingService::instance()
            ->callNoteToMarkdownHtmlHook(this, result);

    if (!scriptResult.isEmpty()) {
        result = scriptResult;
    }

    return result;
}
Exemplo n.º 8
0
/**
 * @brief Returns html rendered markdown of the note text
 * @param notesPath for transforming relative local urls to absolute ones
 * @return
 */
QString Note::toMarkdownHtml(QString notesPath) {
    hoedown_renderer *renderer =
            hoedown_html_renderer_new(HOEDOWN_HTML_USE_XHTML, 16);
    hoedown_extensions extensions =
            (hoedown_extensions) (HOEDOWN_EXT_BLOCK | HOEDOWN_EXT_SPAN);
    hoedown_document *document = hoedown_document_new(renderer, extensions, 16);

    // get the decrypted note text (or the normal note text if there isn't any)
    QString str = getDecryptedNoteText();

    QString windowsSlash = "";

#ifdef Q_OS_WIN32
    // we need an other slash for Windows
    windowsSlash = "/";
#endif

    // parse for relative file urls and make them absolute
    // (for example to show images under the note path)
    str.replace(
            QRegularExpression("\\(file:\\/\\/([^\\/].+)\\)"),
            "(file://" + windowsSlash + notesPath + "/\\1)");

    unsigned char *sequence = (unsigned char *) qstrdup(
            str.toUtf8().constData());
    qint64 length = strlen((char *) sequence);

    // return an empty string if the note is empty
    if (length == 0) {
        return "";
    }

    hoedown_buffer *html = hoedown_buffer_new(length);

    // render markdown html
    hoedown_document_render(document, html, sequence, length);

    // get markdown html
    QString result = QString::fromUtf8((char *) html->data, html->size);

    /* Cleanup */
    free(sequence);
    hoedown_buffer_free(html);

    hoedown_document_free(document);
    hoedown_html_renderer_free(renderer);

    QSettings(settings);
    QString fontString = settings.value("MainWindow/noteTextView.code.font")
            .toString();

    // set the stylesheet for the <code> blocks
    QString codeStyleSheet = "";
    if (fontString != "") {
        // set the note text view font
        QFont font;
        font.fromString(fontString);

        codeStyleSheet = "pre, code {" + encodeCssFont(font) + "}";
    }

    result = "<html><head>"
                    "<style>h1, h2, h3 { margin: 5pt 0 10pt 0; }"
                    "a { color: #FF9137; text-decoration: none; }" +
            codeStyleSheet + "</style></head><body>" +
            result + "</body></html>";

    // check if width of embedded local images is too high
    QRegularExpression re("<img src=\"file:\\/\\/([^\"]+)\"");
    QRegularExpressionMatchIterator i = re.globalMatch(result);
    while (i.hasNext()) {
        QRegularExpressionMatch match = i.next();
        QString fileName = match.captured(1);
        QImage image(fileName);

        // cap the image width at 980px
        if (image.width() > 980) {
            result.replace(
                    QRegularExpression("<img src=\"file:\\/\\/" +
                                       QRegularExpression::escape(fileName) +
                                       "\""),
                    "<img width=\"980\" src=\"file://" + fileName + "\"");
        }
    }

    return result;
}
Exemplo n.º 9
0
/**
 * @brief Returns html rendered markdown of the note text
 * @param notesPath for transforming relative local urls to absolute ones
 * @return
 */
QString Note::toMarkdownHtml(QString notesPath) {
    hoedown_renderer *renderer =
            hoedown_html_renderer_new(HOEDOWN_HTML_USE_XHTML, 16);
    hoedown_extensions extensions =
            (hoedown_extensions) (HOEDOWN_EXT_BLOCK | HOEDOWN_EXT_SPAN);
    hoedown_document *document = hoedown_document_new(renderer, extensions, 16);

    // get the decrypted note text (or the normal note text if there isn't any)
    QString str = getDecryptedNoteText();

    // parse for relative file urls and make them absolute
    // (for example to show images under the note path)
    str.replace(
            QRegularExpression("\\(file:\\/\\/([^\\/].+)\\)"),
            "(file://" + notesPath + "/\\1)");

    unsigned char *sequence = (unsigned char *) qstrdup(str.toUtf8().constData());
    int length = strlen((char *) sequence);

    // return an empty string if the note is empty
    if (length == 0) {
        return "";
    }

    hoedown_buffer *html = hoedown_buffer_new(length);

    // render markdown html
    hoedown_document_render(document, html, sequence, length);

    // get markdown html
    QString result = QString::fromUtf8((char *) html->data, html->size);

    /* Cleanup */
    free(sequence);
    hoedown_buffer_free(html);

    hoedown_document_free(document);
    hoedown_html_renderer_free(renderer);

    result =
            "<html><head><style>h1, h2, h3 { margin: 5pt 0 10pt 0; }"
            "a { color: #FF9137; text-decoration: none; }</style></head><body>" +
            result + "</body></html>";

    // check if width of embedded local images is too high
    QRegularExpression re("<img src=\"file:\\/\\/([^\"]+)\"");
    QRegularExpressionMatchIterator i = re.globalMatch(result);
    while (i.hasNext()) {
        QRegularExpressionMatch match = i.next();
        QString fileName = match.captured(1);
        QImage image(fileName);

        // cap the image width at 980px
        if (image.width() > 980) {
            result.replace(
                    QRegularExpression("<img src=\"file:\\/\\/" + QRegularExpression::escape(fileName) + "\""),
                           "<img width=\"980\" src=\"file://" + fileName + "\"");
        }
    }

    return result;
}