mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-22 16:26:09 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
0aed11045c
21 changed files with 61 additions and 28 deletions
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "تم تحديد معدل الطلب بواسطة التخزين السحابي. الرجاء التحقق من الإعدادات وأذونات التخزين السحابية",
|
||||
"251": "مجموع الأصول غير المستخدمة [%d]، [%d] فقط منها مدرج هنا",
|
||||
"252": "\uD83D\uDEA8 قد يقوم Microsoft Defender بحذف النواة عن طريق الخطأ، وحذف البيانات وتقليل الأداء بشكل كبير. يُوصى بإضافة مسار التثبيت ومسار مساحة العمل الخاصة بـ SiYuan إلى قائمة الاستثناءات<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">إضافة</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">تجاهل</button>",
|
||||
"253": "جارٍ ضغط الملف [%s]، يرجى الانتظار..."
|
||||
"253": "جارٍ ضغط الملف [%s]، يرجى الانتظار...",
|
||||
"254": "[Region ID] معرّف المنطقة غير صحيح، يرجى الرجوع إلى وثائق مزود خدمة S3 لتكوين معرّف المنطقة"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "Die Anfrage wurde vom Cloud-Speicher begrenzt. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher",
|
||||
"251": "Insgesamt ungenutzte Assets [%d], hier nur [%d] aufgeführt",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender kann fälschlicherweise den Kernel löschen, Daten löschen und die Leistung erheblich verringern. Es wird empfohlen, den SiYuan-Installationspfad und den Arbeitsbereichspfad zur Ausschlussliste hinzuzufügen<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Hinzufügen</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Ignorieren</button>",
|
||||
"253": "Datei [%s] wird komprimiert, bitte warten..."
|
||||
"253": "Datei [%s] wird komprimiert, bitte warten...",
|
||||
"254": "[Region ID] Falsche Regions-ID, bitte konsultieren Sie die Dokumentation des S3-Dienstanbieters zur Konfiguration der Regions-ID"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "Request has been rate-limited by cloud storage. Please check the settings and cloud storage permissions",
|
||||
"251": "Total unused assets [%d], only [%d] listed here",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender may mistakenly delete the kernel, delete data, and significantly reduce performance. It is recommended to add the SiYuan installation path and workspace path to the exclusion list<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Add</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Ignore</button>",
|
||||
"253": "Compressing file [%s], please wait..."
|
||||
"253": "Compressing file [%s], please wait...",
|
||||
"254": "[Region ID] Incorrect Region ID, please refer to the S3 service provider's documentation to configure the Region ID"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "La solicitud ha sido limitada por el almacenamiento en la nube. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube",
|
||||
"251": "Total de activos no utilizados [%d], solo [%d] listados aquí",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender puede eliminar por error el núcleo, eliminar datos y reducir significativamente el rendimiento. Se recomienda agregar la ruta de instalación y el espacio de trabajo de SiYuan a la lista de exclusiones<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Agregar</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Ignorar</button>",
|
||||
"253": "Comprimiendo el archivo [%s], por favor espere..."
|
||||
"253": "Comprimiendo el archivo [%s], por favor espere...",
|
||||
"254": "[Region ID] ID de región incorrecto, por favor consulte la documentación del proveedor de servicios S3 para configurar el ID de región"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "La demande a été limitée par le stockage cloud. Veuillez vérifier les paramètres et les autorisations de stockage cloud",
|
||||
"251": "Total des actifs inutilisés [%d], seulement [%d] listés ici",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender peut supprimer par erreur le noyau, supprimer des données et réduire considérablement les performances. Il est recommandé d'ajouter le chemin d'installation et l'espace de travail de SiYuan à la liste des exclusions<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Ajouter</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Ignorer</button>",
|
||||
"253": "Compression du fichier [%s], veuillez patienter..."
|
||||
"253": "Compression du fichier [%s], veuillez patienter...",
|
||||
"254": "[Region ID] ID de région incorrect, veuillez consulter la documentation du fournisseur de services S3 pour configurer l'ID de région"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "הבקשה הוגבלה על ידי אחסון הענן. אנא בדוק את ההגדרות והרשאות האחסון בענן",
|
||||
"251": "סך כל הנכסים שלא נעשה בהם שימוש [%d], רק [%d] מופיעים כאן",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender עלול למחוק בטעות את הליבה, למחוק נתונים ולהפחית משמעותית את הביצועים. מומלץ להוסיף את נתיב ההתקנה ונתיב סביבת העבודה של SiYuan לרשימת החריגים<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">הוסף</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">התעלם</button>",
|
||||
"253": "דוחס את הקובץ [%s], אנא המתן..."
|
||||
"253": "דוחס את הקובץ [%s], אנא המתן...",
|
||||
"254": "[Region ID] מזהה האזור שגוי, אנא עיין בתיעוד ספק שירותי S3 כדי להגדיר את מזהה האזור"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "La richiesta è stata limitata dall'archiviazione cloud. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud",
|
||||
"251": "Totale risorse inutilizzate [%d], qui elencate solo [%d]",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender potrebbe eliminare erroneamente il kernel, eliminare i dati e ridurre significativamente le prestazioni. Si consiglia di aggiungere il percorso di installazione e lo spazio di lavoro di SiYuan all'elenco delle esclusioni<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Aggiungi</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Ignora</button>",
|
||||
"253": "Compressione del file [%s], attendere prego..."
|
||||
"253": "Compressione del file [%s], attendere prego...",
|
||||
"254": "[Region ID] ID regione non corretto, si prega di consultare la documentazione del fornitore di servizi S3 per configurare l'ID regione"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "リクエストがクラウドストレージによって制限されました。設定を一つずつ確認し、クラウドストレージの権限を確認してください",
|
||||
"251": "未使用のアセットの合計 [%d]、ここにリストされているのは [%d] のみ",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender は、カーネルを誤って削除したり、データを削除したり、パフォーマンスを大幅に低下させたりする可能性があります。SiYuan のインストールパスとワークスペースパスを除外リストに追加することをお勧めします<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">追加</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">無視</button>",
|
||||
"253": "ファイル [%s] を圧縮しています、お待ちください..."
|
||||
"253": "ファイル [%s] を圧縮しています、お待ちください...",
|
||||
"254": "[Region ID] リージョンIDが正しくありません。S3サービスプロバイダーのドキュメントを参照してリージョンIDを設定してください"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "Żądanie zostało ograniczone przez przechowywanie w chmurze. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze",
|
||||
"251": "Łączna liczba nieużywanych zasobów [%d], tutaj wymieniono tylko [%d]",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender może błędnie usunąć jądro, usunąć dane i znacznie obniżyć wydajność. Zaleca się dodanie ścieżki instalacji i przestrzeni roboczej SiYuan do listy wykluczeń<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Dodaj</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Ignoruj</button>",
|
||||
"253": "Kompresja pliku [%s], proszę czekać..."
|
||||
"253": "Kompresja pliku [%s], proszę czekać...",
|
||||
"254": "[Region ID] Nieprawidłowy identyfikator regionu, proszę zapoznać się z dokumentacją dostawcy usług S3 w celu skonfigurowania identyfikatora regionu"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "Запрос был ограничен облачным хранилищем. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу",
|
||||
"251": "Всего неиспользованных активов [%d], здесь перечислены только [%d]",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender может ошибочно удалить ядро, удалить данные и значительно снизить производительность. Рекомендуется добавить путь установки и рабочее пространство SiYuan в список исключений<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">Добавить</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">Игнорировать</button>",
|
||||
"253": "Сжатие файла [%s], пожалуйста, подождите..."
|
||||
"253": "Сжатие файла [%s], пожалуйста, подождите...",
|
||||
"254": "[Region ID] Неправильный идентификатор региона, пожалуйста, обратитесь к документации поставщика услуг S3 для настройки идентификатора региона"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "請求已被雲端存儲限流,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置",
|
||||
"251": "未引用資源一共 ${x} 個,這裡僅列出 ${y} 個",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender 可能會誤殺內核、誤刪數據和嚴重降低運行性能,建議將思源安裝路徑和工作空間路徑添加到排除列表<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">添加</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">忽略</button>",
|
||||
"253": "正在壓縮文件 [%s],請稍等..."
|
||||
"253": "正在壓縮文件 [%s],請稍等...",
|
||||
"254": "[Region ID] 不正確,請參考 S3 服務提供商的文檔配置地域 ID"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,7 @@
|
|||
"250": "请求已被云端存储限流,请仔细逐个核对配置项,并检查云端存储相关权限配置",
|
||||
"251": "未引用资源一共 [%d] 个,这里仅列出 [%d] 个",
|
||||
"252": "\uD83D\uDEA8 Microsoft Defender 可能会误杀内核、误删数据和严重降低运行性能,建议将思源安装路径和工作空间路径添加到排除列表<span class=\"fn__space\"></span><button id=\"addMicrosoftDefenderExclusion\" class=\"b3-button\">添加</button><span class=\"fn__space\"></span><button id=\"ignoreAddMicrosoftDefenderExclusion\" class=\"b3-button b3-button--white\">忽略</button>",
|
||||
"253": "正在压缩文件 [%s],请稍等..."
|
||||
"253": "正在压缩文件 [%s],请稍等...",
|
||||
"254": "[Region ID] 不正确,请参考 S3 服务提供商的文档配置地域 ID"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,9 +153,13 @@ export const goBack = () => {
|
|||
closePanel();
|
||||
return;
|
||||
}
|
||||
if (window.JSAndroid && window.siyuan.backStack.length < 1) {
|
||||
if ((window.JSAndroid || window.JSHarmony) && window.siyuan.backStack.length < 1) {
|
||||
if (document.querySelector('#message [data-id="exitTip"]')) {
|
||||
window.JSAndroid.returnDesktop();
|
||||
if (window.JSAndroid) {
|
||||
window.JSAndroid.returnDesktop();
|
||||
} else if (window.JSHarmony) {
|
||||
window.JSHarmony.returnDesktop();
|
||||
}
|
||||
} else {
|
||||
showMessage(window.siyuan.languages.returnDesktop, 3000, "info", "exitTip");
|
||||
}
|
||||
|
|
|
|||
1
app/src/types/index.d.ts
vendored
1
app/src/types/index.d.ts
vendored
|
|
@ -199,6 +199,7 @@ interface Window {
|
|||
writeClipboard(text: string): void
|
||||
writeHTMLClipboard(text: string, html: string): void
|
||||
readClipboard(): string
|
||||
returnDesktop(): void
|
||||
}
|
||||
|
||||
Protyle: import("../protyle/method").default
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ func setNodeAttrs0(node *ast.Node, nameValues map[string]string) (oldAttrs map[s
|
|||
}
|
||||
|
||||
for name, value := range nameValues {
|
||||
value = util.RemoveInvalid(value)
|
||||
value = util.RemoveInvalidRetainCtrl(value)
|
||||
value = strings.TrimSpace(value)
|
||||
value = strings.TrimSuffix(value, ",")
|
||||
if "" == value {
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ func GetBlockRefText(id string) string {
|
|||
func GetDOMText(dom string) (ret string) {
|
||||
luteEngine := NewLute()
|
||||
tree := luteEngine.BlockDOM2Tree(dom)
|
||||
ret = renderBlockText(tree.Root.FirstChild, nil)
|
||||
ret = renderBlockText(tree.Root.FirstChild, nil, true)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ func getNodeRefText(node *ast.Node) string {
|
|||
ret = util.EscapeHTML(ret)
|
||||
return ret
|
||||
}
|
||||
return getNodeRefText0(node, Conf.Editor.BlockRefDynamicAnchorTextMaxLen)
|
||||
return getNodeRefText0(node, Conf.Editor.BlockRefDynamicAnchorTextMaxLen, true)
|
||||
}
|
||||
|
||||
func getNodeAvBlockText(node *ast.Node) (icon, content string) {
|
||||
|
|
@ -279,7 +279,7 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) {
|
|||
name = util.EscapeHTML(name)
|
||||
content = name
|
||||
} else {
|
||||
content = getNodeRefText0(node, 1024)
|
||||
content = getNodeRefText0(node, 1024, false)
|
||||
}
|
||||
|
||||
content = strings.TrimSpace(content)
|
||||
|
|
@ -290,7 +290,7 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) {
|
|||
return
|
||||
}
|
||||
|
||||
func getNodeRefText0(node *ast.Node, maxLen int) string {
|
||||
func getNodeRefText0(node *ast.Node, maxLen int, removeLineBreak bool) string {
|
||||
switch node.Type {
|
||||
case ast.NodeBlockQueryEmbed:
|
||||
return "Query Embed Block..."
|
||||
|
|
@ -313,7 +313,7 @@ func getNodeRefText0(node *ast.Node, maxLen int) string {
|
|||
if ast.NodeDocument != node.Type && node.IsContainerBlock() {
|
||||
node = treenode.FirstLeafBlock(node)
|
||||
}
|
||||
ret := renderBlockText(node, nil)
|
||||
ret := renderBlockText(node, nil, removeLineBreak)
|
||||
if maxLen < utf8.RuneCountInString(ret) {
|
||||
ret = gulu.Str.SubStr(ret, maxLen) + "..."
|
||||
}
|
||||
|
|
@ -481,9 +481,9 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
|
|||
} else {
|
||||
if "" == name {
|
||||
if ast.NodeListItem == parent.Type || ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type {
|
||||
name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen)
|
||||
name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen)
|
||||
} else {
|
||||
name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes), maxNameLen)
|
||||
name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes, true), maxNameLen)
|
||||
}
|
||||
}
|
||||
if ast.NodeHeading == parent.Type {
|
||||
|
|
@ -504,7 +504,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
|
|||
}
|
||||
if ast.NodeListItem == parent.Type {
|
||||
if "" == name {
|
||||
name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen)
|
||||
name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +542,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
|
|||
continue
|
||||
}
|
||||
|
||||
name = gulu.Str.SubStr(renderBlockText(b, excludeTypes), maxNameLen)
|
||||
name = gulu.Str.SubStr(renderBlockText(b, excludeTypes, true), maxNameLen)
|
||||
name = util.EscapeHTML(name)
|
||||
ret = append([]*BlockPath{{
|
||||
ID: b.ID,
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath, previousPath string) (sr
|
|||
}
|
||||
|
||||
box := Conf.Box(targetBoxID)
|
||||
headingText := getNodeRefText0(headingNode, Conf.Editor.BlockRefDynamicAnchorTextMaxLen)
|
||||
headingText := getNodeRefText0(headingNode, Conf.Editor.BlockRefDynamicAnchorTextMaxLen, true)
|
||||
if strings.Contains(headingText, "/") {
|
||||
headingText = strings.ReplaceAll(headingText, "/", "_")
|
||||
util.PushMsg(Conf.language(246), 7000)
|
||||
|
|
|
|||
|
|
@ -103,14 +103,16 @@ func renderOutline(heading *ast.Node, luteEngine *lute.Lute) (ret string) {
|
|||
return
|
||||
}
|
||||
|
||||
func renderBlockText(node *ast.Node, excludeTypes []string) (ret string) {
|
||||
func renderBlockText(node *ast.Node, excludeTypes []string, removeLineBreak bool) (ret string) {
|
||||
if nil == node {
|
||||
return
|
||||
}
|
||||
|
||||
ret = sql.NodeStaticContent(node, excludeTypes, false, false, false)
|
||||
ret = strings.TrimSpace(ret)
|
||||
ret = strings.ReplaceAll(ret, "\n", "")
|
||||
if removeLineBreak {
|
||||
ret = strings.ReplaceAll(ret, "\n", "")
|
||||
}
|
||||
ret = util.UnescapeHTML(ret)
|
||||
ret = util.EscapeHTML(ret)
|
||||
ret = strings.TrimSpace(ret)
|
||||
|
|
|
|||
|
|
@ -648,6 +648,8 @@ func formatRepoErrorMsg(err error) string {
|
|||
msgLowerCase := strings.ToLower(msg)
|
||||
if strings.Contains(msgLowerCase, "permission denied") || strings.Contains(msg, "access is denied") {
|
||||
msg = Conf.Language(33)
|
||||
} else if strings.Contains(msgLowerCase, "region was not a valid DNS name") {
|
||||
msg = Conf.language(254)
|
||||
} else if strings.Contains(msgLowerCase, "device or resource busy") || strings.Contains(msg, "is being used by another") {
|
||||
msg = fmt.Sprintf(Conf.Language(85), err)
|
||||
} else if strings.Contains(msgLowerCase, "cipher: message authentication failed") {
|
||||
|
|
|
|||
|
|
@ -188,12 +188,16 @@ func DocSaveAsTemplate(id, name string, overwrite bool) (code int, err error) {
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
// Code content in templates is not properly escaped https://github.com/siyuan-note/siyuan/issues/9649
|
||||
// Content in templates is not properly escaped
|
||||
// https://github.com/siyuan-note/siyuan/issues/9649
|
||||
// https://github.com/siyuan-note/siyuan/issues/13701
|
||||
switch n.Type {
|
||||
case ast.NodeCodeBlockCode:
|
||||
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("""), []byte("\""))
|
||||
case ast.NodeCodeSpanContent:
|
||||
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("""), []byte("\""))
|
||||
case ast.NodeBlockQueryEmbedScript:
|
||||
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("""), []byte("\""))
|
||||
case ast.NodeTextMark:
|
||||
if n.IsTextMarkType("code") {
|
||||
n.TextMarkTextContent = strings.ReplaceAll(n.TextMarkTextContent, """, "\"")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
|
|
@ -69,6 +70,13 @@ func RemoveInvalid(text string) (ret string) {
|
|||
return
|
||||
}
|
||||
|
||||
func RemoveInvalidRetainCtrl(text string) (ret string) {
|
||||
ret = strings.ReplaceAll(text, "\u00A0", " ") // NBSP 转换为普通空格
|
||||
ret = gulu.Str.RemoveZeroWidthCharacters(ret)
|
||||
ret = gulu.Str.RemovePUA(ret)
|
||||
return
|
||||
}
|
||||
|
||||
var NativeEmojiChars = map[string]bool{}
|
||||
|
||||
func InitEmojiChars() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue