Skip to content

Commit

Permalink
Merge pull request #4 from tarjei/translator-support
Browse files Browse the repository at this point in the history
Optional MathInput + translator support
  • Loading branch information
Tran-Loc Le authored Sep 23, 2017
2 parents 871f890 + d0e63e9 commit e09610a
Show file tree
Hide file tree
Showing 161 changed files with 13,914 additions and 353 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
lib/*
/.idea/
node_modules
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
node_modules

# sources
/src/
/draft-js-katex-plugin/src.bak/
webpack.config.js
.babelrc
.gitignore
Expand Down
7 changes: 7 additions & 0 deletions .storybook/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { configure } from '@storybook/react';

function loadStories() {
require('../stories');
}

configure(loadStories, module);
2 changes: 2 additions & 0 deletions .storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathquill/0.10.1/mathquill.min.js"></script>
51 changes: 51 additions & 0 deletions .storybook/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// you can use this file to add your custom webpack plugins, loaders and anything you like.
// This is just the basic way to add additional webpack configurations.
// For more information refer the docs: https://storybook.js.org/docs/react-storybook/configurations/custom-webpack-config

// IMPORTANT
// When you add this file, we won't add the default configurations which is similar
// to "React Create App". This only has babel loader to load JavaScript.
const path = require('path');

module.exports = {
plugins: [
// your custom plugins
],
module: {
rules: [
/*
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader", "postcss-loader"],
include: path.resolve(__dirname, '../')
},
*/
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader', 'postcss-loader'],
include: path.resolve(__dirname, '../'),
},
],
/*
loaders: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
localIdentName: 'draftJsKatexPlugin__[local]__[hash:base64:5]',
},
},
'postcss-loader'
]
}]
*/
},
};
106 changes: 101 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,118 @@

This plugin insert and render LaTeX using [KaTeX](https://github.com/Khan/KaTeX), modified from [TeX example](https://github.com/facebook/draft-js/tree/master/examples/draft-0-10-0/tex).

- Integrated with [Khan/math-input](https://github.com/Khan/math-input).

## Usage

Add KaTeX style
Add MathQuill libs if you want to use MathInput:
```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathquill/0.10.1/mathquill.min.js"></script>
```

Add plugin
```js
import createKaTeXPlugin from 'draft-js-katex-plugin';
import katex from 'katex'

const kaTeXPlugin = createKaTeXPlugin({katex});

const { InsertButton } = kaTeXPlugin;
```

With MathInput:

```js
import createKaTeXPlugin from 'draft-js-katex-plugin';
import katex from 'katex'
import MathInput from '../src/components/math-input/components/app';


const kaTeXPlugin = createKaTeXPlugin();
const kaTeXPlugin = createKaTeXPlugin({katex, MathInput});

const { InsertButton } = kaTeXPlugin;
```

## TODO
There are more examples in the `stories/index.js` file.

## Configuration options:

Here shown with defaults:
```js
{
katex, // the katex object or a wrapper defining render() and __parse().

doneContent: {
valid: 'Done',
invalid: 'Invalid TeX',
},

MathInput: null, // Sett to the MathInput element to use MathInput
removeContent: 'Remove',
theme: {
// CSS classes, either you define them or they come from the plugin.css import
saveButton: '',
removeButton: '',
invalidButton: '',
buttons: '',
}
// function (string) -> string.
translator: null,
}
```


- [ ] Integrate with [Khan/math-input](https://github.com/Khan/math-input).
## Loading katex async
If you want to load katex in the background instead of right away, then you can do this by wrapping the katex object that you pass into the plugin:

```js
//file: asyncKatex.js
let katex = null
const renderQueue = []

System.import(/* webpackChunkName: 'katex' */ 'katex')
.then(function methodName(module) {
katex = module.default
})
.then(() => {
console.log('Katex loaded, ', renderQueue)
if (renderQueue.length) {
const now = Date.now()
renderQueue.map(([d, expression, baseNode, options]) => {
if (now - d < 4000) {
katex.render(expression, baseNode, options)
}
})
}
})

export default {
render: (expression, baseNode, options) => {
if (katex) {
return katex.render(expression, baseNode, options)
}

renderQueue.push([Date.now(), expression, baseNode, options])
},
// parse is only used by this plugin to check syntax validity.
__parse: (expression, options) => {
if (katex) {
return katex.parse(expression, options)
}
return null
}
}


```

Store this in a separate file and and pass it to the plugin config:

```js
import createKaTeXPlugin from 'draft-js-katex-plugin';
import katex from './asyncKatex'

const kaTeXPlugin = createKaTeXPlugin({katex});

```
15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,21 @@
"url": "https://github.com/letranloc/draft-js-katex-plugin/issues"
},
"dependencies": {
"aphrodite": "^1.2.3",
"decorate-component-with-props": "^1.0.2",
"draft-js": ">=0.9.1",
"katex": "^0.7.1",
"jquery": "^3.2.1",
"katex": "^0.8.3",
"react": "^15.4.2",
"react-addons-css-transition-group": "^15.6.0",
"react-addons-pure-render-mixin": "^15.6.0",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"union-class-names": "^1.0.0"
},
"devDependencies": {
"@storybook/react": "^3.2.8",
"asciimath-to-latex": "^0.3.2",
"autoprefixer": "^6.7.7",
"babel-cli": "^6.14.0",
"babel-core": "^6.14.0",
Expand All @@ -29,6 +37,7 @@
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"css-loader": "^0.27.2",
"draft-js-plugins-editor": "2.0.0-rc7",
"eslint": "^3.5.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-plugin-import": "^2.2.0",
Expand Down Expand Up @@ -79,6 +88,8 @@
"lint:eslint": "eslint --rule 'mocha/no-exclusive-tests:2' ./",
"lint:eslint:fix": "eslint --fix --rule 'mocha/no-exclusive-tests:2' ./",
"lint:staged": "lint-staged",
"prepublish": "npm run build"
"prepublish": "npm run build",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
}
}
7 changes: 7 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable global-require */

module.exports = {
plugins: [
require('autoprefixer')({ browsers: ['> 1%'] })
]
};
25 changes: 13 additions & 12 deletions src/components/InsertKatexButton.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
import React, { Component, PropTypes } from 'react';
import React, { Children, Component } from 'react';
import PropTypes from 'prop-types';
import unionClassNames from 'union-class-names';
import insertTeXBlock from '../modifiers/insertTeXBlock';

export default class InsertKatexButton extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
children: PropTypes.node,
initialValue: PropTypes.string,
translator: PropTypes.func.isRequired,
theme: PropTypes.any,
};

