@podlite/editor-react 0.0.9 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../node_modules/react-is/cjs/react-is.production.min.js", "../../../node_modules/react-is/index.js", "../src/index.tsx", "../src/dict.ts"],
4
+ "sourcesContent": ["/** @license React v17.0.2\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var b=60103,c=60106,d=60107,e=60108,f=60114,g=60109,h=60110,k=60112,l=60113,m=60120,n=60115,p=60116,q=60121,r=60122,u=60117,v=60129,w=60131;\nif(\"function\"===typeof Symbol&&Symbol.for){var x=Symbol.for;b=x(\"react.element\");c=x(\"react.portal\");d=x(\"react.fragment\");e=x(\"react.strict_mode\");f=x(\"react.profiler\");g=x(\"react.provider\");h=x(\"react.context\");k=x(\"react.forward_ref\");l=x(\"react.suspense\");m=x(\"react.suspense_list\");n=x(\"react.memo\");p=x(\"react.lazy\");q=x(\"react.block\");r=x(\"react.server.block\");u=x(\"react.fundamental\");v=x(\"react.debug_trace_mode\");w=x(\"react.legacy_hidden\")}\nfunction y(a){if(\"object\"===typeof a&&null!==a){var t=a.$$typeof;switch(t){case b:switch(a=a.type,a){case d:case f:case e:case l:case m:return a;default:switch(a=a&&a.$$typeof,a){case h:case k:case p:case n:case g:return a;default:return t}}case c:return t}}}var z=g,A=b,B=k,C=d,D=p,E=n,F=c,G=f,H=e,I=l;exports.ContextConsumer=h;exports.ContextProvider=z;exports.Element=A;exports.ForwardRef=B;exports.Fragment=C;exports.Lazy=D;exports.Memo=E;exports.Portal=F;exports.Profiler=G;exports.StrictMode=H;\nexports.Suspense=I;exports.isAsyncMode=function(){return!1};exports.isConcurrentMode=function(){return!1};exports.isContextConsumer=function(a){return y(a)===h};exports.isContextProvider=function(a){return y(a)===g};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===b};exports.isForwardRef=function(a){return y(a)===k};exports.isFragment=function(a){return y(a)===d};exports.isLazy=function(a){return y(a)===p};exports.isMemo=function(a){return y(a)===n};\nexports.isPortal=function(a){return y(a)===c};exports.isProfiler=function(a){return y(a)===f};exports.isStrictMode=function(a){return y(a)===e};exports.isSuspense=function(a){return y(a)===l};exports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===d||a===f||a===v||a===e||a===l||a===m||a===w||\"object\"===typeof a&&null!==a&&(a.$$typeof===p||a.$$typeof===n||a.$$typeof===g||a.$$typeof===h||a.$$typeof===k||a.$$typeof===u||a.$$typeof===q||a[0]===r)?!0:!1};\nexports.typeOf=y;\n", "'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n", "import * as React from 'react'\nimport { Controlled as CodeMirrorControlled, UnControlled as CodeMirror} from 'react-codemirror2'\nimport CMirror from 'codemirror'\nimport dictionary from './dict'\nimport { useState, useEffect, useRef, useMemo } from 'react'\nimport {isValidElementType, isElement} from 'react-is'\n\n// TODO: use bundler to add into package\n// import '../../../node_modules/codemirror/lib/codemirror.css';\nimport 'codemirror/mode/gfm/gfm';\nimport \"codemirror/addon/hint/show-hint\";\nimport 'codemirror/addon/hint/show-hint.css';\nimport './Editor.css';\n\n\n//@ts-ignore\nfunction useDebouncedEffect(fn, deps, time) {\n const dependencies = [...deps, time] \n useEffect(() => {\n const timeout = setTimeout(fn, time);\n return () => {\n clearTimeout(timeout);\n }\n }, dependencies);\n}\n\n/* set window title */ \n// @ts-ignore\n// const setWindowTitle = (title: string) => { vmd.setWindowTitle(title) }\nexport interface ConverterResult {\n errors?:any,\n result:any\n}\n\nlet instanceCM = null\ntype Props={\n content: string,\n onChangeSource:Function,\n sourceType?: 'pod6' | 'md',\n onConvertSource: (source:string)=>ConverterResult,\n onSavePressed?: Function,\n isDarkTheme? : boolean,\n isLineNumbers?: boolean,\n isAutoComplete?: boolean,\n isPreviewModeEnabled? :boolean\n isControlled?:boolean\n}\n\nexport default ({ \n onChangeSource = ()=>{}, \n content, \n isDarkTheme = false, \n isLineNumbers = false, \n isPreviewModeEnabled = false, \n onConvertSource, \n onSavePressed = () => { },\n sourceType = 'pod6',\n isControlled=false,\n isAutoComplete = true,\n }: Props) => {\n const [text, updateText] = useState(content)\n\n const [marks, updateMarks] = useState([])\n const [, updateScrollMap] = useState([])\n \n const [isPreviewMode, setPreviewMode] = useState(isPreviewModeEnabled)\n\n const [isPreviewScroll, setPreviewScrolling] = useState(false);\n const refValue = useRef(isPreviewScroll);\n const [showTree, setShowTree] = useState(false)\n\n const [filePath, setFilePath] = useState('')\n const [fileName, setFileName] = useState('')\n const [fileExt, setFileExt] = useState('')\n const [isChanged, setChanged] = useState(false)\n\n const [fileLoading, setFileLoading] = useState(true)\n\nuseEffect(()=>{\nupdateText(content)\n},[content])\n\n const [result, updateResult] = useState<ConverterResult>() \n useDebouncedEffect(() => {\n updateResult(onConvertSource(text))\n }, [text], 50)\n \n const inputEl = useRef(null)\n\n// hot keys\n useEffect( () => {\n const saveFileAction = () => {\n if (isChanged) {\n console.warn(\"Save File\")\n onSavePressed(text)\n\n }\n }\n})\n\n\nuseEffect(() => {\n refValue.current = isPreviewScroll;\n});\nvar options: CMirror.EditorConfiguration = {\n lineNumbers: isLineNumbers,\n inputStyle: \"contenteditable\",\n //@ts-ignore\n spellcheck: true,\n autofocus:true,\n lineWrapping:true,\n viewportMargin:Infinity,\n mode: sourceType !== 'md' ? null : \n {\n name: \"gfm\",\n tokenTypeOverrides: {\n emoji: \"emoji\"\n }\n },\n theme: isDarkTheme ? \"duotone-dark\" : \"default\"\n};\n\n\nconst previewEl = useRef(null)\n\nuseEffect(() => {\n //@ts-ignore\n const newScrollMap = [...document.querySelectorAll('.line-src')]\n .map(n => {\n const line = parseInt(n.getAttribute('data-line'),10 )\n //@ts-ignore\n const offsetTop = n.offsetTop\n return { line, offsetTop}\n })\n //@ts-ignore \n updateScrollMap(newScrollMap)\n //@ts-ignore\n const listener = (e) => { \n if (!isPreviewScroll ) {return}\n let element = e.target\n //@ts-ignore\n const getLine = (offset) => {\n const c = newScrollMap.filter( i => i.offsetTop > offset )\n const lineElement = c.shift() || newScrollMap[ newScrollMap.length - 1 ]\n if (!lineElement) {\n console.warn(`[podlite-editor] can't get line for offset. Forget add .line-src ?`)\n }\n return lineElement.line\n }\n const line = getLine(element.scrollTop)\n if (instanceCM) {\n const t = element.scrollTop === 0 ? 0 : instanceCM.charCoords({line: line, ch: 0}, \"local\").top;\n instanceCM.scrollTo(null, t);\n }\n return true\n }\n if (previewEl && previewEl.current) {\n //@ts-ignore\n previewEl.current.addEventListener(\"scroll\", listener);\n }\n return () => {\n // @ts-ignore\n previewEl && previewEl.current && previewEl && previewEl.current.removeEventListener(\"scroll\", listener);\n };\n},[text,isPreviewScroll])\n\nuseEffect(() => {\n //@ts-ignore\n let cm = instanceCM\n if (!cm) {return}\n //@ts-ignore\n marks.forEach(marker => marker.clear())\n //@ts-ignore\n let cmMrks:Array<never> = []\n //@ts-ignore\n if (result && result.errors ) {\n\n //@ts-ignore\n result.errors.map((loc:any)=>{\n // @ts-ignore\n let from = {line: loc.start.line-1, ch: loc.start.column-1 - (loc.start.offset === loc.end.offset)};\n let to = {line: loc.end.line-1, ch: loc.end.column-1};\n\n cmMrks.push(\n //@ts-ignore\n cm.markText(\n from,\n to, \n {\n className: 'syntax-error',\n title: ';data.error.message',\n css: \"color : red\"\n }\n )\n \n )\n })\n }\n updateMarks(cmMrks)\n\n},[text,result])\n\nconst previewHtml = <div className={ \"Editorright \" + (isDarkTheme ? 'dark' : '' )}\n onMouseEnter={()=>setPreviewScrolling(true)} \n onMouseMove={()=>setPreviewScrolling(true)} \n ref={previewEl} \n >\n {\n result ? \n isElement(result.result) ? <div className=\"content\">{result.result}</div> : <div \n dangerouslySetInnerHTML={{__html: result.result}} \n className=\"content\" \n ></div>\n : ''\n \n }\n </div>\n//@ts-ignore\nconst scrollEditorHandler = (editor) => {\n if (refValue.current) { return }\n let scrollInfo = editor.getScrollInfo();\n // get line number of the top line in the page\n let lineNumber = editor.lineAtHeight(scrollInfo.top, 'local') + 1;\n if (previewEl) {\n const el = previewEl.current\n const elementId = `#line-${lineNumber}`\n const scrollToElement = document.querySelector(elementId)\n if (scrollToElement) {\n //@ts-ignore\n const scrollTo = scrollToElement.offsetTop\n //@ts-ignore\n el.scrollTo({\n top: scrollTo,\n left: 0,\n behavior: 'smooth'\n })\n }\n }\n}\nconst [instanceCMLocal, updateInstanceCM] = useState<any>()\n\nuseEffect(()=>{\n if (!instanceCMLocal) return\n if (!isAutoComplete) return\n var onChange = function(instance, object)\n {\n // Check if the last inserted character is `=`.\n if (object.text[0] === '=' &&\n // start directive\n instance.getRange({ch:0,line: object.to.line}, object.to).match(/^\\s*$/))\n {\n CMirror.showHint(instanceCMLocal, CMirror.hint.dictionaryHint);\n }\n }\n instanceCMLocal.on('change', onChange);\n\n CMirror.registerHelper('hint', 'dictionaryHint', function(editor) {\n var cur = editor.getCursor();\n var curLine = editor.getLine(cur.line);\n var start = cur.ch;\n var end = start;\n while (end < curLine.length && /[\\w$]/.test(curLine.charAt(end))) ++end;\n while (start && /[^=]/.test(curLine.charAt(start - 1))) --start;\n var curWord = start !== end && curLine.slice(start, end);\n var regex = new RegExp('' + curWord, 'i');\n // filter dict by regex and sort by mostly nearness\n const filterDictByRegex = (arr, regex)=>{\n const dict = arr.reduce((acc, item)=>{\n if (item === null) { return acc; }\n const result = (typeof item === 'object' && !Array.isArray(item)) ? item.displayText.match(regex): item.match(regex);\n if ( result ) {\n acc.push({item, index:result.index})\n }\n return acc;\n }, []);\n return dict.sort((a, b) => a.index - b.index).map(i=>i.item)\n }\n return {\n list: (!curWord ? dictionary : filterDictByRegex(dictionary,regex )),\n from: CMirror.Pos(cur.line, start-1),\n to: CMirror.Pos(cur.line, end)\n }\n });\n instanceCMLocal.refresh()\n return () => {\n //@ts-ignore\n instanceCMLocal.off('change', onChange)\n }\n},[instanceCMLocal, isAutoComplete])\n\nreturn (\n <div className=\"EditorApp\">\n <div className={ isPreviewModeEnabled ? \"layoutPreview\": \"layout\"}>\n <div className=\"Editorleft\" onMouseEnter={()=>setPreviewScrolling(false)}\n onMouseMove={()=>setPreviewScrolling(false)}\n >\n {isControlled ? \n <CodeMirrorControlled\n value={content}\n editorDidMount={ editor => { instanceCM = editor; updateInstanceCM(editor) } }\n onBeforeChange={(editor, data, value) => {\n setChanged(true); \n // updateText(value);\n onChangeSource(value)\n }}\n onScroll={scrollEditorHandler}\n options={options} \n className=\"editorApp\"\n />\n :\n <CodeMirror \n value={content}\n editorDidMount={ editor => { instanceCM = editor; updateInstanceCM(editor) } }\n onChange = { (editor, data, value) => { \n setChanged(true); \n updateText(value);\n onChangeSource(value)\n } }\n onScroll={scrollEditorHandler}\n options={options} \n className=\"editorApp\"\n />\n }\n </div>\n {previewHtml}\n </div>\n </div>\n);\n}\n", "// this file contains the dictionary ot the messages used in the podlite editor\n\nconst dict = [\n {\n \"displayText\": \"head1\",\n \"text\": `=head1 `\n },\n {\n \"displayText\": \"head2\",\n \"text\": `=head2 `\n },\n \n {\n \"displayText\": \"head3\",\n \"text\": `=head3 `\n },\n {\n \"displayText\": \"item1 *\",\n \"text\": `=item1 `\n }, \n {\n \"displayText\": \"item1 1.)\",\n \"text\": `=item1 # `\n},\n{\n \"displayText\": \"item (1., 2.) \uD83C\uDFF7\",\n \"text\": `=item1 # item \n =item2 # item level 2\n =item2 # item level 2\n=item1 # item\n =item2 # item\n =item2 # item level 2\n`},\n{\n \"displayText\": \"item (*, *) \uD83C\uDFF7\",\n \"text\": `=item1 item \n =item2 item level 2\n =item2 item level 2\n=item1 item\n =item2 item\n =item3 item level 2\n`},\n{\n \"displayText\": \"Image \uD83C\uDFF7\",\n \"text\": `=Image https://github.com/zag/podlite-desktop/blob/master/dist-assets/linux-icon/256x256.png?raw=true\n`,\n},\n{\n \"displayText\": \"table simple \uD83C\uDFF7\",\n \"text\":`=for table\n mouse | mice\n horse | horses\n elephant | elephants\n`\n},\n{\n \"displayText\": \"table 2x \uD83C\uDFF7\",\n \"text\": `=begin table :caption('Caption of table')\nConstants 1\nVariables 10\nSubroutines 33\nEverything else 57\n=end table\n`},\n{\n \"displayText\": \"table 3x \uD83C\uDFF7\",\n \"text\": `=for table :caption('Caption of table')\n Animal | Legs | Eats\n =======================\n Zebra + 4 + Cookies\n Human + 2 + Pizza\n Shark + 0 + Fish\n`\n},\n{\n \"displayText\": \"Diagram simple \uD83C\uDFF7\",\n \"text\": `=begin Diagram :caption('Caption of diagram')\n graph LR\n A-->B\n B-->C\n C-->A\n D-->C\n=end Diagram\n`\n},\n{\n \"displayText\": \"Diagram Sequence \uD83C\uDFF7\",\n \"text\": `=for Diagram :caption('Caption of diagram')\n sequenceDiagram\n autonumber\n Student->>Admin: Can I enrol this semester?\n loop enrolmentCheck\n Admin->>Admin: Check previous results\n end\n Note right of Admin: Exam results may <br> be delayed\n Admin-->>Student: Enrolment success\n Admin->>Professor: Assign student to tutor\n Professor-->>Admin: Student is assigned\n\n`\n},\n{\n \"displayText\": \"Diagram flowchart \uD83C\uDFF7\",\n \"text\": `=for Diagram :caption('Caption of diagram')\n graph LR\n A[Square Rect] -- Link text --> B((Circle))\n A --> C(Round Rect)\n B --> D{Rhombus}\n C --> D\n\n`\n},\n{\n \"displayText\": \"Diagram class \uD83C\uDFF7\",\n \"text\": `=for Diagram :caption('Caption of diagram')\n classDiagram\n Person <|-- Student\n Person <|-- Professor\n Person : +String name\n Person : +String phoneNumber\n Person : +String emailAddress\n Person: +purchaseParkingPass()\n Address \"1\" <-- \"0..1\" Person:lives at\n class Student{\n +int studentNumber\n +int averageMark\n +isEligibleToEnrol()\n +getSeminarsTaken()\n }\n class Professor{\n +int salary\n }\n class Address{\n +String street\n +String city\n +String state\n +int postalCode\n +String country\n -validate()\n +outputAsLabel() \n }\n\n`\n},\n{\n \"displayText\": \"code block with formatting \uD83C\uDFF7\",\n \"text\": `=begin code :allow<I B Z> \n\n=end code\n`\n},\n{\n \"displayText\": \"Toc head1, head2, head3\",\n \"text\": `=Toc head1, head2, head3\n`},\n{\n \"displayText\": \"Toc (with :title) \uD83C\uDFF7\",\n \"text\": `=for Toc :title('Table of content')\nhead1, head2, head3 \n\n`\n},\n{\n \"displayText\": \"Toc ( Images, Diagrams ) + tables \uD83C\uDFF7\",\n \"text\": `=for Toc :title('List of media')\nImage, Diagram\n=for Toc :title('List of tables')\ntable\n\n`\n},\n\n]\nexport default dict;\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@podlite/editor-react",
3
- "version": "0.0.9",
3
+ "version": "0.0.13",
4
4
  "description": "Podlite React component",
5
5
  "main": "index.js",
6
6
  "types": "lib/index.d.ts",
@@ -17,29 +17,29 @@
17
17
  },
18
18
  "scripts": {
19
19
  "clean": "rm -rf dist lib tsconfig.tsbuildinfo",
20
- "build": "yarn build:cjs && yarn build:esm",
21
- "build:cjs": "esbuild --bundle src/index.tsx --outfile=lib/index.js --external:'react*' --format=cjs && tsc --declaration --emitDeclarationOnly",
22
- "build:esm": "esbuild --bundle src/index.tsx --outfile=esm/index.js --external:'react*' --format=esm && tsc --declaration --emitDeclarationOnly --outDir esm",
23
- "test": "jest --verbose --passWithNoTests"
20
+ "build": "run-p build:cjs build:esm",
21
+ "build:cjs": "ts-node ./scripts/build.ts && tsc --declaration --emitDeclarationOnly",
22
+ "build:esm": "ts-node ./scripts/build_esm.ts && tsc --declaration --emitDeclarationOnly --outDir esm",
23
+ "test": "yarn g:jest --passWithNoTests"
24
24
  },
25
25
  "dependencies": {
26
- "codemirror": "^5.60.0",
27
- "mousetrap": "^1.6.5",
28
- "mousetrap-global-bind": "^1.1.0",
29
- "react-codemirror2": "^7.2.1"
26
+ "codemirror": "5.x",
27
+ "react-codemirror2": "^7.2.1",
28
+ "react-is": "^17.0.2"
30
29
  },
