From aae9e741745cb77d45182e288961fafe3d261b37 Mon Sep 17 00:00:00 2001 From: xmcp Date: Sun, 10 Mar 2019 17:42:20 +0800 Subject: [PATCH] add text splitter --- src/Common.js | 32 +++++++++++++++++++------------- src/UserAction.js | 2 +- src/text_splitter.js | 24 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 src/text_splitter.js diff --git a/src/Common.js b/src/Common.js index e9f5cc2..c5f2f24 100644 --- a/src/Common.js +++ b/src/Common.js @@ -1,8 +1,8 @@ import React, {Component, PureComponent} from 'react'; import {PKUHELPER_ROOT} from './flows_api'; +import {split_text,NICKNAME_RE,PID_RE,URL_RE} from './text_splitter' import TimeAgo from 'react-timeago'; -import Linkify from 'react-linkify'; import chineseStrings from 'react-timeago/lib/language-strings/zh-CN'; import buildFormatter from 'react-timeago/lib/formatters/buildFormatter'; @@ -12,9 +12,6 @@ const chinese_format=buildFormatter(chineseStrings); export const API_BASE=PKUHELPER_ROOT+'services/pkuhole'; -const PID_RE=/(^|[^\d])([1-9]\d{4,5})(?!\d)/g; -const NICKNAME_RE=/(^|[^A-Za-z])((?:(?:Angry|Baby|Crazy|Diligent|Excited|Fat|Greedy|Hungry|Interesting|Japanese|Kind|Little|Magic|Naïve|Old|Powerful|Quiet|Rich|Superman|THU|Undefined|Valuable|Wifeless|Xiangbuchulai|Young|Zombie)\s)?(?:Alice|Bob|Carol|Dave|Eve|Francis|Grace|Hans|Isabella|Jason|Kate|Louis|Margaret|Nathan|Olivia|Paul|Queen|Richard|Susan|Thomas|Uma|Vivian|Winnie|Xander|Yasmine|Zach)|You Win(?: \d+)?|洞主)(?![A-Za-z])/gi; - function pad2(x) { return x<10 ? '0'+x : ''+x; } @@ -44,19 +41,28 @@ export function TitleLine(props) { export class HighlightedText extends PureComponent { render() { - let parts=[].concat.apply([], this.props.text.split(PID_RE).map((p)=>p.split(NICKNAME_RE))); + let parts=split_text(this.props.text,[ + ['url',URL_RE], + ['pid',PID_RE], + ['nickname',NICKNAME_RE], + ]); + function normalize_url(url) { + return /^https?:\/\//.test(url) ? url : 'http://'+url; + } return ( - -
-                    {parts.map((p,idx)=>(
+            
+                {parts.map((part,idx)=>{
+                    let [rule,p]=part;
+                    return (
                         {
-                            PID_RE.test(p) ? {e.preventDefault(); this.props.show_pid(p);}}>{p} :
-                            NICKNAME_RE.test(p) ? {p} :
+                            rule==='url' ? {p} :
+                            rule==='pid' ? {e.preventDefault(); this.props.show_pid(p);}}>{p} :
+                            rule==='nickname' ? {p} :
                             p
                         }
-                    ))}
-                
- + ); + })} +
) } } diff --git a/src/UserAction.js b/src/UserAction.js index 5304ebf..1237c25 100644 --- a/src/UserAction.js +++ b/src/UserAction.js @@ -235,7 +235,7 @@ export class ReplyForm extends Component { }) .catch((e)=>{ console.error(e); - alert('回复失败\n(树洞服务器经常抽风,其实有可能已经回复上了,不妨点“刷新回复”看一看)'); + alert('回复失败'); this.setState({ loading_status: 'done', }); diff --git a/src/text_splitter.js b/src/text_splitter.js new file mode 100644 index 0000000..b11e12a --- /dev/null +++ b/src/text_splitter.js @@ -0,0 +1,24 @@ +export const PID_RE=/(^|[^\d])([1-9]\d{4,5})(?!\d)/g; +export const NICKNAME_RE=/(^|[^A-Za-z])((?:(?:Angry|Baby|Crazy|Diligent|Excited|Fat|Greedy|Hungry|Interesting|Japanese|Kind|Little|Magic|Naïve|Old|Powerful|Quiet|Rich|Superman|THU|Undefined|Valuable|Wifeless|Xiangbuchulai|Young|Zombie)\s)?(?:Alice|Bob|Carol|Dave|Eve|Francis|Grace|Hans|Isabella|Jason|Kate|Louis|Margaret|Nathan|Olivia|Paul|Queen|Richard|Susan|Thomas|Uma|Vivian|Winnie|Xander|Yasmine|Zach)|You Win(?: \d+)?|洞主)(?![A-Za-z])/gi; +export const URL_RE=/(?:^|\b)((?:https?:\/\/)?(?:[\w-]+\.)+[a-zA-Z]{2,3}(?::\d{1,5})?(?:\/[\w~!@#$%^&*()-_=+[\];,./?]*)?)(?:$|\b)/gi; + +export function split_text(txt,rules) { + // rules: [['name',/regex/],...] + // return: [['name','part'],[null,'part'],...] + + txt=[[null,txt]]; + rules.forEach((rule)=>{ + let [name,regex]=rule; + txt=[].concat.apply([],txt.map((part)=>{ + let [rule,content]=part; + if(rule) // already tagged by previous rules + return [part]; + else { + return content.split(regex).map((seg)=>( + regex.test(seg) ? [name,seg] : [null,seg] + )); + } + })); + }); + return txt; +}