mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
feat: upsert tag based content (#816)
* feat: upsert tag based content * chore: update
This commit is contained in:
@ -5,7 +5,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/usememos/memos/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/usememos/memos" /></a>
|
<a href="https://github.com/usememos/memos/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/usememos/memos" /></a>
|
||||||
<a href="https://hub.docker.com/r/neosmemo/memos"><img alt="Docker pull" src="https://img.shields.io/docker/pulls/neosmemo/memos.svg" /></a>
|
<a href="https://hub.docker.com/r/neosmemo/memos"><img alt="Docker pull" src="https://img.shields.io/docker/pulls/neosmemo/memos.svg" /></a>
|
||||||
<img alt="Go report" src="https://goreportcard.com/badge/github.com/usememos/memos" />
|
<a href="https://discord.gg/tfPJa4UmAv"><img alt="Discord" src="https://img.shields.io/badge/discord-chat-5865f2?logo=discord&logoColor=f5f5f5" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { isNumber, last, toLower } from "lodash";
|
import { isNumber, last, toLower, uniq } from "lodash";
|
||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { getMatchedNodes } from "../labs/marked";
|
||||||
import { deleteMemoResource, upsertMemoResource } from "../helpers/api";
|
import { deleteMemoResource, upsertMemoResource } from "../helpers/api";
|
||||||
import { TAB_SPACE_WIDTH, UNKNOWN_ID, VISIBILITY_SELECTOR_ITEMS } from "../helpers/consts";
|
import { TAB_SPACE_WIDTH, UNKNOWN_ID, VISIBILITY_SELECTOR_ITEMS } from "../helpers/consts";
|
||||||
import { useEditorStore, useLocationStore, useMemoStore, useResourceStore, useTagStore, useUserStore } from "../store/module";
|
import { useEditorStore, useLocationStore, useMemoStore, useResourceStore, useTagStore, useUserStore } from "../store/module";
|
||||||
@ -326,6 +327,13 @@ const MemoEditor = () => {
|
|||||||
toastHelper.error(error.response.data.message);
|
toastHelper.error(error.response.data.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upsert tag based with content.
|
||||||
|
const matchedNodes = getMatchedNodes(content);
|
||||||
|
const tagNameList = uniq(matchedNodes.filter((node) => node.parserName === "tag").map((node) => node.matchedContent.slice(1)));
|
||||||
|
for (const tagName of tagNameList) {
|
||||||
|
await tagStore.upsertTag(tagName);
|
||||||
|
}
|
||||||
|
|
||||||
setState((state) => {
|
setState((state) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -53,3 +53,75 @@ export const marked = (markdownStr: string, blockParsers = blockElementParserLis
|
|||||||
|
|
||||||
return markdownStr;
|
return markdownStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface MatchedNode {
|
||||||
|
parserName: string;
|
||||||
|
matchedContent: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getMatchedNodes = (markdownStr: string): MatchedNode[] => {
|
||||||
|
const matchedNodeList: MatchedNode[] = [];
|
||||||
|
|
||||||
|
const walkthough = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => {
|
||||||
|
for (const parser of blockParsers) {
|
||||||
|
const matchResult = parser.matcher(markdownStr);
|
||||||
|
if (!matchResult) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const matchedStr = matchResult[0];
|
||||||
|
const retainContent = markdownStr.slice(matchedStr.length);
|
||||||
|
matchedNodeList.push({
|
||||||
|
parserName: parser.name,
|
||||||
|
matchedContent: matchedStr,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parser.name === "br") {
|
||||||
|
return walkthough(retainContent, blockParsers, inlineParsers);
|
||||||
|
} else {
|
||||||
|
if (retainContent.startsWith("\n")) {
|
||||||
|
return walkthough(retainContent.slice(1), blockParsers, inlineParsers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let matchedInlineParser = undefined;
|
||||||
|
let matchedIndex = -1;
|
||||||
|
|
||||||
|
for (const parser of inlineParsers) {
|
||||||
|
const matchResult = parser.matcher(markdownStr);
|
||||||
|
if (!matchResult) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser.name === "plain text" && matchedInlineParser !== undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startIndex = matchResult.index as number;
|
||||||
|
if (matchedInlineParser === undefined || matchedIndex > startIndex) {
|
||||||
|
matchedInlineParser = parser;
|
||||||
|
matchedIndex = startIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedInlineParser) {
|
||||||
|
const matchResult = matchedInlineParser.matcher(markdownStr);
|
||||||
|
if (matchResult) {
|
||||||
|
const matchedStr = matchResult[0];
|
||||||
|
const matchedLength = matchedStr.length;
|
||||||
|
const suffixStr = markdownStr.slice(matchedIndex + matchedLength);
|
||||||
|
matchedNodeList.push({
|
||||||
|
parserName: matchedInlineParser.name,
|
||||||
|
matchedContent: matchedStr,
|
||||||
|
});
|
||||||
|
return walkthough(suffixStr, [], inlineParsers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return markdownStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
walkthough(markdownStr);
|
||||||
|
|
||||||
|
return matchedNodeList;
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user