├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
└── src
├── Editor.js
├── index.js
├── parse.js
└── styles.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /build
3 | package-lock.json
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | a **Work-in-Progress** grammatical WISYWIG text editor, using [draftjs](https://draftjs.org/)
2 |
3 | 
4 |
5 | ### [Demo](http://nlp-compromise.github.io/react-nlp/index.html)
6 |
7 | to play with it, run `npm run start`
8 |
9 | will publish it once it's working better
10 |
11 | MIT
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-nlp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "compromise": "^11.12.0",
7 | "draft-js": "^0.10.5",
8 | "react": "^16.5.0",
9 | "react-dom": "^16.5.0",
10 | "react-scripts": "1.1.5"
11 | },
12 | "scripts": {
13 | "start": "react-scripts start",
14 | "build": "react-scripts build",
15 | "test": "react-scripts test --env=jsdom",
16 | "eject": "react-scripts eject"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nlp-compromise/react-nlp/d18d25ffb61482f61a6216fbcd2772aa7871881a/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/Editor.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { Editor, EditorState, RichUtils, CompositeDecorator } from "draft-js";
3 | import styles from "./styles";
4 | import { findNoun, renderNoun } from "./parse";
5 |
6 | class MyEditor extends Component {
7 | constructor(props) {
8 | super(props);
9 | const compositeDecorator = new CompositeDecorator([
10 | {
11 | strategy: findNoun,
12 | component: renderNoun
13 | }
14 | ]);
15 | this.state = {
16 | editorState: EditorState.createEmpty(compositeDecorator)
17 | };
18 | this.focus = () => this.refs.editor.focus();
19 | this.onChange = editorState => {
20 | this.setState({
21 | editorState
22 | });
23 | };
24 | }
25 | render() {
26 | return (
27 |
38 | );
39 | }
40 | }
41 |
42 | export default MyEditor;
43 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import Editor from "./Editor";
4 |
5 | ReactDOM.render(, document.getElementById("root"));
6 |
--------------------------------------------------------------------------------
/src/parse.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from "./styles";
3 | import nlp from "compromise";
4 |
5 | export function findNoun(contentBlock, callback) {
6 | const text = contentBlock.getText();
7 | let doc = nlp(text);
8 | let nouns = doc.nouns().out("offsets");
9 | nouns.forEach(o => {
10 | callback(o.wordStart, o.wordEnd);
11 | });
12 | }
13 | export const renderNoun = props => {
14 | return (
15 |
16 | {props.children}
17 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/src/styles.js:
--------------------------------------------------------------------------------
1 | const blue = "#6699cc";
2 | const red = "#cc7066";
3 | const green = "#6accb2";
4 | // const navy = '#335799'
5 | // const yellow = '#e1e6b3'
6 | // const pink = '#e6b8b3
7 | // const olive = '#7f9c6c'
8 | // const brown = '#9c896c'
9 | // const darkblue = '#6c7f9c'
10 | // const orange = '#cc8a66'
11 | // const purple = '#d8b3e6'
12 | // const lightblue = '#66a8cc'
13 | // const lightgreen = '#66ccac'
14 | // const darkgreen = '#339957'
15 | // const darkbrown = '#605439'
16 | // const burnt = '#603a39'
17 | // const rose = '#e6b4b3'
18 | // const dimblue = '#949a9e'
19 | // const beige = '#e6d7b3'
20 |
21 | // const offwhite = '#fbfbfb'
22 |
23 | // const lightgrey = '#e9edec'
24 | // const dimgrey = '#d7d5d2'
25 | // const grey = '#4d4d4d'
26 | // const midgrey = '#949a9e'
27 | // const slategrey = '#51433e'
28 | // const bluegrey = '#606c74'
29 | // const darkgrey = '#443d3d'
30 | // const offblack = '#333333'
31 |
32 | const styles = {
33 | root: {
34 | fontFamily: "'Helvetica', sans-serif",
35 | padding: 20,
36 | width: 600
37 | },
38 | editor: {
39 | border: "1px solid #ddd",
40 | cursor: "text",
41 | fontSize: 20,
42 | minHeight: 30,
43 | padding: 10
44 | },
45 | red: {
46 | color: red
47 | },
48 | blue: {
49 | color: blue
50 | },
51 | green: {
52 | color: green
53 | },
54 | hashtag: {
55 | color: "rgba(95, 184, 138, 1.0)"
56 | }
57 | };
58 | export default styles;
59 |
--------------------------------------------------------------------------------