Skip to content
Snippets Groups Projects
Commit c52e68f7 authored by chris's avatar chris
Browse files

math input rules

parent 7e9674b6
No related branches found
No related tags found
1 merge request!186add katex fonts
export { default as InfoArea } from './src/components/infoArea/InfoArea';
export { default as Overlay } from './src/components/Overlay'; export { default as Overlay } from './src/components/Overlay';
export { default as Button } from './src/components/Button'; export { default as Button } from './src/components/Button';
export { default as icons } from './src/icons/icons'; export { default as icons } from './src/icons/icons';
......
import React from "react";
import styled from "styled-components";
const InfoAreaContainer = styled.div`
${"" /* height: ${props => (props.height ? props.height : "30px")};
position: fixed;
bottom: 0;
z-index: 9999;
background: #efefef;
width: 100%;*/};
`;
const InfoArea = () => <InfoAreaContainer />;
export default InfoArea;
/* eslint-disable */ /* eslint-disable */
import { EditorState, TextSelection } from 'prosemirror-state'; import { EditorState, TextSelection } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view'; import { EditorView } from 'prosemirror-view';
import { StepMap } from 'prosemirror-transform'; import { StepMap } from 'prosemirror-transform';
......
/* eslint-disable */
import { Plugin as ProsePlugin, PluginKey } from 'prosemirror-state'; import { Plugin as ProsePlugin, PluginKey } from 'prosemirror-state';
import { MathView } from './math-nodeview'; import { MathView } from './math-nodeview';
/** /**
...@@ -11,13 +12,13 @@ function createMathView(displayMode) { ...@@ -11,13 +12,13 @@ function createMathView(displayMode) {
* Docs says that for any function proprs, the current plugin instance * Docs says that for any function proprs, the current plugin instance
* will be bound to `this`. However, the typings don't reflect this. * will be bound to `this`. However, the typings don't reflect this.
*/ */
const pluginState = mathPluginKey.getState(view.state); let pluginState = mathPluginKey.getState(view.state);
if (!pluginState) { if (!pluginState) {
throw new Error('no math plugin!'); throw new Error('no math plugin!');
} }
const nodeViews = pluginState.activeNodeViews; let nodeViews = pluginState.activeNodeViews;
// set up NodeView // set up NodeView
const nodeView = new MathView( let nodeView = new MathView(
node, node,
view, view,
getPos, getPos,
...@@ -30,8 +31,8 @@ function createMathView(displayMode) { ...@@ -30,8 +31,8 @@ function createMathView(displayMode) {
return nodeView; return nodeView;
}; };
} }
const mathPluginKey = new PluginKey('prosemirror-math'); let mathPluginKey = new PluginKey('prosemirror-math');
const mathPluginSpec = { let mathPluginSpec = {
key: mathPluginKey, key: mathPluginKey,
state: { state: {
init(config, instance) { init(config, instance) {
...@@ -46,7 +47,7 @@ const mathPluginSpec = { ...@@ -46,7 +47,7 @@ const mathPluginSpec = {
* information about any new MathViews that were created by this transaction. * information about any new MathViews that were created by this transaction.
* As a result, the cursor position may be wrong for any newly created math blocks. * As a result, the cursor position may be wrong for any newly created math blocks.
*/ */
const pluginState = mathPluginKey.getState(oldState); let pluginState = mathPluginKey.getState(oldState);
if (pluginState) { if (pluginState) {
for (let mathView of pluginState.activeNodeViews) { for (let mathView of pluginState.activeNodeViews) {
mathView.updateCursorPos(newState); mathView.updateCursorPos(newState);
......
/* eslint-disable */
// prosemirror imports // prosemirror imports
import { Plugin as ProsePlugin } from 'prosemirror-state'; import { Plugin as ProsePlugin } from 'prosemirror-state';
import { DecorationSet, Decoration } from 'prosemirror-view'; import { DecorationSet, Decoration } from 'prosemirror-view';
////////////////////////////////////////////////////////////
/** /**
* Uses the selection to determine which math_select decorations * Uses the selection to determine which math_select decorations
* should be applied to the given document. * should be applied to the given document.
* @param arg Should be either a Transaction or an EditorState, * @param arg Should be either a Transaction or an EditorState,
* although any object with `selection` and `doc` will work. * although any object with `selection` and `doc` will work.
*/ */
let checkSelection = arg => {
const checkSelection = arg => { let { from, to } = arg.selection;
const { from, to } = arg; let content = arg.selection.content().content;
const { content } = arg.selection.content(); let result = [];
const result = [];
content.descendants((node, pos, parent) => { content.descendants((node, pos, parent) => {
if (node.type.name === 'text') { if (node.type.name == 'text') {
return false; return false;
} }
if (node.type.name.startsWith('math_')) { if (node.type.name.startsWith('math_')) {
...@@ -52,7 +53,7 @@ const mathSelectPlugin = new ProsePlugin({ ...@@ -52,7 +53,7 @@ const mathSelectPlugin = new ProsePlugin({
if (!tr.selection || !tr.selectionSet) { if (!tr.selection || !tr.selectionSet) {
return oldState; return oldState;
} }
const sel = checkSelection(tr); let sel = checkSelection(tr);
return sel; return sel;
}, },
}, },
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
"prosemirror-schema-list": "1.1.4", "prosemirror-schema-list": "1.1.4",
"prosemirror-state": "1.3.3", "prosemirror-state": "1.3.3",
"prosemirror-transform": "1.2.6", "prosemirror-transform": "1.2.6",
"prosemirror-inputrules": "1.1.2",
"prosemirror-view": "1.15.2", "prosemirror-view": "1.15.2",
"styled-components": "^4.2.0", "styled-components": "^4.2.0",
"uuid": "^7.0.3", "uuid": "^7.0.3",
......
/* eslint-disable */
import { InputRule } from 'prosemirror-inputrules';
import { NodeSelection } from 'prosemirror-state';
const blockInputRule = (pattern, nodeType, getAttrs) => {
return new InputRule(pattern, (state, match, start, end) => {
let $start = state.doc.resolve(start);
let attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
if (
!$start
.node(-1)
.canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)
)
return null;
let tr = state.tr
.delete(start, end)
.setBlockType(start, start, nodeType, attrs);
return tr.setSelection(
NodeSelection.create(tr.doc, tr.mapping.map($start.pos - 1)),
);
});
};
export default blockInputRule;
import { InputRule } from 'prosemirror-inputrules';
const inlineInputRule = (pattern, nodeType, getAttrs) => {
return new InputRule(pattern, (state, match, start, end) => {
const $start = state.doc.resolve(start);
const index = $start.index();
const $end = state.doc.resolve(end);
// get attrs
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
// check if replacement valid
if (!$start.parent.canReplaceWith(index, $end.index(), nodeType)) {
return null;
}
// perform replacement
return state.tr.replaceRangeWith(
start,
end,
nodeType.create(attrs, nodeType.schema.text(match[1])),
);
});
};
export default inlineInputRule;
...@@ -5,6 +5,8 @@ import { ...@@ -5,6 +5,8 @@ import {
} from 'wax-prosemirror-schema'; } from 'wax-prosemirror-schema';
import { mathPlugin, mathSelectPlugin } from 'wax-prosemirror-plugins'; import { mathPlugin, mathSelectPlugin } from 'wax-prosemirror-plugins';
import Service from '../Service'; import Service from '../Service';
import inlineInputRule from './InlineInputRule';
import blockInputRule from './BlockInputRule';
class MathService extends Service { class MathService extends Service {
name = 'MathService'; name = 'MathService';
...@@ -12,6 +14,16 @@ class MathService extends Service { ...@@ -12,6 +14,16 @@ class MathService extends Service {
boot() { boot() {
this.app.PmPlugins.add('mathplugin', mathPlugin); this.app.PmPlugins.add('mathplugin', mathPlugin);
this.app.PmPlugins.add('mathselectplugin', mathSelectPlugin); this.app.PmPlugins.add('mathselectplugin', mathSelectPlugin);
const schema = this.container.get('Schema');
const rules = this.container.get('Rules');
const newRules = [
inlineInputRule(
/(?<!\\)\$(.+)(?<!\\)\$/,
schema.schema.nodes.math_inline,
),
blockInputRule(/^\$\$\s+$/, schema.schema.nodes.math_display),
];
// rules.addRule(newRules);
} }
register() { register() {
......
...@@ -6,6 +6,10 @@ import { ...@@ -6,6 +6,10 @@ import {
smartQuotes, smartQuotes,
} from 'prosemirror-inputrules'; } from 'prosemirror-inputrules';
// TODO add through service.
import inlineInputRule from '../MathService/InlineInputRule';
import blockInputRule from '../MathService/BlockInputRule';
@injectable() @injectable()
class Rules { class Rules {
constructor(plugins, schema) { constructor(plugins, schema) {
...@@ -17,6 +21,7 @@ class Rules { ...@@ -17,6 +21,7 @@ class Rules {
addRule(rules) { addRule(rules) {
this.extendedRules.push(...rules); this.extendedRules.push(...rules);
// this.extendedRules = this.allRules().concat(...rules);
} }
createRules() { createRules() {
...@@ -50,6 +55,8 @@ class Rules { ...@@ -50,6 +55,8 @@ class Rules {
this.schema.nodes.heading, this.schema.nodes.heading,
match => ({ level: match[1].length }), match => ({ level: match[1].length }),
), ),
inlineInputRule(/(?<!\\)\$(.+)(?<!\\)\$/, this.schema.nodes.math_inline),
blockInputRule(/^\$\$\s+$/, this.schema.nodes.math_display),
]; ];
} }
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment