From c52e68f79ae44f962cca49f4f2fd83aceab1a7eb Mon Sep 17 00:00:00 2001
From: chris <kokosias@yahoo.gr>
Date: Wed, 14 Oct 2020 13:40:33 +0300
Subject: [PATCH] math input rules

---
 wax-prosemirror-components/index.js           |  1 -
 .../src/components/infoArea/InfoArea.js       | 15 ------------
 .../src/math/math-nodeview.js                 |  1 -
 .../src/math/math-plugin.js                   | 13 ++++++-----
 .../src/math/math-select.js                   | 17 +++++++-------
 wax-prosemirror-services/package.json         |  1 +
 .../src/MathService/BlockInputRule.js         | 23 +++++++++++++++++++
 .../src/MathService/InlineInputRule.js        | 23 +++++++++++++++++++
 .../src/MathService/MathService.js            | 12 ++++++++++
 .../src/RulesService/Rules.js                 |  7 ++++++
 10 files changed, 82 insertions(+), 31 deletions(-)
 delete mode 100644 wax-prosemirror-components/src/components/infoArea/InfoArea.js
 create mode 100644 wax-prosemirror-services/src/MathService/BlockInputRule.js
 create mode 100644 wax-prosemirror-services/src/MathService/InlineInputRule.js

diff --git a/wax-prosemirror-components/index.js b/wax-prosemirror-components/index.js
index 0742df29f..0da2eedf1 100644
--- a/wax-prosemirror-components/index.js
+++ b/wax-prosemirror-components/index.js
@@ -1,4 +1,3 @@
-export { default as InfoArea } from './src/components/infoArea/InfoArea';
 export { default as Overlay } from './src/components/Overlay';
 export { default as Button } from './src/components/Button';
 export { default as icons } from './src/icons/icons';
diff --git a/wax-prosemirror-components/src/components/infoArea/InfoArea.js b/wax-prosemirror-components/src/components/infoArea/InfoArea.js
deleted file mode 100644
index ae6e088a0..000000000
--- a/wax-prosemirror-components/src/components/infoArea/InfoArea.js
+++ /dev/null
@@ -1,15 +0,0 @@
-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;
diff --git a/wax-prosemirror-plugins/src/math/math-nodeview.js b/wax-prosemirror-plugins/src/math/math-nodeview.js
index 81bcd0d33..1f9241d3a 100644
--- a/wax-prosemirror-plugins/src/math/math-nodeview.js
+++ b/wax-prosemirror-plugins/src/math/math-nodeview.js
@@ -1,5 +1,4 @@
 /* eslint-disable */
-
 import { EditorState, TextSelection } from 'prosemirror-state';
 import { EditorView } from 'prosemirror-view';
 import { StepMap } from 'prosemirror-transform';
diff --git a/wax-prosemirror-plugins/src/math/math-plugin.js b/wax-prosemirror-plugins/src/math/math-plugin.js
index e9569035f..aebe23521 100644
--- a/wax-prosemirror-plugins/src/math/math-plugin.js
+++ b/wax-prosemirror-plugins/src/math/math-plugin.js
@@ -1,3 +1,4 @@
+/* eslint-disable */
 import { Plugin as ProsePlugin, PluginKey } from 'prosemirror-state';
 import { MathView } from './math-nodeview';
 /**
@@ -11,13 +12,13 @@ function createMathView(displayMode) {
      * Docs says that for any function proprs, the current plugin instance
      * 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) {
       throw new Error('no math plugin!');
     }
-    const nodeViews = pluginState.activeNodeViews;
+    let nodeViews = pluginState.activeNodeViews;
     // set up NodeView
-    const nodeView = new MathView(
+    let nodeView = new MathView(
       node,
       view,
       getPos,
@@ -30,8 +31,8 @@ function createMathView(displayMode) {
     return nodeView;
   };
 }
-const mathPluginKey = new PluginKey('prosemirror-math');
-const mathPluginSpec = {
+let mathPluginKey = new PluginKey('prosemirror-math');
+let mathPluginSpec = {
   key: mathPluginKey,
   state: {
     init(config, instance) {
@@ -46,7 +47,7 @@ const mathPluginSpec = {
        * 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.
        */
