mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
use highlightjs for code block highlight in edit mode
This commit is contained in:
parent
859fb51c07
commit
04a020ba20
@ -146,83 +146,39 @@ font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Co
|
|||||||
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
||||||
# The last occurence of the same attribute takes effect
|
# The last occurence of the same attribute takes effect
|
||||||
# Could specify multiple attribute in one line
|
# Could specify multiple attribute in one line
|
||||||
hll: 404040
|
hljs-comment: af8787
|
||||||
c: 999999
|
hljs-quote: af8787
|
||||||
err: a61717
|
hljs-doctag: ccb24c
|
||||||
esc: d0d0d0
|
hljs-keyword: ccb24c
|
||||||
g: d0d0d0
|
hljs-formula: ccb24c
|
||||||
k: bold, 6ab825
|
hljs-section: e37c84
|
||||||
l: d0d0d0
|
hljs-name: e37c84
|
||||||
n: d0d0d0
|
hljs-selector-tag: e37c84
|
||||||
o: d0d0d0
|
hljs-deletion: e37c84
|
||||||
x: d0d0d0
|
hljs-subst: e37c84
|
||||||
p: d0d0d0
|
hljs-literal: 56b6c2
|
||||||
ch: italic, 999999
|
hljs-string: f06292
|
||||||
cm: italic, 999999
|
hljs-regexp: f06292
|
||||||
cp: bold, cd2828
|
hljs-addition: f06292
|
||||||
cpf: italic, 999999
|
hljs-attribute: f06292
|
||||||
c1: italic, 999999
|
hljs-meta-string: f06292
|
||||||
cs: bold, e50808
|
hljs-built_in: 80cbc4
|
||||||
gd: d22323
|
hljs-attr: ce93db
|
||||||
ge: italic, d0d0d0
|
hljs-variable: ce93db
|
||||||
gr: d22323
|
hljs-template-variable: ce93db
|
||||||
gh: bold, ffffff
|
hljs-type: ce93db
|
||||||
gi: 589819
|
hljs-selector-class: ce93db
|
||||||
go: cccccc
|
hljs-selector-attr: ce93db
|
||||||
gp: aaaaaa
|
hljs-selector-pseudo: ce93db
|
||||||
gs: bold, d0d0d0
|
hljs-number: ce93db
|
||||||
gu: underlined, ffffff
|
hljs-symbol: 84c0f2
|
||||||
gt: d22323
|
hljs-link: underlined, 84c0f2
|
||||||
kc: bold, 6ab825
|
hljs-bullet: 84c0f2
|
||||||
kd: bold, 6ab825
|
hljs-meta: 84c0f2
|
||||||
kn: bold, 6ab825
|
hljs-selector-id: 84c0f2
|
||||||
kp: 6ab825
|
hljs-title: bold, 84c0f2
|
||||||
kr: bold, 6ab825
|
hljs-emphasis: italic
|
||||||
kt: bold, 6ab825
|
hljs-strong: bold
|
||||||
ld: d0d0d0
|
|
||||||
m: 3677a9
|
|
||||||
s: ed9d13
|
|
||||||
na: bbbbbb
|
|
||||||
nb: 24909d
|
|
||||||
nc: underlined, 447fcf
|
|
||||||
no: 40ffff
|
|
||||||
nd: ffa500
|
|
||||||
ni: d0d0d0
|
|
||||||
ne: bbbbbb
|
|
||||||
nf: 447fcf
|
|
||||||
nl: d0d0d0
|
|
||||||
nn: underlined, 447fcf
|
|
||||||
nx: d0d0d0
|
|
||||||
py: d0d0d0
|
|
||||||
nt: bold, 6ab825
|
|
||||||
nv: 40ffff
|
|
||||||
ow: bold, 6ab825
|
|
||||||
w: 666666
|
|
||||||
mb: 3677a9
|
|
||||||
mf: 3677a9
|
|
||||||
mh: 3677a9
|
|
||||||
mi: 3677a9
|
|
||||||
mo: 3677a9
|
|
||||||
sa: ed9d13
|
|
||||||
sb: ed9d13
|
|
||||||
sc: ed9d13
|
|
||||||
dl: ed9d13
|
|
||||||
sd: ed9d13
|
|
||||||
s2: ed9d13
|
|
||||||
se: ed9d13
|
|
||||||
sh: ed9d13
|
|
||||||
si: ed9d13
|
|
||||||
sx: ffa500
|
|
||||||
sr: ed9d13
|
|
||||||
s1: ed9d13
|
|
||||||
ss: ed9d13
|
|
||||||
bp: 24909d
|
|
||||||
fm: 447fcf
|
|
||||||
vc: 40ffff
|
|
||||||
vg: 40ffff
|
|
||||||
vi: 40ffff
|
|
||||||
vm: 40ffff
|
|
||||||
il: 3677a9
|
|
||||||
|
|
||||||
BLOCKQUOTE
|
BLOCKQUOTE
|
||||||
foreground: ccb24c
|
foreground: ccb24c
|
||||||
|
@ -144,83 +144,40 @@ font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Co
|
|||||||
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
||||||
# The last occurence of the same attribute takes effect
|
# The last occurence of the same attribute takes effect
|
||||||
# Could specify multiple attribute in one line
|
# Could specify multiple attribute in one line
|
||||||
hll: 404040
|
hljs-comment: 6e7686
|
||||||
c: 999999
|
hljs-quote: 6e7686
|
||||||
err: a61717
|
hljs-doctag: c678dd
|
||||||
esc: d0d0d0
|
hljs-keyword: c678dd
|
||||||
g: d0d0d0
|
hljs-formula: c678dd
|
||||||
k: bold, 6ab825
|
hljs-section: e06c75
|
||||||
l: d0d0d0
|
hljs-name: e06c75
|
||||||
n: d0d0d0
|
hljs-selector-tag: e06c75
|
||||||
o: d0d0d0
|
hljs-deletion: e06c75
|
||||||
x: d0d0d0
|
hljs-subst: e06c75
|
||||||
p: d0d0d0
|
hljs-literal: 56b6c2
|
||||||
ch: italic, 999999
|
hljs-string: 98c379
|
||||||
cm: italic, 999999
|
hljs-regexp: 98c379
|
||||||
cp: bold, cd2828
|
hljs-addition: 98c379
|
||||||
cpf: italic, 999999
|
hljs-attribute: 98c379
|
||||||
c1: italic, 999999
|
hljs-meta-string: 98c379
|
||||||
cs: bold, e50808
|
hljs-built_in: e6c07b
|
||||||
gd: d22323
|
hljs-class: e6c07b
|
||||||
ge: italic, d0d0d0
|
hljs-attr: d19a66
|
||||||
gr: d22323
|
hljs-variable: d19a66
|
||||||
gh: bold, ffffff
|
hljs-template-variable: d19a66
|
||||||
gi: 589819
|
hljs-type: d19a66
|
||||||
go: cccccc
|
hljs-selector-class: d19a66
|
||||||
gp: aaaaaa
|
hljs-selector-attr: d19a66
|
||||||
gs: bold, d0d0d0
|
hljs-selector-pseudo: d19a66
|
||||||
gu: underlined, ffffff
|
hljs-number: d19a66
|
||||||
gt: d22323
|
hljs-symbol: 61aeee
|
||||||
kc: bold, 6ab825
|
hljs-link: underlined, 61aeee
|
||||||
kd: bold, 6ab825
|
hljs-bullet: 61aeee
|
||||||
kn: bold, 6ab825
|
hljs-meta: 61aeee
|
||||||
kp: 6ab825
|
hljs-selector-id: 61aeee
|
||||||
kr: bold, 6ab825
|
hljs-title: bold, 61aeee
|
||||||
kt: bold, 6ab825
|
hljs-emphasis: italic
|
||||||
ld: d0d0d0
|
hljs-strong: bold
|
||||||
m: 3677a9
|
|
||||||
s: ed9d13
|
|
||||||
na: bbbbbb
|
|
||||||
nb: 24909d
|
|
||||||
nc: underlined, 447fcf
|
|
||||||
no: 40ffff
|
|
||||||
nd: ffa500
|
|
||||||
ni: d0d0d0
|
|
||||||
ne: bbbbbb
|
|
||||||
nf: 447fcf
|
|
||||||
nl: d0d0d0
|
|
||||||
nn: underlined, 447fcf
|
|
||||||
nx: d0d0d0
|
|
||||||
py: d0d0d0
|
|
||||||
nt: bold, 6ab825
|
|
||||||
nv: 40ffff
|
|
||||||
ow: bold, 6ab825
|
|
||||||
w: 666666
|
|
||||||
mb: 3677a9
|
|
||||||
mf: 3677a9
|
|
||||||
mh: 3677a9
|
|
||||||
mi: 3677a9
|
|
||||||
mo: 3677a9
|
|
||||||
sa: ed9d13
|
|
||||||
sb: ed9d13
|
|
||||||
sc: ed9d13
|
|
||||||
dl: ed9d13
|
|
||||||
sd: ed9d13
|
|
||||||
s2: ed9d13
|
|
||||||
se: ed9d13
|
|
||||||
sh: ed9d13
|
|
||||||
si: ed9d13
|
|
||||||
sx: ffa500
|
|
||||||
sr: ed9d13
|
|
||||||
s1: ed9d13
|
|
||||||
ss: ed9d13
|
|
||||||
bp: 24909d
|
|
||||||
fm: 447fcf
|
|
||||||
vc: 40ffff
|
|
||||||
vg: 40ffff
|
|
||||||
vi: 40ffff
|
|
||||||
vm: 40ffff
|
|
||||||
il: 3677a9
|
|
||||||
|
|
||||||
BLOCKQUOTE
|
BLOCKQUOTE
|
||||||
foreground: 6e7686
|
foreground: 6e7686
|
||||||
|
@ -138,69 +138,42 @@ font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Co
|
|||||||
FENCEDCODEBLOCK
|
FENCEDCODEBLOCK
|
||||||
foreground: 673ab7
|
foreground: 673ab7
|
||||||
font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New
|
font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New
|
||||||
# [VNote] Codeblock sylte from Pygment (bold, italic, underlined, strikeout, color)
|
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
||||||
# The last occurence of the same attribute takes effect
|
# The last occurence of the same attribute takes effect
|
||||||
hll: ffffcc
|
hljs-comment: 6c6c6c
|
||||||
c: 888888
|
hljs-keyword: 0000ee
|
||||||
err: FF0000
|
hljs-attribute: 0000ee
|
||||||
k: 008800
|
hljs-selector-tag: 0000ee
|
||||||
o: 333333
|
hljs-meta-keyword: 0000ee
|
||||||
ch: 888888
|
hljs-doctag: 0000ee
|
||||||
cm: 888888
|
hljs-name: 0000ee
|
||||||
cp: 557799
|
hljs-type: 880000
|
||||||
cpf: 4d99bf
|
hljs-string: 880000
|
||||||
c1: 888888
|
hljs-number: 880000
|
||||||
cs: cc0000
|
hljs-selector-id: 880000
|
||||||
gd: A00000
|
hljs-selector-class: 880000
|
||||||
ge: italic
|
hljs-quote: 880000
|
||||||
gr: FF0000
|
hljs-template-tag: 880000
|
||||||
gh: 000080
|
hljs-deletion: 880000
|
||||||
gi: 00A000
|
# Could specify multiple attribute in one line
|
||||||
go: 888888
|
hljs-title: bold, 880000
|
||||||
gp: c65d09
|
hljs-section: bold, 880000
|
||||||
gs: bold
|
hljs-regexp: bc6060
|
||||||
gu: bold, 800080
|
hljs-symbol: bc6060
|
||||||
gt: bold, 0044DD
|
hljs-variable: bc6060
|
||||||
kc: bold, 008800
|
hljs-template-variable: bc6060
|
||||||
kd: bold, 008800
|
hljs-link: bc6060
|
||||||
kn: bold, 008800
|
hljs-selector-attr: bc6060
|
||||||
kp: bold, 003388
|
hljs-selector-pseudo: bc6060
|
||||||
kr: bold, 008800
|
hljs-literal: af00d7
|
||||||
kt: bold, 333399
|
hljs-built_in: 008700
|
||||||
m: bold, 6600EE
|
hljs-bullet: 008700
|
||||||
s: af00d7
|
hljs-code: 008700
|
||||||
na: 0000CC
|
hljs-addition: 008700
|
||||||
nb: 007020
|
hljs-meta: 1f7199
|
||||||
nc: bold, BB0066
|
hljs-meta-string: 4d99bf
|
||||||
no: bold, 003366
|
hljs-emphasis: italic
|
||||||
nd: bold, 555555
|
hljs-strong: bold
|
||||||
ni: bold, 880000
|
|
||||||
ne: bold, FF0000
|
|
||||||
nf: bold, 0066BB
|
|
||||||
nl: bold, 997700
|
|
||||||
nn: bold, 0e84b5
|
|
||||||
nt: 007700
|
|
||||||
nv: 996633
|
|
||||||
ow: bold, 000000
|
|
||||||
w: bbbbbb
|
|
||||||
mb: bold, 6600EE
|
|
||||||
mf: bold, 6600EE
|
|
||||||
mh: bold, 005588
|
|
||||||
mi: bold, 0000DD
|
|
||||||
mo: bold, 4400EE
|
|
||||||
sc: 0044DD
|
|
||||||
sd: DD4422
|
|
||||||
se: 666666
|
|
||||||
sx: DD2200
|
|
||||||
sr: 000000
|
|
||||||
ss: AA6600
|
|
||||||
bp: 007020
|
|
||||||
fm: bold, 0066BB
|
|
||||||
vc: 336699
|
|
||||||
vg: bold, dd7700
|
|
||||||
vi: 3333BB
|
|
||||||
vm: 996633
|
|
||||||
il: bold, 0000DD
|
|
||||||
|
|
||||||
BLOCKQUOTE
|
BLOCKQUOTE
|
||||||
foreground: 00af00
|
foreground: 00af00
|
||||||
|
@ -139,70 +139,42 @@ font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Co
|
|||||||
FENCEDCODEBLOCK
|
FENCEDCODEBLOCK
|
||||||
foreground: 673ab7
|
foreground: 673ab7
|
||||||
font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New
|
font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New
|
||||||
# [VNote] Codeblock sylte from Pygment (bold, italic, underlined, strikeout, color)
|
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
||||||
# The last occurence of the same attribute takes effect
|
# The last occurence of the same attribute takes effect
|
||||||
# Could specify multiple attribute in one line
|
# Could specify multiple attribute in one line
|
||||||
hll: ffffcc
|
hljs-comment: 6c6c6c
|
||||||
c: 888888
|
hljs-keyword: 0000ee
|
||||||
err: FF0000
|
hljs-attribute: 0000ee
|
||||||
k: 008800
|
hljs-selector-tag: 0000ee
|
||||||
o: 333333
|
hljs-meta-keyword: 0000ee
|
||||||
ch: 888888
|
hljs-doctag: 0000ee
|
||||||
cm: 888888
|
hljs-name: 0000ee
|
||||||
cp: 557799
|
hljs-type: 880000
|
||||||
cpf: 4d99bf
|
hljs-string: 880000
|
||||||
c1: 888888
|
hljs-number: 880000
|
||||||
cs: cc0000
|
hljs-selector-id: 880000
|
||||||
gd: A00000
|
hljs-selector-class: 880000
|
||||||
ge: italic
|
hljs-quote: 880000
|
||||||
gr: FF0000
|
hljs-template-tag: 880000
|
||||||
gh: 000080
|
hljs-deletion: 880000
|
||||||
gi: 00A000
|
hljs-title: bold, 880000
|
||||||
go: 888888
|
hljs-section: bold, 880000
|
||||||
gp: c65d09
|
hljs-regexp: bc6060
|
||||||
gs: bold
|
hljs-symbol: bc6060
|
||||||
gu: bold, 800080
|
hljs-variable: bc6060
|
||||||
gt: bold, 0044DD
|
hljs-template-variable: bc6060
|
||||||
kc: bold, 008800
|
hljs-link: bc6060
|
||||||
kd: bold, 008800
|
hljs-selector-attr: bc6060
|
||||||
kn: bold, 008800
|
hljs-selector-pseudo: bc6060
|
||||||
kp: bold, 003388
|
hljs-literal: af00d7
|
||||||
kr: bold, 008800
|
hljs-built_in: 008700
|
||||||
kt: bold, 333399
|
hljs-bullet: 008700
|
||||||
m: bold, 6600EE
|
hljs-code: 008700
|
||||||
s: af00d7
|
hljs-addition: 008700
|
||||||
na: 0000CC
|
hljs-meta: 1f7199
|
||||||
nb: 007020
|
hljs-meta-string: 4d99bf
|
||||||
nc: bold, BB0066
|
hljs-emphasis: italic
|
||||||
no: bold, 003366
|
hljs-strong: bold
|
||||||
nd: bold, 555555
|
|
||||||
ni: bold, 880000
|
|
||||||
ne: bold, FF0000
|
|
||||||
nf: bold, 0066BB
|
|
||||||
nl: bold, 997700
|
|
||||||
nn: bold, 0e84b5
|
|
||||||
nt: 007700
|
|
||||||
nv: 996633
|
|
||||||
ow: bold, 000000
|
|
||||||
w: bbbbbb
|
|
||||||
mb: bold, 6600EE
|
|
||||||
mf: bold, 6600EE
|
|
||||||
mh: bold, 005588
|
|
||||||
mi: bold, 0000DD
|
|
||||||
mo: bold, 4400EE
|
|
||||||
sc: 0044DD
|
|
||||||
sd: DD4422
|
|
||||||
se: 666666
|
|
||||||
sx: DD2200
|
|
||||||
sr: 000000
|
|
||||||
ss: AA6600
|
|
||||||
bp: 007020
|
|
||||||
fm: bold, 0066BB
|
|
||||||
vc: 336699
|
|
||||||
vg: bold, dd7700
|
|
||||||
vi: 3333BB
|
|
||||||
vm: 996633
|
|
||||||
il: bold, 0000DD
|
|
||||||
|
|
||||||
BLOCKQUOTE
|
BLOCKQUOTE
|
||||||
foreground: 00af00
|
foreground: 00af00
|
||||||
|
@ -135,67 +135,39 @@ font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Co
|
|||||||
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color)
|
||||||
# The last occurence of the same attribute takes effect
|
# The last occurence of the same attribute takes effect
|
||||||
# Could specify multiple attribute in one line
|
# Could specify multiple attribute in one line
|
||||||
hll: ffffcc
|
hljs-comment: 6c6c6c
|
||||||
c: 888888
|
hljs-keyword: 0000ee
|
||||||
err: FF0000
|
hljs-attribute: 0000ee
|
||||||
k: 008800
|
hljs-selector-tag: 0000ee
|
||||||
o: 333333
|
hljs-meta-keyword: 0000ee
|
||||||
ch: 888888
|
hljs-doctag: 0000ee
|
||||||
cm: 888888
|
hljs-name: 0000ee
|
||||||
cp: 557799
|
hljs-type: 880000
|
||||||
cpf: 4d99bf
|
hljs-string: 880000
|
||||||
c1: 888888
|
hljs-number: 880000
|
||||||
cs: cc0000
|
hljs-selector-id: 880000
|
||||||
gd: A00000
|
hljs-selector-class: 880000
|
||||||
ge: italic
|
hljs-quote: 880000
|
||||||
gr: FF0000
|
hljs-template-tag: 880000
|
||||||
gh: 000080
|
hljs-deletion: 880000
|
||||||
gi: 00A000
|
hljs-title: bold, 880000
|
||||||
go: 888888
|
hljs-section: bold, 880000
|
||||||
gp: c65d09
|
hljs-regexp: bc6060
|
||||||
gs: bold
|
hljs-symbol: bc6060
|
||||||
gu: bold, 800080
|
hljs-variable: bc6060
|
||||||
gt: bold, 0044DD
|
hljs-template-variable: bc6060
|
||||||
kc: bold, 008800
|
hljs-link: bc6060
|
||||||
kd: bold, 008800
|
hljs-selector-attr: bc6060
|
||||||
kn: bold, 008800
|
hljs-selector-pseudo: bc6060
|
||||||
kp: bold, 003388
|
hljs-literal: af00d7
|
||||||
kr: bold, 008800
|
hljs-built_in: 008700
|
||||||
kt: bold, 333399
|
hljs-bullet: 008700
|
||||||
m: bold, 6600EE
|
hljs-code: 008700
|
||||||
s: af00d7
|
hljs-addition: 008700
|
||||||
na: 0000CC
|
hljs-meta: 1f7199
|
||||||
nb: 007020
|
hljs-meta-string: 4d99bf
|
||||||
nc: bold, BB0066
|
hljs-emphasis: italic
|
||||||
no: bold, 003366
|
hljs-strong: bold
|
||||||
nd: bold, 555555
|
|
||||||
ni: bold, 880000
|
|
||||||
ne: bold, FF0000
|
|
||||||
nf: bold, 0066BB
|
|
||||||
nl: bold, 997700
|
|
||||||
nn: bold, 0e84b5
|
|
||||||
nt: 007700
|
|
||||||
nv: 996633
|
|
||||||
ow: bold, 000000
|
|
||||||
w: bbbbbb
|
|
||||||
mb: bold, 6600EE
|
|
||||||
mf: bold, 6600EE
|
|
||||||
mh: bold, 005588
|
|
||||||
mi: bold, 0000DD
|
|
||||||
mo: bold, 4400EE
|
|
||||||
sc: 0044DD
|
|
||||||
sd: DD4422
|
|
||||||
se: 666666
|
|
||||||
sx: DD2200
|
|
||||||
sr: 000000
|
|
||||||
ss: AA6600
|
|
||||||
bp: 007020
|
|
||||||
fm: bold, 0066BB
|
|
||||||
vc: 336699
|
|
||||||
vg: bold, dd7700
|
|
||||||
vi: 3333BB
|
|
||||||
vm: 996633
|
|
||||||
il: bold, 0000DD
|
|
||||||
|
|
||||||
BLOCKQUOTE
|
BLOCKQUOTE
|
||||||
foreground: 00af00
|
foreground: 00af00
|
||||||
|
@ -424,7 +424,7 @@ plantuml_cmd=
|
|||||||
graphviz_dot=
|
graphviz_dot=
|
||||||
|
|
||||||
; Whether enable copy button in code block
|
; Whether enable copy button in code block
|
||||||
enable_code_block_copy_button=true
|
enable_code_block_copy_button=false
|
||||||
|
|
||||||
[shortcuts]
|
[shortcuts]
|
||||||
; Define shortcuts here, with each item in the form "operation=keysequence".
|
; Define shortcuts here, with each item in the form "operation=keysequence".
|
||||||
|
@ -68,6 +68,7 @@ SOURCES += main.cpp\
|
|||||||
vnavigationmode.cpp \
|
vnavigationmode.cpp \
|
||||||
vorphanfile.cpp \
|
vorphanfile.cpp \
|
||||||
vcodeblockhighlighthelper.cpp \
|
vcodeblockhighlighthelper.cpp \
|
||||||
|
vcodeblockhighlighthelper2.cpp \
|
||||||
vmdtab.cpp \
|
vmdtab.cpp \
|
||||||
vhtmltab.cpp \
|
vhtmltab.cpp \
|
||||||
utils/vvim.cpp \
|
utils/vvim.cpp \
|
||||||
@ -202,6 +203,7 @@ HEADERS += vmainwindow.h \
|
|||||||
vnavigationmode.h \
|
vnavigationmode.h \
|
||||||
vorphanfile.h \
|
vorphanfile.h \
|
||||||
vcodeblockhighlighthelper.h \
|
vcodeblockhighlighthelper.h \
|
||||||
|
vcodeblockhighlighthelper2.h \
|
||||||
vmdtab.h \
|
vmdtab.h \
|
||||||
vhtmltab.h \
|
vhtmltab.h \
|
||||||
utils/vvim.h \
|
utils/vvim.h \
|
||||||
|
307
src/vcodeblockhighlighthelper2.cpp
Normal file
307
src/vcodeblockhighlighthelper2.cpp
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
#include "vcodeblockhighlighthelper2.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "vdocument.h"
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
#include "pegmarkdownhighlighter.h"
|
||||||
|
|
||||||
|
VCodeBlockHighlightHelper2::VCodeBlockHighlightHelper2(PegMarkdownHighlighter *p_highlighter,
|
||||||
|
VDocument *p_vdoc,
|
||||||
|
MarkdownConverterType p_type)
|
||||||
|
: QObject(p_highlighter),
|
||||||
|
m_highlighter(p_highlighter),
|
||||||
|
m_vdocument(p_vdoc),
|
||||||
|
m_type(p_type),
|
||||||
|
m_timeStamp(0)
|
||||||
|
{
|
||||||
|
connect(m_highlighter, &PegMarkdownHighlighter::codeBlocksUpdated,
|
||||||
|
this, &VCodeBlockHighlightHelper2::handleCodeBlocksUpdated);
|
||||||
|
connect(m_vdocument, &VDocument::textHighlighted,
|
||||||
|
this, &VCodeBlockHighlightHelper2::handleTextHighlightResult);
|
||||||
|
|
||||||
|
// Web side is ready for code block highlight.
|
||||||
|
connect(m_vdocument, &VDocument::readyToHighlightText,
|
||||||
|
m_highlighter, &PegMarkdownHighlighter::updateHighlight);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VCodeBlockHighlightHelper2::unindentCodeBlock(const QString &p_text)
|
||||||
|
{
|
||||||
|
if (p_text.isEmpty()) {
|
||||||
|
return p_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList lines = p_text.split('\n');
|
||||||
|
Q_ASSERT(lines[0].trimmed().startsWith("```") || lines[0].trimmed().startsWith("~~~"));
|
||||||
|
Q_ASSERT(lines.size() > 1);
|
||||||
|
|
||||||
|
QRegExp regExp("(^\\s*)");
|
||||||
|
regExp.indexIn(lines[0]);
|
||||||
|
V_ASSERT(regExp.captureCount() == 1);
|
||||||
|
int nrSpaces = regExp.capturedTexts()[1].size();
|
||||||
|
|
||||||
|
if (nrSpaces == 0) {
|
||||||
|
return p_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString res = lines[0].right(lines[0].size() - nrSpaces);
|
||||||
|
for (int i = 1; i < lines.size(); ++i) {
|
||||||
|
const QString &line = lines[i];
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
while (idx < nrSpaces && idx < line.size() && line[idx].isSpace()) {
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
res = res + "\n" + line.right(line.size() - idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VCodeBlockHighlightHelper2::handleCodeBlocksUpdated(TimeStamp p_timeStamp,
|
||||||
|
const QVector<VCodeBlock> &p_codeBlocks)
|
||||||
|
{
|
||||||
|
if (!m_vdocument->isReadyToHighlight()) {
|
||||||
|
// Immediately return empty results.
|
||||||
|
QVector<HLUnitPos> emptyRes;
|
||||||
|
for (int i = 0; i < p_codeBlocks.size(); ++i) {
|
||||||
|
updateHighlightResults(p_timeStamp, 0, emptyRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_timeStamp = p_timeStamp;
|
||||||
|
m_codeBlocks = p_codeBlocks;
|
||||||
|
for (int i = 0; i < m_codeBlocks.size(); ++i) {
|
||||||
|
const VCodeBlock &block = m_codeBlocks[i];
|
||||||
|
auto it = m_cache.find(block.m_text);
|
||||||
|
if (it != m_cache.end()) {
|
||||||
|
// Hit cache.
|
||||||
|
qDebug() << "code block highlight hit cache" << p_timeStamp << i;
|
||||||
|
it.value().m_timeStamp = p_timeStamp;
|
||||||
|
updateHighlightResults(p_timeStamp, block.m_startPos, it.value().m_units);
|
||||||
|
} else {
|
||||||
|
QString unindentedText = unindentCodeBlock(block.m_text);
|
||||||
|
m_vdocument->highlightTextAsync(unindentedText, i, p_timeStamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VCodeBlockHighlightHelper2::handleTextHighlightResult(const QString &p_html,
|
||||||
|
int p_id,
|
||||||
|
unsigned long long p_timeStamp)
|
||||||
|
{
|
||||||
|
// Abandon obsolete result.
|
||||||
|
if (m_timeStamp != p_timeStamp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseHighlightResult(p_timeStamp, p_id, p_html);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void revertEscapedHtml(QString &p_html)
|
||||||
|
{
|
||||||
|
p_html.replace(">", ">").replace("<", "<").replace("&", "&");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search @p_tokenStr in @p_text from p_index. Spaces after `\n` will not make
|
||||||
|
// a difference in the match. The matched range will be returned as
|
||||||
|
// [@p_start, @p_end]. Update @p_index to @p_end + 1.
|
||||||
|
// Set @p_start and @p_end to -1 to indicate mismatch.
|
||||||
|
static void matchTokenRelaxed(const QString &p_text, const QString &p_tokenStr,
|
||||||
|
int &p_index, int &p_start, int &p_end)
|
||||||
|
{
|
||||||
|
QString regStr = QRegExp::escape(p_tokenStr);
|
||||||
|
|
||||||
|
// Remove the leading spaces.
|
||||||
|
int nonSpaceIdx = 0;
|
||||||
|
while (nonSpaceIdx < regStr.size() && regStr[nonSpaceIdx].isSpace()) {
|
||||||
|
++nonSpaceIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonSpaceIdx > 0 && nonSpaceIdx < regStr.size()) {
|
||||||
|
regStr.remove(0, nonSpaceIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not replace the ending '\n'.
|
||||||
|
regStr.replace(QRegExp("\n(?!$)"), "\\s+");
|
||||||
|
|
||||||
|
QRegExp regExp(regStr);
|
||||||
|
p_start = p_text.indexOf(regExp, p_index);
|
||||||
|
if (p_start == -1) {
|
||||||
|
p_end = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_end = p_start + regExp.matchedLength() - 1;
|
||||||
|
p_index = p_end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, we could only handle code blocks outside the list.
|
||||||
|
void VCodeBlockHighlightHelper2::parseHighlightResult(TimeStamp p_timeStamp,
|
||||||
|
int p_idx,
|
||||||
|
const QString &p_html)
|
||||||
|
{
|
||||||
|
const VCodeBlock &block = m_codeBlocks.at(p_idx);
|
||||||
|
int startPos = block.m_startPos;
|
||||||
|
QString text = block.m_text;
|
||||||
|
|
||||||
|
QVector<HLUnitPos> hlUnits;
|
||||||
|
|
||||||
|
bool failed = true;
|
||||||
|
|
||||||
|
QXmlStreamReader xml(p_html);
|
||||||
|
|
||||||
|
// Must have a fenced line at the front.
|
||||||
|
// textIndex is the start index in the code block text to search for.
|
||||||
|
int textIndex = text.indexOf('\n');
|
||||||
|
if (textIndex == -1) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
++textIndex;
|
||||||
|
|
||||||
|
if (xml.readNextStartElement()) {
|
||||||
|
if (xml.name() != "pre") {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xml.readNextStartElement()) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.name() != "code") {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (xml.readNext()) {
|
||||||
|
if (xml.isCharacters()) {
|
||||||
|
// Revert the HTML escape to match.
|
||||||
|
QString tokenStr = xml.text().toString();
|
||||||
|
revertEscapedHtml(tokenStr);
|
||||||
|
|
||||||
|
int start, end;
|
||||||
|
matchTokenRelaxed(text, tokenStr, textIndex, start, end);
|
||||||
|
if (start == -1) {
|
||||||
|
failed = true;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else if (xml.isStartElement()) {
|
||||||
|
if (xml.name() != "span") {
|
||||||
|
failed = true;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!parseSpanElement(xml, text, textIndex, hlUnits)) {
|
||||||
|
failed = true;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else if (xml.isEndElement()) {
|
||||||
|
if (xml.name() != "code" && xml.name() != "pre") {
|
||||||
|
failed = true;
|
||||||
|
} else {
|
||||||
|
failed = false;
|
||||||
|
}
|
||||||
|
goto exit;
|
||||||
|
} else {
|
||||||
|
failed = true;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
// Pass result back to highlighter.
|
||||||
|
// Abandon obsolete result.
|
||||||
|
if (m_timeStamp != p_timeStamp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.hasError() || failed) {
|
||||||
|
qWarning() << "fail to parse highlighted result"
|
||||||
|
<< "stamp:" << p_timeStamp << "index:" << p_idx << p_html;
|
||||||
|
hlUnits.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add it to cache.
|
||||||
|
addToHighlightCache(text, p_timeStamp, hlUnits);
|
||||||
|
|
||||||
|
updateHighlightResults(p_timeStamp, startPos, hlUnits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VCodeBlockHighlightHelper2::updateHighlightResults(TimeStamp p_timeStamp,
|
||||||
|
int p_startPos,
|
||||||
|
QVector<HLUnitPos> p_units)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < p_units.size(); ++i) {
|
||||||
|
p_units[i].m_position += p_startPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to call this function anyway to trigger the rehighlight.
|
||||||
|
m_highlighter->setCodeBlockHighlights(p_timeStamp, p_units);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VCodeBlockHighlightHelper2::parseSpanElement(QXmlStreamReader &p_xml,
|
||||||
|
const QString &p_text,
|
||||||
|
int &p_index,
|
||||||
|
QVector<HLUnitPos> &p_units)
|
||||||
|
{
|
||||||
|
int unitStart = p_index;
|
||||||
|
QString style = p_xml.attributes().value("class").toString();
|
||||||
|
|
||||||
|
while (p_xml.readNext()) {
|
||||||
|
if (p_xml.isCharacters()) {
|
||||||
|
// Revert the HTML escape to match.
|
||||||
|
QString tokenStr = p_xml.text().toString();
|
||||||
|
revertEscapedHtml(tokenStr);
|
||||||
|
|
||||||
|
int start, end;
|
||||||
|
matchTokenRelaxed(p_text, tokenStr, p_index, start, end);
|
||||||
|
if (start == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (p_xml.isStartElement()) {
|
||||||
|
if (p_xml.name() != "span") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub-span.
|
||||||
|
if (!parseSpanElement(p_xml, p_text, p_index, p_units)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (p_xml.isEndElement()) {
|
||||||
|
if (p_xml.name() != "span") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Got a complete span. Use relative position here.
|
||||||
|
HLUnitPos unit(unitStart, p_index - unitStart, style);
|
||||||
|
p_units.append(unit);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VCodeBlockHighlightHelper2::addToHighlightCache(const QString &p_text,
|
||||||
|
TimeStamp p_timeStamp,
|
||||||
|
const QVector<HLUnitPos> &p_units)
|
||||||
|
{
|
||||||
|
const int c_maxEntries = 100;
|
||||||
|
const TimeStamp c_maxTimeStampSpan = 3;
|
||||||
|
if (m_cache.size() >= c_maxEntries) {
|
||||||
|
// Remove the oldest one.
|
||||||
|
TimeStamp ts = p_timeStamp - c_maxTimeStampSpan;
|
||||||
|
for (auto it = m_cache.begin(); it != m_cache.end();) {
|
||||||
|
if (it.value().m_timeStamp < ts) {
|
||||||
|
it = m_cache.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cache.insert(p_text, HLResult(p_timeStamp, p_units));
|
||||||
|
}
|
81
src/vcodeblockhighlighthelper2.h
Normal file
81
src/vcodeblockhighlighthelper2.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#ifndef VCODEBLOCKHIGHLIGHTHELPER2_H
|
||||||
|
#define VCODEBLOCKHIGHLIGHTHELPER2_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QAtomicInteger>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
|
||||||
|
class VDocument;
|
||||||
|
class PegMarkdownHighlighter;
|
||||||
|
|
||||||
|
class VCodeBlockHighlightHelper2 : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
VCodeBlockHighlightHelper2(PegMarkdownHighlighter *p_highlighter,
|
||||||
|
VDocument *p_vdoc, MarkdownConverterType p_type);
|
||||||
|
|
||||||
|
// @p_text: text of fenced code block.
|
||||||
|
// Get the indent level of the first line (fence) and unindent the whole block
|
||||||
|
// to make the fence at the highest indent level.
|
||||||
|
// This operation is to make sure JS could handle the code block correctly
|
||||||
|
// without any context.
|
||||||
|
static QString unindentCodeBlock(const QString &p_text);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleCodeBlocksUpdated(TimeStamp p_timeStamp, const QVector<VCodeBlock> &p_codeBlocks);
|
||||||
|
|
||||||
|
void handleTextHighlightResult(const QString &p_html, int p_id, unsigned long long p_timeStamp);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct HLResult
|
||||||
|
{
|
||||||
|
HLResult()
|
||||||
|
: m_timeStamp(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HLResult(TimeStamp p_timeStamp, const QVector<HLUnitPos> &p_units)
|
||||||
|
: m_timeStamp(p_timeStamp),
|
||||||
|
m_units(p_units)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeStamp m_timeStamp;
|
||||||
|
|
||||||
|
QVector<HLUnitPos> m_units;
|
||||||
|
};
|
||||||
|
|
||||||
|
void parseHighlightResult(TimeStamp p_timeStamp, int p_idx, const QString &p_html);
|
||||||
|
|
||||||
|
// @p_text: the raw text of the code block;
|
||||||
|
// @p_index: the start index of the span element within @p_text;
|
||||||
|
// @p_units: all the highlight units of this code block;
|
||||||
|
bool parseSpanElement(QXmlStreamReader &p_xml,
|
||||||
|
const QString &p_text, int &p_index,
|
||||||
|
QVector<HLUnitPos> &p_units);
|
||||||
|
|
||||||
|
void updateHighlightResults(TimeStamp p_timeStamp, int p_startPos, QVector<HLUnitPos> p_units);
|
||||||
|
|
||||||
|
void addToHighlightCache(const QString &p_text,
|
||||||
|
TimeStamp p_timeStamp,
|
||||||
|
const QVector<HLUnitPos> &p_units);
|
||||||
|
|
||||||
|
PegMarkdownHighlighter *m_highlighter;
|
||||||
|
VDocument *m_vdocument;
|
||||||
|
MarkdownConverterType m_type;
|
||||||
|
|
||||||
|
TimeStamp m_timeStamp;
|
||||||
|
|
||||||
|
QVector<VCodeBlock> m_codeBlocks;
|
||||||
|
|
||||||
|
// Cache for highlight result, using the code block text as key.
|
||||||
|
// The HLResult has relative position only.
|
||||||
|
QHash<QString, HLResult> m_cache;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VCODEBLOCKHIGHLIGHTHELPER2_H
|
@ -13,7 +13,7 @@
|
|||||||
#include "utils/veditutils.h"
|
#include "utils/veditutils.h"
|
||||||
#include "vedittab.h"
|
#include "vedittab.h"
|
||||||
#include "pegmarkdownhighlighter.h"
|
#include "pegmarkdownhighlighter.h"
|
||||||
#include "vcodeblockhighlighthelper.h"
|
#include "vcodeblockhighlighthelper2.h"
|
||||||
#include "vmdeditoperations.h"
|
#include "vmdeditoperations.h"
|
||||||
#include "vtableofcontent.h"
|
#include "vtableofcontent.h"
|
||||||
#include "utils/veditutils.h"
|
#include "utils/veditutils.h"
|
||||||
@ -101,7 +101,7 @@ VMdEditor::VMdEditor(VFile *p_file,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_cbHighlighter = new VCodeBlockHighlightHelper(m_pegHighlighter, p_type);
|
m_cbHighlighter = new VCodeBlockHighlightHelper2(m_pegHighlighter, p_doc, p_type);
|
||||||
|
|
||||||
m_previewMgr = new VPreviewManager(this, m_pegHighlighter);
|
m_previewMgr = new VPreviewManager(this, m_pegHighlighter);
|
||||||
connect(m_pegHighlighter, &PegMarkdownHighlighter::imageLinksUpdated,
|
connect(m_pegHighlighter, &PegMarkdownHighlighter::imageLinksUpdated,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
|
|
||||||
class PegMarkdownHighlighter;
|
class PegMarkdownHighlighter;
|
||||||
class VCodeBlockHighlightHelper;
|
class VCodeBlockHighlightHelper2;
|
||||||
class VDocument;
|
class VDocument;
|
||||||
class VPreviewManager;
|
class VPreviewManager;
|
||||||
class VCopyTextAsHtmlDialog;
|
class VCopyTextAsHtmlDialog;
|
||||||
@ -329,7 +329,7 @@ private:
|
|||||||
|
|
||||||
PegMarkdownHighlighter *m_pegHighlighter;
|
PegMarkdownHighlighter *m_pegHighlighter;
|
||||||
|
|
||||||
VCodeBlockHighlightHelper *m_cbHighlighter;
|
VCodeBlockHighlightHelper2 *m_cbHighlighter;
|
||||||
|
|
||||||
VPreviewManager *m_previewMgr;
|
VPreviewManager *m_previewMgr;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user