static defaultProps = {
theme: {}
initialValue: null,
tex: null,
};

onClick = () => {
const { store } = this.props;
const { store, translator, initialValue } = this.props;
const editorState = store.getEditorState();
store.setEditorState(insertTeXBlock(editorState));
store.setEditorState(insertTeXBlock(editorState, translator, initialValue));
};

render() {
const { theme, className, children } = this.props;
const { theme = {}, className, children, defaultContent } = this.props;
const combinedClassName = unionClassNames(theme.insertButton, className);
const content = Children.count(children) ? children : defaultContent;

return (
<button
className={combinedClassName}
onClick={this.onClick}
>
{children}
<button className={combinedClassName} onClick={this.onClick}>
{content}
</button>
);
}
Expand Down
32 changes: 21 additions & 11 deletions src/components/KatexOutput.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import katex from 'katex';
import React from 'react';
import PropTypes from 'prop-types';

export default class KatexOutput extends React.Component {
static propTypes = {
value: PropTypes.string.isRequired,
katex: PropTypes.object.isRequired,
displayMode: PropTypes.bool.isRequired,
onClick: PropTypes.func,
};
static defaultProps = {
onClick: () => {},
};
constructor(props) {
super(props);
this.timer = null;
Expand All @@ -11,8 +20,8 @@ export default class KatexOutput extends React.Component {
this.update();
}

componentWillReceiveProps({ content }) {
if (content !== this.props.content) {
componentWillReceiveProps({ value }) {
if (value !== this.props.value) {
this.update();
}
}
Expand All @@ -22,24 +31,25 @@ export default class KatexOutput extends React.Component {
this.timer = null;
}

update() {
update = () => {
const { katex } = this.props;
if (this.timer) {
clearTimeout(this.timer);
}

this.timer = setTimeout(() => {
katex.render(
this.props.content,
this.container,
{ displayMode: true }
);
katex.render(this.props.value, this.container, {
displayMode: this.props.displayMode,
});
}, 0);
}
};

render() {
return (
<div
ref={(container) => { this.container = container; }}
ref={container => {
this.container = container;
}}
onClick={this.props.onClick}
/>
);
Expand Down
Loading

0 comments on commit e09610a

Please sign in to comment.