Пример #1
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;
}
Пример #2
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;
}