31
30
  "devDependencies": {
32
- "@types/react": "^17.0.3",
31
+ "@types/node": "^17.0.7",
32
+ "@types/react": "^16.x",
33
+ "@yarnpkg/esbuild-plugin-pnp": "^2.0.0",
33
34
  "esbuild": "^0.11.12",
34
- "jest-serializer-html": "^7.0.0",
35
35
  "prettier": "^2.2.1",
36
36
  "react": "^16.12.0",
37
- "react-dom": "^17.0.2",
38
- "ts-jest": "^26.5.4",
39
- "typescript": "4.2.3"
37
+ "react-dom": "^16.12.0",
38
+ "ts-node": "^9.1.1",
39
+ "typescript": "4.5.4"
40
40
  },
41
41
  "peerDependencies": {
42
- "react": "^16.12.0"
43
- },
44
- "gitHead": "a4a607de65e342ea89d674628d2b450fa6b53de8"
45
- }
42
+ "react": "*",
43
+ "react-dom": "*"
44
+ }
45
+ }
@@ -0,0 +1,17 @@
1
+ import { build } from 'esbuild';
2
+ import { pnpPlugin } from '@yarnpkg/esbuild-plugin-pnp';
3
+
4
+ build({
5
+ plugins: [pnpPlugin()],
6
+ bundle: true,
7
+ entryPoints: ['src/index.tsx'],
8
+ external: ['react', 'react-dom', 'codemirror', 'react-codemirror2'],
9
+ minify: true,
10
+ format: 'cjs',
11
+ target: 'node12.0',
12
+ sourcemap: true,
13
+ outfile: 'lib/index.js',
14
+ }).catch((e) => {
15
+ console.log('Build not successful', e.message);
16
+ process.exit(1);
17
+ });
@@ -0,0 +1,17 @@
1
+ import { build } from 'esbuild';
2
+ import { pnpPlugin } from '@yarnpkg/esbuild-plugin-pnp';
3
+
4
+ build({
5
+ plugins: [pnpPlugin()],
6
+ bundle: true,
7
+ entryPoints: ['src/index.tsx'],
8
+ external: ['react', 'react-dom', 'codemirror', 'react-codemirror2'],
9
+ minify: true,
10
+ format: 'esm',
11
+ target: 'node12.0',
12
+ sourcemap: true,
13
+ outfile: 'esm/index.js',
14
+ }).catch((e) => {
15
+ console.log('Build not successful', e.message);
16
+ process.exit(1);
17
+ });
package/src/Editor.css CHANGED
@@ -133,7 +133,7 @@
133
133
  word-break: normal;
134
134
  min-width: 70%;
135
135
  max-width: 100%;
136
- margin: 0 auto;
136
+ margin: 1em auto;
137
137
  border-spacing: 0;
138
138
  border-collapse: collapse;
139
139
  text-align: center;
@@ -210,7 +210,20 @@
210
210
  display: block;
211
211
  margin: auto;
212
212
  }
213
+
214
+ .toc {
215
+ padding: 1rem;
216
+ }
213
217
 
218
+ .toc-list {
219
+ list-style: none;
220
+ font-size: .8rem;
221
+ }
222
+
223
+ .caption {
224
+ text-align: center;
225
+ font-size: 0.9rem;
226
+ }
214
227
  /* End of pod6 */
215
228
 
216
229
 
@@ -335,4 +348,9 @@
335
348
  }
336
349
  ::-webkit-scrollbar-corner {
337
350
  background: transparent;
351
+ }
352
+
353
+ .CodeMirror-hints {
354
+ z-index: 1000;
355
+ border: none;
338
356
  }
package/src/dict.ts ADDED
@@ -0,0 +1,174 @@
1
+ // this file contains the dictionary ot the messages used in the podlite editor
2
+
3
+ const dict = [
4
+ {
5
+ "displayText": "head1",
6
+ "text": `=head1 `
7
+ },
8
+ {
9
+ "displayText": "head2",
10
+ "text": `=head2 `
11
+ },
12
+
13
+ {
14
+ "displayText": "head3",
15
+ "text": `=head3 `
16
+ },
17
+ {
18
+ "displayText": "item1 *",
19
+ "text": `=item1 `
20
+ },
21
+ {
22
+ "displayText": "item1 1.)",
23
+ "text": `=item1 # `
24
+ },
25
+ {
26
+ "displayText": "item (1., 2.) 🏷",
27
+ "text": `=item1 # item
28
+ =item2 # item level 2
29
+ =item2 # item level 2
30
+ =item1 # item
31
+ =item2 # item
32
+ =item2 # item level 2
33
+ `},
34
+ {
35
+ "displayText": "item (*, *) 🏷",
36
+ "text": `=item1 item
37
+ =item2 item level 2
38
+ =item2 item level 2
39
+ =item1 item
40
+ =item2 item
41
+ =item3 item level 2
42
+ `},
43
+ {
44
+ "displayText": "Image 🏷",
45
+ "text": `=Image https://github.com/zag/podlite-desktop/blob/master/dist-assets/linux-icon/256x256.png?raw=true
46
+ `,
47
+ },
48
+ {
49
+ "displayText": "table simple 🏷",
50
+ "text":`=for table
51
+ mouse | mice
52
+ horse | horses
53
+ elephant | elephants
54
+ `
55
+ },
56
+ {
57
+ "displayText": "table 2x 🏷",
58
+ "text": `=begin table :caption('Caption of table')
59
+ Constants 1
60
+ Variables 10
61
+ Subroutines 33
62
+ Everything else 57
63
+ =end table
64
+ `},
65
+ {
66
+ "displayText": "table 3x 🏷",
67
+ "text": `=for table :caption('Caption of table')
68
+ Animal | Legs | Eats
69
+ =======================
70
+ Zebra + 4 + Cookies
71
+ Human + 2 + Pizza
72
+ Shark + 0 + Fish
73
+ `
74
+ },
75
+ {
76
+ "displayText": "Diagram simple 🏷",
77
+ "text": `=begin Diagram :caption('Caption of diagram')
78
+ graph LR
79
+ A-->B
80
+ B-->C
81
+ C-->A
82
+ D-->C
83
+ =end Diagram
84
+ `
85
+ },
86
+ {
87
+ "displayText": "Diagram Sequence 🏷",
88
+ "text": `=for Diagram :caption('Caption of diagram')
89
+ sequenceDiagram
90
+ autonumber
91
+ Student->>Admin: Can I enrol this semester?
92
+ loop enrolmentCheck
93
+ Admin->>Admin: Check previous results
94
+ end
95
+ Note right of Admin: Exam results may <br> be delayed
96
+ Admin-->>Student: Enrolment success
97
+ Admin->>Professor: Assign student to tutor
98
+ Professor-->>Admin: Student is assigned
99
+
100
+ `
101
+ },
102
+ {
103
+ "displayText": "Diagram flowchart 🏷",
104
+ "text": `=for Diagram :caption('Caption of diagram')
105
+ graph LR
106
+ A[Square Rect] -- Link text --> B((Circle))
107
+ A --> C(Round Rect)
108
+ B --> D{Rhombus}
109
+ C --> D
110
+
111
+ `
112
+ },
113
+ {
114
+ "displayText": "Diagram class 🏷",
115
+ "text": `=for Diagram :caption('Caption of diagram')
116
+ classDiagram
117
+ Person <|-- Student
118
+ Person <|-- Professor
119
+ Person : +String name
120
+ Person : +String phoneNumber
121
+ Person : +String emailAddress
122
+ Person: +purchaseParkingPass()
123
+ Address "1" <-- "0..1" Person:lives at
124
+ class Student{
125
+ +int studentNumber
126
+ +int averageMark
127
+ +isEligibleToEnrol()
128
+ +getSeminarsTaken()
129
+ }
130
+ class Professor{
131
+ +int salary
132
+ }
133
+ class Address{
134
+ +String street
135
+ +String city
136
+ +String state
137
+ +int postalCode
138
+ +String country
139
+ -validate()
140
+ +outputAsLabel()
141
+ }
142
+
143
+ `
144
+ },
145
+ {
146
+ "displayText": "code block with formatting 🏷",
147
+ "text": `=begin code :allow<I B Z>
148
+
149
+ =end code
150
+ `
151
+ },
152
+ {
153
+ "displayText": "Toc head1, head2, head3",
154
+ "text": `=Toc head1, head2, head3
155
+ `},
156
+ {
157
+ "displayText": "Toc (with :title) 🏷",
158
+ "text": `=for Toc :title('Table of content')
159
+ head1, head2, head3
160
+
161
+ `
162
+ },
163
+ {
164
+ "displayText": "Toc ( Images, Diagrams ) + tables 🏷",
165
+ "text": `=for Toc :title('List of media')
166
+ Image, Diagram
167
+ =for Toc :title('List of tables')
168
+ table
169
+
170
+ `
171
+ },
172
+
173
+ ]
174
+ export default dict;
package/src/index.tsx CHANGED
@@ -1,21 +1,16 @@
1
1
  import * as React from 'react'
2
- import {UnControlled as CodeMirror} from 'react-codemirror2'
3
- import {Controlled as CodeMirrorControlled} from 'react-codemirror2'
4
- import {EditorConfiguration} from 'codemirror'
2
+ import { Controlled as CodeMirrorControlled, UnControlled as CodeMirror} from 'react-codemirror2'
3
+ import CMirror from 'codemirror'
4
+ import dictionary from './dict'
5
5
  import { useState, useEffect, useRef, useMemo } from 'react'
6
-
7
- //@ts-ignore
8
6
  import {isValidElementType, isElement} from 'react-is'
9
7
 
10
- // import Mousetrap from 'mousetrap'
11
- // ; // global-bind must be import after Mousetrap
12
- // import 'mousetrap-global-bind';
13
8
  // TODO: use bundler to add into package
14
9
  // import '../../../node_modules/codemirror/lib/codemirror.css';
15
- import './Editor.css';
16
10
  import 'codemirror/mode/gfm/gfm';
17
-
18
- import path from 'path'
11
+ import "codemirror/addon/hint/show-hint";
12
+ import 'codemirror/addon/hint/show-hint.css';
13
+ import './Editor.css';
19
14
 
20
15
 
21
16
  //@ts-ignore
@@ -46,11 +41,23 @@ type Props={
46
41
  onSavePressed?: Function,
47
42
  isDarkTheme? : boolean,
48
43
  isLineNumbers?: boolean,
44
+ isAutoComplete?: boolean,
49
45
  isPreviewModeEnabled? :boolean
50
46
  isControlled?:boolean
51
47
  }
