From 11406674c2598f7fe47267ac2c23711a8515ae02 Mon Sep 17 00:00:00 2001 From: Juan Carlos Farah Date: Tue, 13 Aug 2019 20:14:39 +0200 Subject: [PATCH] feat: support math equations closes #164 --- package.json | 2 + src/components/common/Text.js | 56 ++++++++ src/components/phase/PhaseDescription.css | 3 + src/components/phase/PhaseDescription.js | 14 +- src/components/phase/PhaseText.js | 10 +- src/components/space/SpaceDescription.css | 18 ++- src/components/space/SpaceDescription.js | 17 ++- src/config/constants.js | 8 ++ src/index.js | 6 + src/test/fixtures/math.js | 145 ++++++++++++++++++++ src/utils/math.js | 57 ++++++++ src/utils/math.test.js | 156 ++++++++++++++++++++++ yarn.lock | 88 +++++++++++- 13 files changed, 562 insertions(+), 18 deletions(-) create mode 100644 src/components/common/Text.js create mode 100644 src/components/phase/PhaseDescription.css create mode 100644 src/test/fixtures/math.js create mode 100644 src/utils/math.js create mode 100644 src/utils/math.test.js diff --git a/package.json b/package.json index ed3e7aa5..75630d02 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "i18next": "15.1.0", "immutable": "4.0.0-rc.12", "is-online": "8.2.0", + "katex": "0.11.0", "lodash": "4.17.13", "lowdb": "1.0.0", "md5": "2.2.1", @@ -93,6 +94,7 @@ "react-immutable-proptypes": "2.1.0", "react-json-view": "1.19.1", "react-loading": "2.0.3", + "react-quill": "1.3.3", "react-redux": "7.0.3", "react-redux-toastr": "7.4.9", "react-resizable": "1.8.0", diff --git a/src/components/common/Text.js b/src/components/common/Text.js new file mode 100644 index 00000000..264a00ce --- /dev/null +++ b/src/components/common/Text.js @@ -0,0 +1,56 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ReactQuill from 'react-quill'; +import { hasMath, renderMath } from '../../utils/math'; + +const modules = { + toolbar: false, +}; + +const formats = [ + 'header', + 'bold', + 'italic', + 'underline', + 'strike', + 'blockquote', + 'list', + 'bullet', + 'indent', + 'link', + 'image', + 'formula', +]; + +const Text = ({ content, style, className }) => { + let parsedContent = content; + if (hasMath(content)) { + parsedContent = renderMath(parsedContent); + } + return ( +
+ +
+ ); +}; + +Text.propTypes = { + content: PropTypes.string, + className: PropTypes.string, + style: PropTypes.shape({}), +}; + +Text.defaultProps = { + content: '', + className: '', + style: {}, +}; + +export default Text; diff --git a/src/components/phase/PhaseDescription.css b/src/components/phase/PhaseDescription.css new file mode 100644 index 00000000..b135dd74 --- /dev/null +++ b/src/components/phase/PhaseDescription.css @@ -0,0 +1,3 @@ +.PhaseDescriptionText p { + font-size: x-large; +} diff --git a/src/components/phase/PhaseDescription.js b/src/components/phase/PhaseDescription.js index 57334569..a79d0b40 100644 --- a/src/components/phase/PhaseDescription.js +++ b/src/components/phase/PhaseDescription.js @@ -1,9 +1,21 @@ import React from 'react'; import PropTypes from 'prop-types'; +import Text from '../common/Text'; +import './PhaseDescription.css'; + +const style = { + marginBottom: '2rem', +}; const PhaseDescription = ({ description }) => { if (description && description !== '') { - return
; + return ( + + ); } return null; }; diff --git a/src/components/phase/PhaseText.js b/src/components/phase/PhaseText.js index 2a87613c..fac5bf26 100644 --- a/src/components/phase/PhaseText.js +++ b/src/components/phase/PhaseText.js @@ -1,9 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; +import Text from '../common/Text'; -const PhaseText = ({ content }) => ( -
-); +const style = { + marginTop: '2rem', + marginBottom: '2rem', +}; + +const PhaseText = ({ content }) => ; PhaseText.propTypes = { content: PropTypes.string, diff --git a/src/components/space/SpaceDescription.css b/src/components/space/SpaceDescription.css index 6c2633d2..e564eeca 100644 --- a/src/components/space/SpaceDescription.css +++ b/src/components/space/SpaceDescription.css @@ -1,11 +1,15 @@ .SpaceDescription { - height: 100%; - display: flex; - justify-content: center; - align-items: center; + height: 100%; + display: flex; + justify-content: center; + align-items: center; } .SpaceDescriptionDiv { - justify-content: center; - align-items: center; -} \ No newline at end of file + justify-content: center; + align-items: center; +} + +.SpaceDescriptionText p { + font-size: xx-large; +} diff --git a/src/components/space/SpaceDescription.js b/src/components/space/SpaceDescription.js index a5b1259e..ab5c0732 100644 --- a/src/components/space/SpaceDescription.js +++ b/src/components/space/SpaceDescription.js @@ -1,11 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; import Button from '@material-ui/core/Button'; -import { Typography, withStyles } from '@material-ui/core'; +import { withStyles } from '@material-ui/core'; import { useTranslation } from 'react-i18next'; import Styles from '../../Styles'; import './SpaceDescription.css'; import Banner from '../common/Banner'; +import Text from '../common/Text'; + +const style = { + fontSize: 'large', +}; const renderPreviewWarning = t => { return ( @@ -25,9 +30,13 @@ const SpaceDescription = ({ description, classes, start, saved }) => {
{saved ? null : renderPreviewWarning(t)} - -
- +
+ +