forked from newthuhole/hole_thu_frontend
add text splitter
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
import React, {Component, PureComponent} from 'react';
|
import React, {Component, PureComponent} from 'react';
|
||||||
import {PKUHELPER_ROOT} from './flows_api';
|
import {PKUHELPER_ROOT} from './flows_api';
|
||||||
|
import {split_text,NICKNAME_RE,PID_RE,URL_RE} from './text_splitter'
|
||||||
|
|
||||||
import TimeAgo from 'react-timeago';
|
import TimeAgo from 'react-timeago';
|
||||||
import Linkify from 'react-linkify';
|
|
||||||
import chineseStrings from 'react-timeago/lib/language-strings/zh-CN';
|
import chineseStrings from 'react-timeago/lib/language-strings/zh-CN';
|
||||||
import buildFormatter from 'react-timeago/lib/formatters/buildFormatter';
|
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';
|
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) {
|
function pad2(x) {
|
||||||
return x<10 ? '0'+x : ''+x;
|
return x<10 ? '0'+x : ''+x;
|
||||||
}
|
}
|
||||||
@@ -44,19 +41,28 @@ export function TitleLine(props) {
|
|||||||
|
|
||||||
export class HighlightedText extends PureComponent {
|
export class HighlightedText extends PureComponent {
|
||||||
render() {
|
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 (
|
return (
|
||||||
<Linkify properties={{target: '_blank'}}>
|
|
||||||
<pre>
|
<pre>
|
||||||
{parts.map((p,idx)=>(
|
{parts.map((part,idx)=>{
|
||||||
|
let [rule,p]=part;
|
||||||
|
return (
|
||||||
<span key={idx}>{
|
<span key={idx}>{
|
||||||
PID_RE.test(p) ? <a href={'##'+p} onClick={(e)=>{e.preventDefault(); this.props.show_pid(p);}}>{p}</a> :
|
rule==='url' ? <a href={normalize_url(p)} target="_blank" rel="noopener">{p}</a> :
|
||||||
NICKNAME_RE.test(p) ? <span style={{backgroundColor: this.props.color_picker.get(p)}}>{p}</span> :
|
rule==='pid' ? <a href={'##'+p} onClick={(e)=>{e.preventDefault(); this.props.show_pid(p);}}>{p}</a> :
|
||||||
|
rule==='nickname' ? <span style={{backgroundColor: this.props.color_picker.get(p)}}>{p}</span> :
|
||||||
p
|
p
|
||||||
}</span>
|
}</span>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</pre>
|
</pre>
|
||||||
</Linkify>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ export class ReplyForm extends Component {
|
|||||||
})
|
})
|
||||||
.catch((e)=>{
|
.catch((e)=>{
|
||||||
console.error(e);
|
console.error(e);
|
||||||
alert('回复失败\n(树洞服务器经常抽风,其实有可能已经回复上了,不妨点“刷新回复”看一看)');
|
alert('回复失败');
|
||||||
this.setState({
|
this.setState({
|
||||||
loading_status: 'done',
|
loading_status: 'done',
|
||||||
});
|
});
|
||||||
|
|||||||
24
src/text_splitter.js
Normal file
24
src/text_splitter.js
Normal file
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user