52
48
 
53
- export default ({ onChangeSource = ()=>{}, content, isDarkTheme = false, isLineNumbers = false, isPreviewModeEnabled = false, onConvertSource, onSavePressed = () => { }, sourceType = 'pod6', isControlled=false}: Props) => {
49
+ export default ({
50
+ onChangeSource = ()=>{},
51
+ content,
52
+ isDarkTheme = false,
53
+ isLineNumbers = false,
54
+ isPreviewModeEnabled = false,
55
+ onConvertSource,
56
+ onSavePressed = () => { },
57
+ sourceType = 'pod6',
58
+ isControlled=false,
59
+ isAutoComplete = true,
60
+ }: Props) => {
54
61
  const [text, updateText] = useState(content)
55
62
 
56
63
  const [marks, updateMarks] = useState([])
@@ -89,19 +96,13 @@ updateText(content)
89
96
 
90
97
  }
91
98
  }
92
- // TODO: remove save keys binds
93
- // Mousetrap.bindGlobal(['ctrl+s', 'command+s'], saveFileAction)
94
- return () => {
95
- // Mousetrap.unbind(['ctrl+s', 'command+s'])
96
- }
97
-
98
99
  })
99
100
 
100
101
 
101
102
  useEffect(() => {
102
103
  refValue.current = isPreviewScroll;
103
104
  });
104
- var options: EditorConfiguration = {
105
+ var options: CMirror.EditorConfiguration = {
105
106
  lineNumbers: isLineNumbers,
106
107
  inputStyle: "contenteditable",
107
108
  //@ts-ignore
@@ -164,43 +165,41 @@ useEffect(() => {
164
165
  },[text,isPreviewScroll])
165
166
 
166
167
  useEffect(() => {
167
- //@ts-ignore
168
- let cm = instanceCM
169
- if (!cm) {return}
170
- //@ts-ignore
171
- marks.forEach(marker => marker.clear())
172
- //@ts-ignore
173
- let cmMrks:Array<never> = []
174
- //@ts-ignore
175
- if (result && result.errors ) {
168
+ //@ts-ignore
169
+ let cm = instanceCM
170
+ if (!cm) {return}
171
+ //@ts-ignore
172
+ marks.forEach(marker => marker.clear())
173
+ //@ts-ignore
174
+ let cmMrks:Array<never> = []
175
+ //@ts-ignore
176
+ if (result && result.errors ) {
176
177
 
177
- //@ts-ignore
178
- result.errors.map((loc:any)=>{
179
- // @ts-ignore
180
- let from = {line: loc.start.line-1, ch: loc.start.column-1 - (loc.start.offset === loc.end.offset)};
181
- let to = {line: loc.end.line-1, ch: loc.end.column-1};
178
+ //@ts-ignore
179
+ result.errors.map((loc:any)=>{
180
+ // @ts-ignore
181
+ let from = {line: loc.start.line-1, ch: loc.start.column-1 - (loc.start.offset === loc.end.offset)};
182
+ let to = {line: loc.end.line-1, ch: loc.end.column-1};
182
183
 
183
- cmMrks.push(
184
- //@ts-ignore
185
- cm.markText(
186
- from,
187
- to,
188
- {
189
- className: 'syntax-error',
190
- title: ';data.error.message',
191
- css: "color : red"
192
- }
193
- )
194
-
195
- )
196
- })
197
- }
198
- updateMarks(cmMrks)
184
+ cmMrks.push(
185
+ //@ts-ignore
186
+ cm.markText(
187
+ from,
188
+ to,
189
+ {
190
+ className: 'syntax-error',
191
+ title: ';data.error.message',
192
+ css: "color : red"
193
+ }
194
+ )
195
+
196
+ )
197
+ })
198
+ }
199
+ updateMarks(cmMrks)
199
200
 
200
201
  },[text,result])
201
202
 
202
-
203
-
204
203
  const previewHtml = <div className={ "Editorright " + (isDarkTheme ? 'dark' : '' )}
205
204
  onMouseEnter={()=>setPreviewScrolling(true)}
206
205
  onMouseMove={()=>setPreviewScrolling(true)}
@@ -218,27 +217,77 @@ const previewHtml = <div className={ "Editorright " + (isDarkTheme ? 'dark' : ''
218
217
  </div>
219
218
  //@ts-ignore
220
219
  const scrollEditorHandler = (editor) => {
221
- if (refValue.current) { return }
222
- let scrollInfo = editor.getScrollInfo();
223
- // get line number of the top line in the page
224
- let lineNumber = editor.lineAtHeight(scrollInfo.top, 'local') + 1;
225
- if (previewEl) {
226
- const el = previewEl.current
227
- const elementId = `#line-${lineNumber}`
228
- const scrollToElement = document.querySelector(elementId)
229
- if (scrollToElement) {
230
- //@ts-ignore
231
- const scrollTo = scrollToElement.offsetTop
232
- //@ts-ignore
233
- el.scrollTo({
234
- top: scrollTo,
235
- left: 0,
236
- behavior: 'smooth'
237
- })
238
- }
239
-
240
- }
220
+ if (refValue.current) { return }
221
+ let scrollInfo = editor.getScrollInfo();
222
+ // get line number of the top line in the page
223
+ let lineNumber = editor.lineAtHeight(scrollInfo.top, 'local') + 1;
224
+ if (previewEl) {
225
+ const el = previewEl.current
226
+ const elementId = `#line-${lineNumber}`
227
+ const scrollToElement = document.querySelector(elementId)
228
+ if (scrollToElement) {
229
+ //@ts-ignore
230
+ const scrollTo = scrollToElement.offsetTop
231
+ //@ts-ignore
232
+ el.scrollTo({
233
+ top: scrollTo,
234
+ left: 0,
235
+ behavior: 'smooth'
236
+ })
237
+ }
238
+ }
241
239
  }
240
+ const [instanceCMLocal, updateInstanceCM] = useState<any>()
241
+
242
+ useEffect(()=>{
243
+ if (!instanceCMLocal) return
244
+ if (!isAutoComplete) return
245
+ var onChange = function(instance, object)
246
+ {
247
+ // Check if the last inserted character is `=`.
248
+ if (object.text[0] === '=' &&
249
+ // start directive
250
+ instance.getRange({ch:0,line: object.to.line}, object.to).match(/^\s*$/))
251
+ {
252
+ CMirror.showHint(instanceCMLocal, CMirror.hint.dictionaryHint);
253
+ }
254
+ }
255
+ instanceCMLocal.on('change', onChange);
256
+
257
+ CMirror.registerHelper('hint', 'dictionaryHint', function(editor) {
258
+ var cur = editor.getCursor();
259
+ var curLine = editor.getLine(cur.line);
260
+ var start = cur.ch;
261
+ var end = start;
262
+ while (end < curLine.length && /[\w$]/.test(curLine.charAt(end))) ++end;
263
+ while (start && /[^=]/.test(curLine.charAt(start - 1))) --start;
264
+ var curWord = start !== end && curLine.slice(start, end);
265
+ var regex = new RegExp('' + curWord, 'i');
266
+ // filter dict by regex and sort by mostly nearness
267
+ const filterDictByRegex = (arr, regex)=>{
268
+ const dict = arr.reduce((acc, item)=>{
269
+ if (item === null) { return acc; }
270
+ const result = (typeof item === 'object' && !Array.isArray(item)) ? item.displayText.match(regex): item.match(regex);
271
+ if ( result ) {
272
+ acc.push({item, index:result.index})
273
+ }
274
+ return acc;
275
+ }, []);
276
+ return dict.sort((a, b) => a.index - b.index).map(i=>i.item)
277
+ }
278
+ return {
279
+ list: (!curWord ? dictionary : filterDictByRegex(dictionary,regex )),
280
+ from: CMirror.Pos(cur.line, start-1),
281
+ to: CMirror.Pos(cur.line, end)
282
+ }
283
+ });
284
+ instanceCMLocal.refresh()
285
+ return () => {
286
+ //@ts-ignore
287
+ instanceCMLocal.off('change', onChange)
288
+ }
289
+ },[instanceCMLocal, isAutoComplete])
290
+
242
291
  return (
243
292
  <div className="EditorApp">
244
293
  <div className={ isPreviewModeEnabled ? "layoutPreview": "layout"}>
@@ -246,34 +295,31 @@ return (
246
295
  onMouseMove={()=>setPreviewScrolling(false)}
247
296
  >
248
297
  {isControlled ?
249
- <CodeMirrorControlled
250
- value={content}
251
- editorDidMount={ editor => { instanceCM = editor } }
252
- onBeforeChange={(editor, data, value) => {
253
- setChanged(true);
254
- // updateText(value);
255
- onChangeSource(value)
256
- }}
257
- // onChange={(editor, data, value) => {
258
-
259
- // }}
260
- onScroll={scrollEditorHandler}
261
- options={options}
262
- className="editorApp"
263
- />
264
- :
265
- <CodeMirror
298
+ <CodeMirrorControlled
266
299
  value={content}
267
- editorDidMount={ editor => { instanceCM = editor } }
268
- onChange = { (editor, data, value) => {
300
+ editorDidMount={ editor => { instanceCM = editor; updateInstanceCM(editor) } }
301
+ onBeforeChange={(editor, data, value) => {
269
302
  setChanged(true);
270
- updateText(value);
303
+ // updateText(value);
271
304
  onChangeSource(value)
272
- } }
305
+ }}
273
306
  onScroll={scrollEditorHandler}
274
307
  options={options}
275
308
  className="editorApp"
276
- />
309
+ />
310
+ :
311
+ <CodeMirror
312
+ value={content}
313
+ editorDidMount={ editor => { instanceCM = editor; updateInstanceCM(editor) } }
314
+ onChange = { (editor, data, value) => {
315
+ setChanged(true);
316
+ updateText(value);
317
+ onChangeSource(value)
318
+ } }
319
+ onScroll={scrollEditorHandler}
320
+ options={options}
321
+ className="editorApp"
322
+ />
277
323
  }
278
324
  </div>
279
325
  {previewHtml}