Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
64f67f4b
Unverified
Commit
64f67f4b
authored
Jun 30, 2022
by
boojack
Committed by
GitHub
Jun 30, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update content parser (#97)
parent
5b2e6a56
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
35 additions
and
79 deletions
+35
-79
Memo.tsx
web/src/components/Memo.tsx
+14
-28
MemoList.tsx
web/src/components/MemoList.tsx
+3
-16
marked.ts
web/src/helpers/marked.ts
+9
-19
daily-memo.less
web/src/less/daily-memo.less
+0
-6
memo-card-dialog.less
web/src/less/memo-card-dialog.less
+1
-5
memo-content.less
web/src/less/memo-content.less
+2
-3
memo.less
web/src/less/memo.less
+4
-0
tag-list.less
web/src/less/tag-list.less
+2
-2
No files found.
web/src/components/Memo.tsx
View file @
64f67f4b
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
escape
}
from
"lodash-es"
;
import
{
escape
}
from
"lodash-es"
;
import
{
IMAGE_URL_REG
,
LINK_REG
,
MEMO_LINK_REG
,
TAG_REG
,
UNKNOWN_ID
}
from
"../helpers/consts"
;
import
{
IMAGE_URL_REG
,
LINK_REG
,
MEMO_LINK_REG
,
TAG_REG
,
UNKNOWN_ID
}
from
"../helpers/consts"
;
import
{
parseMarkedToHtml
,
parseRawTextToHtml
}
from
"../helpers/marked"
;
import
{
parseMarkedToHtml
}
from
"../helpers/marked"
;
import
*
as
utils
from
"../helpers/utils"
;
import
*
as
utils
from
"../helpers/utils"
;
import
useToggle
from
"../hooks/useToggle"
;
import
useToggle
from
"../hooks/useToggle"
;
import
{
editorStateService
,
memoService
}
from
"../services"
;
import
{
editorStateService
,
locationService
,
memoService
}
from
"../services"
;
import
Only
from
"./common/OnlyWhen"
;
import
Only
from
"./common/OnlyWhen"
;
import
Image
from
"./Image"
;
import
Image
from
"./Image"
;
import
showMemoCardDialog
from
"./MemoCardDialog"
;
import
showMemoCardDialog
from
"./MemoCardDialog"
;
...
@@ -116,8 +116,16 @@ const Memo: React.FC<Props> = (props: Props) => {
...
@@ -116,8 +116,16 @@ const Memo: React.FC<Props> = (props: Props) => {
toastHelper
.
error
(
"MEMO Not Found"
);
toastHelper
.
error
(
"MEMO Not Found"
);
targetEl
.
classList
.
remove
(
"memo-link-text"
);
targetEl
.
classList
.
remove
(
"memo-link-text"
);
}
}
}
else
if
(
targetEl
.
tagName
===
"SPAN"
&&
targetEl
.
className
===
"tag-span"
)
{
const
tagName
=
targetEl
.
innerText
.
slice
(
1
);
const
currTagQuery
=
locationService
.
getState
().
query
?.
tag
;
if
(
currTagQuery
===
tagName
)
{
locationService
.
setTagQuery
(
""
);
}
else
{
locationService
.
setTagQuery
(
tagName
);
}
}
else
if
(
targetEl
.
className
===
"todo-block"
)
{
}
else
if
(
targetEl
.
className
===
"todo-block"
)
{
// do nth
//
...
do nth
}
}
};
};
...
@@ -196,32 +204,10 @@ const Memo: React.FC<Props> = (props: Props) => {
...
@@ -196,32 +204,10 @@ const Memo: React.FC<Props> = (props: Props) => {
};
};
export
function
formatMemoContent
(
content
:
string
)
{
export
function
formatMemoContent
(
content
:
string
)
{
content
=
escape
(
content
);
const
tempElement
=
document
.
createElement
(
"div"
);
content
=
parseRawTextToHtml
(
content
)
tempElement
.
innerHTML
=
parseMarkedToHtml
(
escape
(
content
));
.
split
(
"<br>"
)
.
map
((
t
)
=>
{
return
`<p>
${
t
!==
""
?
t
:
"<br>"
}
</p>`
;
})
.
join
(
""
);
content
=
parseMarkedToHtml
(
content
);
// Add space in english and chinese
content
=
content
.
replace
(
/
([\u
4e00-
\u
9fa5
])([
A-Za-z0-9?.,;[
\]]
+
)
/g
,
"$1 $2"
).
replace
(
/
([
A-Za-z0-9?.,;[
\]]
+
)([\u
4e00-
\u
9fa5
])
/g
,
"$1 $2"
);
const
tempDivContainer
=
document
.
createElement
(
"div"
);
tempDivContainer
.
innerHTML
=
content
;
for
(
let
i
=
0
;
i
<
tempDivContainer
.
children
.
length
;
i
++
)
{
const
c
=
tempDivContainer
.
children
[
i
];
if
(
c
.
tagName
===
"P"
&&
c
.
textContent
===
""
&&
c
.
firstElementChild
?.
tagName
!==
"BR"
)
{
c
.
remove
();
i
--
;
continue
;
}
}
return
temp
DivContainer
.
innerHTML
return
temp
Element
.
innerHTML
.
replace
(
IMAGE_URL_REG
,
""
)
.
replace
(
IMAGE_URL_REG
,
""
)
.
replace
(
TAG_REG
,
"<span class='tag-span'>#$1</span> "
)
.
replace
(
TAG_REG
,
"<span class='tag-span'>#$1</span> "
)
.
replace
(
LINK_REG
,
"<a class='link' target='_blank' rel='noreferrer' href='$1'>$1</a>"
)
.
replace
(
LINK_REG
,
"<a class='link' target='_blank' rel='noreferrer' href='$1'>$1</a>"
)
...
...
web/src/components/MemoList.tsx
View file @
64f67f4b
import
{
use
Callback
,
use
Effect
,
useRef
,
useState
}
from
"react"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
locationService
,
memoService
,
shortcutService
}
from
"../services"
;
import
{
memoService
,
shortcutService
}
from
"../services"
;
import
{
useAppSelector
}
from
"../store"
;
import
{
useAppSelector
}
from
"../store"
;
import
{
IMAGE_URL_REG
,
LINK_REG
,
MEMO_LINK_REG
,
TAG_REG
}
from
"../helpers/consts"
;
import
{
IMAGE_URL_REG
,
LINK_REG
,
MEMO_LINK_REG
,
TAG_REG
}
from
"../helpers/consts"
;
import
*
as
utils
from
"../helpers/utils"
;
import
*
as
utils
from
"../helpers/utils"
;
...
@@ -94,21 +94,8 @@ const MemoList: React.FC<Props> = () => {
...
@@ -94,21 +94,8 @@ const MemoList: React.FC<Props> = () => {
wrapperElement
.
current
?.
scrollTo
({
top
:
0
});
wrapperElement
.
current
?.
scrollTo
({
top
:
0
});
}
, [query]);
}
, [query]);
const handleMemoListClick = useCallback((event: React.MouseEvent) =
>
{
const
targetEl
=
event
.
target
as
HTMLElement
;
if
(
targetEl
.
tagName
===
"SPAN"
&&
targetEl
.
className
===
"tag-span"
)
{
const
tagName
=
targetEl
.
innerText
.
slice
(
1
);
const
currTagQuery
=
locationService
.
getState
().
query
?.
tag
;
if
(
currTagQuery
===
tagName
)
{
locationService
.
setTagQuery
(
""
);
}
else
{
locationService
.
setTagQuery
(
tagName
);
}
}
}
, []);
return (
return (
<
div
className=
{
`memo-list-container ${isFetching ? "" : "completed"}`
}
onClick=
{
handleMemoListClick
}
ref=
{
wrapperElement
}
>
<
div
className=
{
`memo-list-container ${isFetching ? "" : "completed"}`
}
ref=
{
wrapperElement
}
>
{
sortedMemos
.
map
((
memo
)
=>
(
{
sortedMemos
.
map
((
memo
)
=>
(
<
Memo
key=
{
`${memo.id}-${memo.updatedTs}`
}
memo=
{
memo
}
/>
<
Memo
key=
{
`${memo.id}-${memo.updatedTs}`
}
memo=
{
memo
}
/>
))
}
))
}
...
...
web/src/helpers/marked.ts
View file @
64f67f4b
/**
* 实现一个简易版的 markdown 解析
* - 列表解析;
* - 代码块;
* - 加粗/斜体;
* - TODO;
*/
const
CODE_BLOCK_REG
=
/```
([\s\S]
*
?)
```/g
;
const
CODE_BLOCK_REG
=
/```
([\s\S]
*
?)
```/g
;
const
BOLD_TEXT_REG
=
/
\*\*(
.+
?)\*\*
/g
;
const
BOLD_TEXT_REG
=
/
\*\*(
.+
?)\*\*
/g
;
const
EM_TEXT_REG
=
/
\*(
.+
?)\*
/g
;
const
EM_TEXT_REG
=
/
\*(
.+
?)\*
/g
;
const
TODO_BLOCK_REG
=
/
\[
\]
/g
;
const
TODO_BLOCK_REG
=
/
-
\[
\]
/g
;
const
DONE_BLOCK_REG
=
/
\[
x
\]
/g
;
const
DONE_BLOCK_REG
=
/
-
\[
x
\]
/g
;
const
DOT_LI_REG
=
/
[
*
]
/g
;
const
DOT_LI_REG
=
/
[
*
-
]
/g
;
const
NUM_LI_REG
=
/
(\d
+
)\.
/g
;
const
NUM_LI_REG
=
/
(\d
+
)\.
/g
;
const
parseMarkedToHtml
=
(
markedStr
:
string
):
string
=>
{
const
parseMarkedToHtml
=
(
markedStr
:
string
):
string
=>
{
const
htmlText
=
markedStr
const
htmlText
=
markedStr
.
replace
(
CODE_BLOCK_REG
,
"<pre lang=''>$1</pre>"
)
.
replace
(
CODE_BLOCK_REG
,
"<pre lang=''>$1</pre>"
)
.
replace
(
DOT_LI_REG
,
"<span class='counter-block'>•</span>"
)
.
replace
(
NUM_LI_REG
,
"<span class='counter-block'>$1.</span>"
)
.
replace
(
TODO_BLOCK_REG
,
"<span class='todo-block' data-type='todo'>⬜</span>"
)
.
replace
(
TODO_BLOCK_REG
,
"<span class='todo-block' data-type='todo'>⬜</span>"
)
.
replace
(
DONE_BLOCK_REG
,
"<span class='todo-block' data-type='done'>✅</span>"
)
.
replace
(
DONE_BLOCK_REG
,
"<span class='todo-block' data-type='done'>✅</span>"
)
.
replace
(
DOT_LI_REG
,
"<span class='counter-block'>•</span>"
)
.
replace
(
NUM_LI_REG
,
"<span class='counter-block'>$1.</span>"
)
.
replace
(
BOLD_TEXT_REG
,
"<strong>$1</strong>"
)
.
replace
(
BOLD_TEXT_REG
,
"<strong>$1</strong>"
)
.
replace
(
EM_TEXT_REG
,
"<em>$1</em>"
);
.
replace
(
EM_TEXT_REG
,
"<em>$1</em>"
)
.
replace
(
/
([\u
4e00-
\u
9fa5
])([
A-Za-z0-9?.,;[
\]]
+
)
/g
,
"$1 $2"
)
.
replace
(
/
([
A-Za-z0-9?.,;[
\]]
+
)([\u
4e00-
\u
9fa5
])
/g
,
"$1 $2"
);
return
htmlText
;
return
htmlText
;
};
};
...
@@ -34,9 +29,4 @@ const parseHtmlToRawText = (htmlStr: string): string => {
...
@@ -34,9 +29,4 @@ const parseHtmlToRawText = (htmlStr: string): string => {
return
text
;
return
text
;
};
};
const
parseRawTextToHtml
=
(
rawTextStr
:
string
):
string
=>
{
export
{
parseMarkedToHtml
,
parseHtmlToRawText
};
const
htmlText
=
rawTextStr
.
replace
(
/
\n
/g
,
"<br>"
);
return
htmlText
;
};
export
{
parseMarkedToHtml
,
parseHtmlToRawText
,
parseRawTextToHtml
};
web/src/less/daily-memo.less
View file @
64f67f4b
...
@@ -21,12 +21,6 @@
...
@@ -21,12 +21,6 @@
> .memo-content-container {
> .memo-content-container {
@apply flex flex-col justify-start items-start w-full p-0 text-base;
@apply flex flex-col justify-start items-start w-full p-0 text-base;
> .memo-content-text {
.tag-span {
cursor: unset;
}
}
> .images-container {
> .images-container {
@apply flex flex-col justify-start items-start mt-1 w-full;
@apply flex flex-col justify-start items-start mt-1 w-full;
...
...
web/src/less/memo-card-dialog.less
View file @
64f67f4b
...
@@ -41,11 +41,7 @@
...
@@ -41,11 +41,7 @@
@apply w-full pt-2;
@apply w-full pt-2;
> .memo-content-text {
> .memo-content-text {
@apply w-full text-base leading-6;
@apply w-full text-base;
.tag-span {
@apply p-0 text-blue-600 text-base bg-transparent cursor-auto;
}
}
}
> .images-wrapper {
> .images-wrapper {
...
...
web/src/less/memo-content.less
View file @
64f67f4b
@import "./mixin.less";
@import "./mixin.less";
.memo-content-text {
.memo-content-text {
.flex(column, flex-start, flex-start);
@apply w-full whitespace-pre-wrap break-words text-base leading-7;
@apply w-full whitespace-pre-wrap break-words;
> p {
> p {
@apply inline-block w-full h-auto mb-1 last:mb-0 text-base leading-7 whitespace-pre-wrap break-words;
@apply inline-block w-full h-auto mb-1 last:mb-0 text-base leading-7 whitespace-pre-wrap break-words;
}
}
.tag-span {
.tag-span {
@apply inline-block w-auto
px-2 text-sm leading-6 border-none rounded cursor-pointer text-blue-600 bg-blue-50 hover:text-white hover:bg
-blue-600;
@apply inline-block w-auto
font-mono text
-blue-600;
}
}
.memo-link-text {
.memo-link-text {
...
...
web/src/less/memo.less
View file @
64f67f4b
...
@@ -87,6 +87,10 @@
...
@@ -87,6 +87,10 @@
> .memo-content-text {
> .memo-content-text {
@apply w-full h-auto transition-all;
@apply w-full h-auto transition-all;
.tag-span {
@apply cursor-pointer hover:opacity-80;
}
}
}
> .expand-btn-container {
> .expand-btn-container {
...
...
web/src/less/tag-list.less
View file @
64f67f4b
...
@@ -76,10 +76,10 @@
...
@@ -76,10 +76,10 @@
}
}
> .tag-tip-container {
> .tag-tip-container {
@apply w-full mt-2 pl-4 text-
xs
text-gray-400;
@apply w-full mt-2 pl-4 text-
sm
text-gray-400;
> .code-text {
> .code-text {
@apply p-1 mx-1 text-blue-
4
00 font-mono whitespace-pre-line bg-blue-100 rounded;
@apply p-1 mx-1 text-blue-
6
00 font-mono whitespace-pre-line bg-blue-100 rounded;
}
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment