|
1 | 1 | import React from 'react';
|
2 |
| -import logo from './logo.svg'; |
3 |
| -import './App.css'; |
| 2 | +import nlp from 'compromise' |
| 3 | +const ReactMarkdown = require('react-markdown') |
4 | 4 |
|
5 |
| -function App() { |
| 5 | +const CorpusContext = React.createContext() |
| 6 | + |
| 7 | +let currentWord = -1 |
| 8 | + |
| 9 | +let Line = (props) => { |
| 10 | + const corpusContext = React.useContext(CorpusContext) |
| 11 | + let words |
| 12 | + |
| 13 | + if(!corpusContext.parseEntire) { |
| 14 | + const dump = nlp(props.children) |
| 15 | + words = dump.words().map(word => ({ |
| 16 | + text: word.text ? word.text().trim() : "", |
| 17 | + id: word.list[0] ? word.list[0].start : "", |
| 18 | + raw: "", |
| 19 | + tags: word.json() ? word.json()[0].terms[0].tags : [] |
| 20 | + })) |
| 21 | + }else { |
| 22 | + words = nlp.tokenize(props.children).terms().map(word => ({ |
| 23 | + text: word.text ? word.text().trim(): "", |
| 24 | + id: word.list[0] ? word.list[0].start : "", |
| 25 | + raw: word.json() ? word.json() : "", |
| 26 | + tags: [] |
| 27 | + })) |
| 28 | + } |
| 29 | + // console.log("words:", words) |
| 30 | + if(words.world) words = [] |
| 31 | + |
| 32 | + return ( |
| 33 | + <> |
| 34 | + { |
| 35 | + words |
| 36 | + .filter(word => word.text !== "") |
| 37 | + .map(word => <Word key={word.id} raw={word.raw} tags={word.tags}>{ word.text }</Word>) |
| 38 | + } |
| 39 | + </> |
| 40 | + ) |
| 41 | +} |
| 42 | + |
| 43 | +let Word = (props) => { |
| 44 | + const corpusContext = React.useContext(CorpusContext) |
| 45 | + let tagString |
| 46 | + |
| 47 | + if(!corpusContext.parseEntire) { |
| 48 | + tagString = props.tags ? props.tags.join(" ") : "" |
| 49 | + }else { |
| 50 | + currentWord++ |
| 51 | + const thisWordIndex = currentWord |
| 52 | + const thisWordData = corpusContext.terms[thisWordIndex] |
| 53 | + |
| 54 | + tagString = thisWordData ? thisWordData.terms.map(term => term.tags).reduce((acc, val) => { |
| 55 | + return acc.concat(val) |
| 56 | + }, []).join(" ") : "" |
| 57 | + } |
| 58 | + |
| 59 | + // console.log(props.children, props.raw, corpusContext[thisWord]) |
| 60 | + |
| 61 | + return ( |
| 62 | + <span className={"word " + tagString}> |
| 63 | + <span className="word__content"> |
| 64 | + {props.children} |
| 65 | + </span> |
| 66 | + <span> </span> |
| 67 | + <span className="word__hover"> |
| 68 | + {tagString} |
| 69 | + </span> |
| 70 | + </span> |
| 71 | + ) |
| 72 | +} |
| 73 | + |
| 74 | +let Renderer = (props) => { |
| 75 | + // console.log(props) |
| 76 | + // const corpusData = React.useContext(CorpusContext) |
| 77 | + // console.log("corpusData:", corpusData) |
| 78 | + // corpusData.debug() |
| 79 | + |
| 80 | + return ( |
| 81 | + <> |
| 82 | + {props.children} |
| 83 | + </> |
| 84 | + ) |
| 85 | +} |
| 86 | + |
| 87 | +let Editor = () => { |
| 88 | + const [rawContent, setRawContent] = React.useState(localStorage.getItem("content") ? localStorage.getItem("content") : "") |
| 89 | + const [corpusData, setCorpusData] = React.useState(nlp("")) |
| 90 | + const [parseEntire, setParseEntire] = React.useState(true) |
| 91 | + |
| 92 | + let handleInputChange = (e) => { |
| 93 | + localStorage.setItem("content", e.target.value) |
| 94 | + setRawContent(e.target.value) |
| 95 | + } |
| 96 | + |
| 97 | + let handleParseChange = (e) => { |
| 98 | + currentWord = -1 |
| 99 | + setParseEntire(!parseEntire) |
| 100 | + } |
| 101 | + |
| 102 | + React.useEffect(() => { |
| 103 | + // get innerText || textContent of #renderer |
| 104 | + let renderer = document.getElementById("renderer") |
| 105 | + let plainText = renderer.textContent || renderer.innerText |
| 106 | + |
| 107 | + currentWord = -1 |
| 108 | + // console.log(plainText) |
| 109 | + // set corpusData to nlp() of innerText |
| 110 | + const dump = nlp(plainText) |
| 111 | + console.log(dump) |
| 112 | + setCorpusData(dump.terms().json()) |
| 113 | + }, [rawContent]) |
| 114 | + |
6 | 115 | return (
|
7 |
| - <div className="App"> |
8 |
| - <header className="App-header"> |
9 |
| - <img src={logo} className="App-logo" alt="logo" /> |
10 |
| - <p> |
11 |
| - Edit <code>src/App.js</code> and save to reload. |
12 |
| - </p> |
13 |
| - <a |
14 |
| - className="App-link" |
15 |
| - href="https://reactjs.org" |
16 |
| - target="_blank" |
17 |
| - rel="noopener noreferrer" |
18 |
| - > |
19 |
| - Learn React |
20 |
| - </a> |
21 |
| - </header> |
22 |
| - </div> |
23 |
| - ); |
| 116 | + <> |
| 117 | + <textarea onChange={handleInputChange} value={localStorage.getItem("content") ? localStorage.getItem("content") : ""}></textarea> |
| 118 | + {/* <button onClick={handleParseChange}>Parse Mode: {parseEntire ? "Entire" : "Text"}</button> */} |
| 119 | + <div id="renderer"> |
| 120 | + <CorpusContext.Provider value={{terms: corpusData, parseEntire: parseEntire}}> |
| 121 | + <ReactMarkdown source={rawContent} rawSourcePos={true} renderers={{ |
| 122 | + text: Line, |
| 123 | + root: Renderer |
| 124 | + }} /> |
| 125 | + </CorpusContext.Provider> |
| 126 | + </div> |
| 127 | + </> |
| 128 | + ) |
24 | 129 | }
|
25 | 130 |
|
26 |
| -export default App; |
| 131 | +export default Editor; |
0 commit comments