mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
bugfix: highlight links and images with spaces in URL
It is said that URL should not contain spaces. Anyway, we use regular expression syntax highlighting to complement PEG Markdown Highlight. Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
parent
0c0fdfcbf1
commit
180ab46367
@ -1,12 +1,3 @@
|
|||||||
/* PEG Markdown Highlight
|
|
||||||
* Copyright 2011-2016 Ali Rantakari -- http://hasseg.org
|
|
||||||
* Licensed under the GPL2+ and MIT licenses (see LICENSE for more info).
|
|
||||||
*
|
|
||||||
* highlighter.cpp
|
|
||||||
*
|
|
||||||
* Qt 4.7 example for highlighting a rich text widget.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include "hgmarkdownhighlighter.h"
|
#include "hgmarkdownhighlighter.h"
|
||||||
@ -36,9 +27,13 @@ HGMarkdownHighlighter::HGMarkdownHighlighter(const QVector<HighlightingStyle> &s
|
|||||||
codeBlockEndExp = QRegExp("^(\\s)*```$");
|
codeBlockEndExp = QRegExp("^(\\s)*```$");
|
||||||
codeBlockFormat.setForeground(QBrush(Qt::darkYellow));
|
codeBlockFormat.setForeground(QBrush(Qt::darkYellow));
|
||||||
for (int index = 0; index < styles.size(); ++index) {
|
for (int index = 0; index < styles.size(); ++index) {
|
||||||
if (styles[index].type == pmh_VERBATIM) {
|
const pmh_element_type &eleType = styles[index].type;
|
||||||
|
if (eleType == pmh_VERBATIM) {
|
||||||
codeBlockFormat = styles[index].format;
|
codeBlockFormat = styles[index].format;
|
||||||
break;
|
} else if (eleType == pmh_LINK) {
|
||||||
|
m_linkFormat = styles[index].format;
|
||||||
|
} else if (eleType == pmh_IMAGE) {
|
||||||
|
m_imageFormat = styles[index].format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +72,16 @@ void HGMarkdownHighlighter::highlightBlock(const QString &text)
|
|||||||
setFormat(unit.start, unit.length, highlightingStyles[unit.styleIndex].format);
|
setFormat(unit.start, unit.length, highlightingStyles[unit.styleIndex].format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCurrentBlockState(HighlightBlockState::BlockNormal);
|
|
||||||
|
// We use PEG Markdown Highlight as the main highlighter.
|
||||||
|
// We can use other highlighting methods to complement it.
|
||||||
|
|
||||||
|
// PEG Markdown Highlight does not handle the ``` code block correctly.
|
||||||
|
setCurrentBlockState(HighlightBlockState::Normal);
|
||||||
highlightCodeBlock(text);
|
highlightCodeBlock(text);
|
||||||
|
|
||||||
|
// PEG Markdown Highlight does not handle links with spaces in the URL.
|
||||||
|
highlightLinkWithSpacesInURL(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HGMarkdownHighlighter::setStyles(const QVector<HighlightingStyle> &styles)
|
void HGMarkdownHighlighter::setStyles(const QVector<HighlightingStyle> &styles)
|
||||||
@ -177,7 +180,7 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
|
|||||||
{
|
{
|
||||||
int nextIndex = 0;
|
int nextIndex = 0;
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
if (previousBlockState() != HighlightBlockState::BlockCodeBlock) {
|
if (previousBlockState() != HighlightBlockState::CodeBlock) {
|
||||||
startIndex = codeBlockStartExp.indexIn(text);
|
startIndex = codeBlockStartExp.indexIn(text);
|
||||||
if (startIndex >= 0) {
|
if (startIndex >= 0) {
|
||||||
nextIndex = startIndex + codeBlockStartExp.matchedLength();
|
nextIndex = startIndex + codeBlockStartExp.matchedLength();
|
||||||
@ -190,7 +193,7 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
|
|||||||
int endIndex = codeBlockEndExp.indexIn(text, nextIndex);
|
int endIndex = codeBlockEndExp.indexIn(text, nextIndex);
|
||||||
int codeBlockLength;
|
int codeBlockLength;
|
||||||
if (endIndex == -1) {
|
if (endIndex == -1) {
|
||||||
setCurrentBlockState(HighlightBlockState::BlockCodeBlock);
|
setCurrentBlockState(HighlightBlockState::CodeBlock);
|
||||||
codeBlockLength = text.length() - startIndex;
|
codeBlockLength = text.length() - startIndex;
|
||||||
} else {
|
} else {
|
||||||
codeBlockLength = endIndex - startIndex + codeBlockEndExp.matchedLength();
|
codeBlockLength = endIndex - startIndex + codeBlockEndExp.matchedLength();
|
||||||
@ -205,6 +208,29 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HGMarkdownHighlighter::highlightLinkWithSpacesInURL(const QString &p_text)
|
||||||
|
{
|
||||||
|
if (currentBlockState() == HighlightBlockState::CodeBlock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: should select links with spaces in URL.
|
||||||
|
QRegExp regExp("[\\!]?\\[[^\\]]*\\]\\(([^\\n\\)]+)\\)");
|
||||||
|
int index = regExp.indexIn(p_text);
|
||||||
|
while (index >= 0) {
|
||||||
|
Q_ASSERT(regExp.captureCount() == 1);
|
||||||
|
int length = regExp.matchedLength();
|
||||||
|
const QString &capturedText = regExp.capturedTexts()[1];
|
||||||
|
if (capturedText.contains(' ')) {
|
||||||
|
if (p_text[index] == '!' && m_imageFormat.isValid()) {
|
||||||
|
setFormat(index, length, m_imageFormat);
|
||||||
|
} else if (m_linkFormat.isValid()) {
|
||||||
|
setFormat(index, length, m_linkFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = regExp.indexIn(p_text, index + length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HGMarkdownHighlighter::parse()
|
void HGMarkdownHighlighter::parse()
|
||||||
{
|
{
|
||||||
if (!parsing.testAndSetRelaxed(0, 1)) {
|
if (!parsing.testAndSetRelaxed(0, 1)) {
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
/* PEG Markdown Highlight
|
|
||||||
* Copyright 2011-2016 Ali Rantakari -- http://hasseg.org
|
|
||||||
* Licensed under the GPL2+ and MIT licenses (see LICENSE for more info).
|
|
||||||
*
|
|
||||||
* highlighter.h
|
|
||||||
*
|
|
||||||
* Qt 4.7 example for highlighting a rich text widget.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HGMARKDOWNHIGHLIGHTER_H
|
#ifndef HGMARKDOWNHIGHLIGHTER_H
|
||||||
#define HGMARKDOWNHIGHLIGHTER_H
|
#define HGMARKDOWNHIGHLIGHTER_H
|
||||||
|
|
||||||
@ -31,8 +22,8 @@ struct HighlightingStyle
|
|||||||
|
|
||||||
enum HighlightBlockState
|
enum HighlightBlockState
|
||||||
{
|
{
|
||||||
BlockNormal = 0,
|
Normal = 0,
|
||||||
BlockCodeBlock = 1,
|
CodeBlock = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// One continuous region for a certain markdown highlight style
|
// One continuous region for a certain markdown highlight style
|
||||||
@ -74,6 +65,8 @@ private:
|
|||||||
QRegExp codeBlockStartExp;
|
QRegExp codeBlockStartExp;
|
||||||
QRegExp codeBlockEndExp;
|
QRegExp codeBlockEndExp;
|
||||||
QTextCharFormat codeBlockFormat;
|
QTextCharFormat codeBlockFormat;
|
||||||
|
QTextCharFormat m_linkFormat;
|
||||||
|
QTextCharFormat m_imageFormat;
|
||||||
|
|
||||||
QTextDocument *document;
|
QTextDocument *document;
|
||||||
QVector<HighlightingStyle> highlightingStyles;
|
QVector<HighlightingStyle> highlightingStyles;
|
||||||
@ -92,6 +85,7 @@ private:
|
|||||||
|
|
||||||
void resizeBuffer(int newCap);
|
void resizeBuffer(int newCap);
|
||||||
void highlightCodeBlock(const QString &text);
|
void highlightCodeBlock(const QString &text);
|
||||||
|
void highlightLinkWithSpacesInURL(const QString &p_text);
|
||||||
void parse();
|
void parse();
|
||||||
void parseInternal();
|
void parseInternal();
|
||||||
void initBlockHighlightFromResult(int nrBlocks);
|
void initBlockHighlightFromResult(int nrBlocks);
|
||||||
|
@ -204,7 +204,7 @@ void VMdEdit::generateEditOutline()
|
|||||||
QRegExp headerReg("(#{1,6})\\s*(\\S.*)"); // Need to trim the spaces
|
QRegExp headerReg("(#{1,6})\\s*(\\S.*)"); // Need to trim the spaces
|
||||||
for (QTextBlock block = doc->begin(); block != doc->end(); block = block.next()) {
|
for (QTextBlock block = doc->begin(); block != doc->end(); block = block.next()) {
|
||||||
Q_ASSERT(block.lineCount() == 1);
|
Q_ASSERT(block.lineCount() == 1);
|
||||||
if ((block.userState() == HighlightBlockState::BlockNormal) &&
|
if ((block.userState() == HighlightBlockState::Normal) &&
|
||||||
headerReg.exactMatch(block.text())) {
|
headerReg.exactMatch(block.text())) {
|
||||||
VHeader header(headerReg.cap(1).length(),
|
VHeader header(headerReg.cap(1).length(),
|
||||||
headerReg.cap(2).trimmed(), "", block.firstLineNumber());
|
headerReg.cap(2).trimmed(), "", block.firstLineNumber());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user