-      const pluginState = mathPluginKey.getState(oldState);
+      let pluginState = mathPluginKey.getState(oldState);
       if (pluginState) {
         for (let mathView of pluginState.activeNodeViews) {
           mathView.updateCursorPos(newState);
diff --git a/wax-prosemirror-plugins/src/math/math-select.js b/wax-prosemirror-plugins/src/math/math-select.js
index 9d9e87454..25989cb3d 100644
--- a/wax-prosemirror-plugins/src/math/math-select.js
+++ b/wax-prosemirror-plugins/src/math/math-select.js
@@ -1,20 +1,21 @@
+/* eslint-disable */
+
 // prosemirror imports
 import { Plugin as ProsePlugin } from 'prosemirror-state';
 import { DecorationSet, Decoration } from 'prosemirror-view';
-
+////////////////////////////////////////////////////////////
 /**
  * Uses the selection to determine which math_select decorations
  * should be applied to the given document.
  * @param arg Should be either a Transaction or an EditorState,
  *     although any object with `selection` and `doc` will work.
  */
-
-const checkSelection = arg => {
-  const { from, to } = arg;
-  const { content } = arg.selection.content();
-  const result = [];
+let checkSelection = arg => {
+  let { from, to } = arg.selection;
+  let content = arg.selection.content().content;
+  let result = [];
   content.descendants((node, pos, parent) => {
-    if (node.type.name === 'text') {
+    if (node.type.name == 'text') {
       return false;
     }
     if (node.type.name.startsWith('math_')) {
@@ -52,7 +53,7 @@ const mathSelectPlugin = new ProsePlugin({
       if (!tr.selection || !tr.selectionSet) {
         return oldState;
       }
-      const sel = checkSelection(tr);
+      let sel = checkSelection(tr);
       return sel;
     },
   },
diff --git a/wax-prosemirror-services/package.json b/wax-prosemirror-services/package.json
index 13876b3a1..60282baf2 100644
--- a/wax-prosemirror-services/package.json
+++ b/wax-prosemirror-services/package.json
@@ -23,6 +23,7 @@
     "prosemirror-schema-list": "1.1.4",
     "prosemirror-state": "1.3.3",
     "prosemirror-transform": "1.2.6",
+    "prosemirror-inputrules": "1.1.2",
     "prosemirror-view": "1.15.2",
     "styled-components": "^4.2.0",
     "uuid": "^7.0.3",
diff --git a/wax-prosemirror-services/src/MathService/BlockInputRule.js b/wax-prosemirror-services/src/MathService/BlockInputRule.js
new file mode 100644
index 000000000..1b13412fb
--- /dev/null
+++ b/wax-prosemirror-services/src/MathService/BlockInputRule.js
@@ -0,0 +1,23 @@
+/* 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;
diff --git a/wax-prosemirror-services/src/MathService/InlineInputRule.js b/wax-prosemirror-services/src/MathService/InlineInputRule.js
new file mode 100644
index 000000000..d0ce6c570
--- /dev/null
+++ b/wax-prosemirror-services/src/MathService/InlineInputRule.js
@@ -0,0 +1,23 @@
+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;
diff --git a/wax-prosemirror-services/src/MathService/MathService.js b/wax-prosemirror-services/src/MathService/MathService.js
index 1cc778bae..8584f7279 100644
--- a/wax-prosemirror-services/src/MathService/MathService.js
+++ b/wax-prosemirror-services/src/MathService/MathService.js
@@ -5,6 +5,8 @@ import {
 } from 'wax-prosemirror-schema';
 import { mathPlugin, mathSelectPlugin } from 'wax-prosemirror-plugins';
 import Service from '../Service';
+import inlineInputRule from './InlineInputRule';
+import blockInputRule from './BlockInputRule';
 
 class MathService extends Service {
   name = 'MathService';
@@ -12,6 +14,16 @@ class MathService extends Service {
   boot() {
     this.app.PmPlugins.add('mathplugin', mathPlugin);
     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() {
diff --git a/wax-prosemirror-services/src/RulesService/Rules.js b/wax-prosemirror-services/src/RulesService/Rules.js
index bb8767832..107bbd025 100644
--- a/wax-prosemirror-services/src/RulesService/Rules.js
+++ b/wax-prosemirror-services/src/RulesService/Rules.js
@@ -6,6 +6,10 @@ import {
   smartQuotes,
 } from 'prosemirror-inputrules';
 
+// TODO add through service.
+import inlineInputRule from '../MathService/InlineInputRule';
+import blockInputRule from '../MathService/BlockInputRule';
+
 @injectable()
 class Rules {
   constructor(plugins, schema) {
@@ -17,6 +21,7 @@ class Rules {
 
   addRule(rules) {
     this.extendedRules.push(...rules);
+    // this.extendedRules = this.allRules().concat(...rules);
   }
 
   createRules() {
@@ -50,6 +55,8 @@ class Rules {
         this.schema.nodes.heading,
         match => ({ level: match[1].length }),
       ),
+      inlineInputRule(/(?<!\\)\$(.+)(?<!\\)\$/, this.schema.nodes.math_inline),
+      blockInputRule(/^\$\$\s+$/, this.schema.nodes.math_display),
     ];
   }
 }
-- 
GitLab