Skip to content

Commit

Permalink
PegParser: support ~~~ as fenced code block
Browse files Browse the repository at this point in the history
  • Loading branch information
tamlok committed Nov 22, 2018
1 parent 026f3a6 commit 28eb48c
Show file tree
Hide file tree
Showing 10 changed files with 736 additions and 635 deletions.
1,300 changes: 691 additions & 609 deletions peg-highlight/pmh_parser.c

Large diffs are not rendered by default.

25 changes: 14 additions & 11 deletions src/peghighlighterresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ PegHighlighterResult::PegHighlighterResult()
m_codeBlockTimeStamp(0),
m_numOfCodeBlockHighlightsToRecv(0)
{
m_codeBlockStartExp = QRegExp(VUtils::c_fencedCodeBlockStartRegExp);
m_codeBlockEndExp = QRegExp(VUtils::c_fencedCodeBlockEndRegExp);
m_codeBlockStartExp = QRegularExpression(VUtils::c_fencedCodeBlockStartRegExp);
m_codeBlockEndExp = QRegularExpression(VUtils::c_fencedCodeBlockEndRegExp);
}

PegHighlighterResult::PegHighlighterResult(const PegMarkdownHighlighter *p_peg,
Expand All @@ -37,8 +37,8 @@ PegHighlighterResult::PegHighlighterResult(const PegMarkdownHighlighter *p_peg,
m_codeBlockTimeStamp(0),
m_numOfCodeBlockHighlightsToRecv(0)
{
m_codeBlockStartExp = QRegExp(VUtils::c_fencedCodeBlockStartRegExp);
m_codeBlockEndExp = QRegExp(VUtils::c_fencedCodeBlockEndRegExp);
m_codeBlockStartExp = QRegularExpression(VUtils::c_fencedCodeBlockStartRegExp);
m_codeBlockEndExp = QRegularExpression(VUtils::c_fencedCodeBlockEndRegExp);

parseBlocksHighlights(m_blocksHighlights, p_peg, p_result);

Expand Down Expand Up @@ -215,6 +215,7 @@ void PegHighlighterResult::parseFencedCodeBlocks(const PegMarkdownHighlighter *p
const QTextDocument *doc = p_peg->getDocument();
VCodeBlock item;
bool inBlock = false;
QString marker;
for (auto it = regs.begin(); it != regs.end(); ++it) {
QTextBlock block = doc->findBlock(it.value().m_startPos);
int lastBlock = doc->findBlock(it.value().m_endPos - 1).blockNumber();
Expand All @@ -232,10 +233,12 @@ void PegHighlighterResult::parseFencedCodeBlocks(const PegMarkdownHighlighter *p
QString text = block.text();
if (inBlock) {
item.m_text = item.m_text + "\n" + text;
int idx = m_codeBlockEndExp.indexIn(text);
if (idx >= 0) {
auto match = m_codeBlockEndExp.match(text);
if (match.hasMatch() && marker == match.captured(2)) {
// End block.
inBlock = false;
marker.clear();

state = HighlightBlockState::CodeBlockEnd;
item.m_endBlock = blockNumber;
m_codeBlocks.append(item);
Expand All @@ -244,17 +247,17 @@ void PegHighlighterResult::parseFencedCodeBlocks(const PegMarkdownHighlighter *p
state = HighlightBlockState::CodeBlock;
}
} else {
int idx = m_codeBlockStartExp.indexIn(text);
if (idx >= 0) {
auto match = m_codeBlockStartExp.match(text);
if (match.hasMatch()) {
// Start block.
inBlock = true;
marker = match.captured(2);

state = HighlightBlockState::CodeBlockStart;
item.m_startBlock = blockNumber;
item.m_startPos = block.position();
item.m_text = text;
if (m_codeBlockStartExp.captureCount() == 2) {
item.m_lang = m_codeBlockStartExp.capturedTexts()[2];
}
item.m_lang = match.captured(3).trimmed();
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/peghighlighterresult.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define PEGHIGHLIGHTERRESULT_H

#include <QSet>
#include <QRegularExpression>

#include "vconstants.h"
#include "pegparser.h"
Expand Down Expand Up @@ -114,8 +115,8 @@ class PegHighlighterResult
unsigned long p_end);
#endif

QRegExp m_codeBlockStartExp;
QRegExp m_codeBlockEndExp;
QRegularExpression m_codeBlockStartExp;
QRegularExpression m_codeBlockEndExp;
};

inline bool PegHighlighterResult::matched(TimeStamp p_timeStamp) const
Expand Down
8 changes: 4 additions & 4 deletions src/pegmarkdownhighlighter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,10 +607,10 @@ void PegMarkdownHighlighter::updateAllBlocksUserState(const QSharedPointer<PegHi
case HighlightBlockState::CodeBlockStart:
{
int startLeadingSpaces = 0;
QRegExp reg(VUtils::c_fencedCodeBlockStartRegExp);
int idx = reg.indexIn(block.text());
if (idx >= 0) {
startLeadingSpaces = reg.capturedTexts()[1].size();
QRegularExpression reg(VUtils::c_fencedCodeBlockStartRegExp);
auto match = reg.match(block.text());
if (match.hasMatch()) {
startLeadingSpaces = match.captured(1).size();
}

blockData->setCodeBlockIndentation(startLeadingSpaces);
Expand Down
6 changes: 5 additions & 1 deletion src/resources/docs/markdown_guide_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,13 @@ As VNote suggests:
This is a fenced code block.
```

~~~
This is another fenced code block.
~~~

**Notes**:

- `lang` is optional to specify the language of the code;
- `lang` is optional to specify the language of the code; if not specified, VNote won't highlight the code;

### Diagrams

Expand Down
6 changes: 5 additions & 1 deletion src/resources/docs/markdown_guide_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,13 @@ As VNote suggests:
This is a fenced code block.
```

~~~
This is another fenced code block.
~~~

**注意**

- `lang`用于指定代码块的代码语言,可选;
- `lang`用于指定代码块的代码语言,可选;如果不指定,VNote不会尝试高亮代码;

### 图表

Expand Down
2 changes: 1 addition & 1 deletion src/resources/vnote.ini
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ smart_live_preview=3
insert_new_note_in_front=false

; Whether highlight matches in page when activating a search result item
highlight_matches_in_page=true
highlight_matches_in_page=false

; Incremental search in page
find_incremental_search=true
Expand Down
11 changes: 9 additions & 2 deletions src/utils/veditutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1130,9 +1130,16 @@ bool VEditUtils::isWordSeparator(QChar p_char)
QString VEditUtils::removeCodeBlockFence(const QString &p_text)
{
QString text = VCodeBlockHighlightHelper::unindentCodeBlock(p_text);
Q_ASSERT(text.startsWith("```") && text.endsWith("```"));
Q_ASSERT(text.startsWith("```") || text.startsWith("~~~"));
int idx = text.indexOf('\n') + 1;
return text.mid(idx, text.size() - idx - 3);
int lidx = text.size() - 1;
// Trim spaces at the end.
while (lidx >= 0 && text[lidx].isSpace()) {
--lidx;
}

Q_ASSERT(text[lidx] == '`' || text[lidx] == '~');
return text.mid(idx, lidx + 1 - idx - 3);
}

bool VEditUtils::isSpaceOrWordSeparator(QChar p_char)
Expand Down
4 changes: 2 additions & 2 deletions src/utils/vutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ const QString VUtils::c_linkRegExp = QString("\\[([^\\]]*)\\]"

const QString VUtils::c_fileNameRegExp = QString("(?:[^\\\\/:\\*\\?\"<>\\|\\s]| )*");

const QString VUtils::c_fencedCodeBlockStartRegExp = QString("^(\\s*)```([^`\\s]*)\\s*[^`]*$");
const QString VUtils::c_fencedCodeBlockStartRegExp = QString("^(\\s*)([`~])\\2{2}((?:(?!\\2)[^\\r\\n])*)$");

const QString VUtils::c_fencedCodeBlockEndRegExp = QString("^(\\s*)```$");
const QString VUtils::c_fencedCodeBlockEndRegExp = QString("^(\\s*)([`~])\\2{2}\\s*$");

const QString VUtils::c_previewImageBlockRegExp = QString("[\\n|^][ |\\t]*\\xfffc[ |\\t]*(?=\\n)");

Expand Down
4 changes: 2 additions & 2 deletions src/vcodeblockhighlighthelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ QString VCodeBlockHighlightHelper::unindentCodeBlock(const QString &p_text)
}

QStringList lines = p_text.split('\n');
V_ASSERT(lines[0].trimmed().startsWith("```"));
V_ASSERT(lines.size() > 1);
Q_ASSERT(lines[0].trimmed().startsWith("```") || lines[0].trimmed().startsWith("~~~"));
Q_ASSERT(lines.size() > 1);

QRegExp regExp("(^\\s*)");
regExp.indexIn(lines[0]);
Expand Down

0 comments on commit 28eb48c

Please sign in to comment.