@podlite/editor-react 0.0.15 → 0.0.17

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@podlite/editor-react",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Podlite React component",
5
5
  "main": "index.js",
6
6
  "types": "lib/index.d.ts",
package/src/dict.ts CHANGED
@@ -1,91 +1,98 @@
1
1
  // this file contains the dictionary ot the messages used in the podlite editor
2
+ interface Dict {
3
+ displayText: string;
4
+ text: string;
5
+ lang?: 'pod6' | 'md';
6
+ }
7
+ const dict: Dict[] = [
8
+ {
9
+ displayText: 'head1',
10
+ text: `=head1 `,
11
+ },
12
+ {
13
+ displayText: 'head2',
14
+ text: `=head2 `,
15
+ },
2
16
 
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
17
+ {
18
+ displayText: 'head3',
19
+ text: `=head3 `,
20
+ },
21
+ {
22
+ displayText: 'item1 *',
23
+ text: `=item1 `,
24
+ },
25
+ {
26
+ displayText: 'item1 1.)',
27
+ text: `=item1 # `,
28
+ },
29
+ {
30
+ displayText: 'item (1., 2.) 🏷',
31
+ text: `=item1 # item
28
32
  =item2 # item level 2
29
33
  =item2 # item level 2
30
34
  =item1 # item
31
35
  =item2 # item
32
36
  =item2 # item level 2
33
- `},
34
- {
35
- "displayText": "item (*, *) 🏷",
36
- "text": `=item1 item
37
+ `,
38
+ },
39
+ {
40
+ displayText: 'item (*, *) 🏷',
41
+ text: `=item1 item
37
42
  =item2 item level 2
38
43
  =item2 item level 2
39
44
  =item1 item
40
45
  =item2 item
41
46
  =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
47
+ `,
48
+ },
49
+ {
50
+ displayText: 'Image 🏷',
51
+ text: `=Image https://github.com/zag/podlite-desktop/blob/master/dist-assets/linux-icon/256x256.png?raw=true
52
+ `,
53
+ },
54
+ {
55
+ displayText: 'table simple 🏷',
56
+ text: `=for table
51
57
  mouse | mice
52
58
  horse | horses
53
59
  elephant | elephants
54
- `
55
- },
56
- {
57
- "displayText": "table 2x 🏷",
58
- "text": `=begin table :caption('Caption of table')
60
+ `,
61
+ },
62
+ {
63
+ displayText: 'table 2x 🏷',
64
+ text: `=begin table :caption('Caption of table')
59
65
  Constants 1
60
66
  Variables 10
61
67
  Subroutines 33
62
68
  Everything else 57
63
69
  =end table
64
- `},
65
- {
66
- "displayText": "table 3x 🏷",
67
- "text": `=for table :caption('Caption of table')
70
+ `,
71
+ },
72
+ {
73
+ displayText: 'table 3x 🏷',
74
+ text: `=for table :caption('Caption of table')
68
75
  Animal | Legs | Eats
69
76
  =======================
70
77
  Zebra + 4 + Cookies
71
78
  Human + 2 + Pizza
72
79
  Shark + 0 + Fish
73
- `
74
- },
75
- {
76
- "displayText": "Diagram simple 🏷",
77
- "text": `=begin Diagram :caption('Caption of diagram')
80
+ `,
81
+ },
82
+ {
83
+ displayText: 'Diagram simple 🏷',
84
+ text: `=begin Diagram :caption('Caption of diagram')
78
85
  graph LR
79
86
  A-->B
80
87
  B-->C
81
88
  C-->A
82
89
  D-->C
83
90
  =end Diagram
84
- `
85
- },
86
- {
87
- "displayText": "Diagram Sequence 🏷",
88
- "text": `=for Diagram :caption('Caption of diagram')
91
+ `,
92
+ },
93
+ {
94
+ displayText: 'Diagram Sequence 🏷',
95
+ text: `=for Diagram :caption('Caption of diagram')
89
96
  sequenceDiagram
90
97
  autonumber
91
98
  Student->>Admin: Can I enrol this semester?
@@ -97,22 +104,22 @@ Everything else 57
97
104
  Admin->>Professor: Assign student to tutor
98
105
  Professor-->>Admin: Student is assigned
99
106
 
100
- `
101
- },
102
- {
103
- "displayText": "Diagram flowchart 🏷",
104
- "text": `=for Diagram :caption('Caption of diagram')
107
+ `,
108
+ },
109
+ {
110
+ displayText: 'Diagram flowchart 🏷',
111
+ text: `=for Diagram :caption('Caption of diagram')
105
112
  graph LR
106
113
  A[Square Rect] -- Link text --> B((Circle))
107
114
  A --> C(Round Rect)
108
115
  B --> D{Rhombus}
109
116
  C --> D
110
117
 
111
- `
112
- },
113
- {
114
- "displayText": "Diagram class 🏷",
115
- "text": `=for Diagram :caption('Caption of diagram')
118
+ `,
119
+ },
120
+ {
121
+ displayText: 'Diagram class 🏷',
122
+ text: `=for Diagram :caption('Caption of diagram')
116
123
  classDiagram
117
124
  Person <|-- Student
118
125
  Person <|-- Professor
@@ -140,35 +147,102 @@ Everything else 57
140
147
  +outputAsLabel()
141
148
  }
142
149
 
143
- `
144
- },
145
- {
146
- "displayText": "code block with formatting 🏷",
147
- "text": `=begin code :allow<I B Z>
150
+ `,
151
+ },
152
+ {
153
+ displayText: 'code block with formatting 🏷',
154
+ text: `=begin code :allow<I B Z>
148
155
 
149
156
  =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 contents')
157
+ `,
158
+ },
159
+ {
160
+ displayText: 'Toc head1, head2, head3',
161
+ text: `=Toc head1, head2, head3
162
+ `,
163
+ },
164
+ {
165
+ displayText: 'Toc (with :title) 🏷',
166
+ text: `=for Toc :title('Table of contents')
159
167
  head1, head2, head3
160
168
 
161
- `
162
- },
163
- {
164
- "displayText": "Toc ( Images, Diagrams ) + tables 🏷",
165
- "text": `=for Toc :title('List of media')
169
+ `,
170
+ },
171
+ {
172
+ displayText: 'Toc ( Images, Diagrams ) + tables 🏷',
173
+ text: `=for Toc :title('List of media')
166
174
  Image, Diagram
167
175
  =for Toc :title('List of tables')
168
176
  table
169
177
 
170
- `
171
- },
178
+ `,
179
+ },
180
+
181
+ {
182
+ displayText: 'Markdown',
183
+ text: `=begin Markdown
184
+
185
+ {}
186
+
187
+ =end Markdown
188
+ `,
189
+ },
190
+ // Markdown
191
+
192
+ {
193
+ displayText: 'head1',
194
+ text: `# `,
195
+ lang: 'md',
196
+ },
197
+ {
198
+ displayText: 'head2',
199
+ text: `## `,
200
+ lang: 'md',
201
+ },
202
+
203
+ {
204
+ displayText: 'head3',
205
+ text: `### `,
206
+ lang: 'md',
207
+ },
208
+ {
209
+ displayText: 'item1 *',
210
+ text: `* `,
211
+ lang: 'md',
212
+ },
213
+ {
214
+ displayText: 'item1 1.)',
215
+ text: `1. `,
216
+ lang: 'md',
217
+ },
218
+ {
219
+ displayText: 'Image 🏷',
220
+ text: `![Podlite](https://github.com/zag/podlite-desktop/blob/master/dist-assets/linux-icon/256x256.png?raw=true "Podlite logo")
221
+
222
+ `,
223
+ lang: 'md',
224
+ },
225
+
226
+ {
227
+ displayText: 'Table',
228
+ text: `| Syntax | Description |
229
+ | ----------- | ----------- |
230
+ | Header | Title |
231
+ | Paragraph | Text |
172
232
 
173
- ]
233
+ `,
234
+ lang: 'md',
235
+ },
236
+ {
237
+ displayText: 'Diagram simple 🏷',
238
+ text: `\`\`\`diagram
239
+ graph LR
240
+ A-->B
241
+ B-->C
242
+ C-->A
243
+ D-->C
244
+ \`\`\``,
245
+ lang: 'md',
246
+ },
247
+ ];
174
248
  export default dict;
package/src/helpers.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { getFromTree, PodliteDocument } from '@podlite/schema';
2
+ import { frozenIds, podlite as podlite_core } from 'podlite';
3
+ export const parse = (str: string): PodliteDocument => {
4
+ let podlite = podlite_core({ importPlugins: false });
5
+ let tree = podlite.parse(str);
6
+ const asAst = podlite.toAstResult(tree);
7
+ return asAst.interator;
8
+ };
9
+ export const getSuggestionContextForLine = (
10
+ pod: string,
11
+ line: number,
12
+ ): 'pod6' | 'md' => {
13
+ const tree = parse(pod);
14
+ const markdownBlocks = getFromTree(tree, 'Markdown');
15
+ const isMd =
16
+ markdownBlocks.findIndex(
17
+ ({
18
+ location: {
19
+ start: { line: lineStart },
20
+ end: { line: lineEnd },
21
+ },
22
+ }) => {
23
+ return line > lineStart && line < lineEnd;
24
+ },
25
+ ) !== -1;
26
+ if (isMd) return 'md';
27
+ return 'pod6';
28
+ };
29
+
30
+ interface Pos {
31
+ line: number;
32
+ offset: number;
33
+ }
34
+ interface Selection {
35
+ start: Pos;
36
+ end: Pos;
37
+ text?: string; // return result pod, after remove {}
38
+ }
39
+ export const templateGetSelectionPos = (pod: string): Selection | null => {
40
+ // if empty selection
41
+ const EMPTY_SELECTION = new RegExp(/\{\}/);
42
+ const lineNumEmptySel = pod
43
+ .split('\n')
44
+ .findIndex((str) => str.match(EMPTY_SELECTION));
45
+ if (lineNumEmptySel > -1) {
46
+ const line = pod.split('\n')[lineNumEmptySel];
47
+ const matchResult = line.match(EMPTY_SELECTION)!;
48
+ const start = { line: lineNumEmptySel, offset: matchResult.index! };
49
+ const end = { line: lineNumEmptySel, offset: matchResult.index! };
50
+ return { start, end, text: pod.replace(EMPTY_SELECTION, '') };
51
+ }
52
+ const SELECTION = new RegExp(/\{[^}]+\}/);
53
+ const lineNum = pod.split('\n').findIndex((str) => str.match(SELECTION));
54
+ if (lineNum > -1) {
55
+ const line = pod.split('\n')[lineNum];
56
+ const matchResult = line.match(SELECTION)!;
57
+ const start = { line: lineNum, offset: matchResult.index! };
58
+ const end = {
59
+ line: lineNum,
60
+ offset: matchResult.index! + matchResult[0].length,
61
+ };
62
+ return { start, end, text: pod };
63
+ }
64
+ return null;
65
+ };
66
+
67
+ export const addVMargin = (count: number, pod: string) => {
68
+ const addString = ' '.repeat(count);
69
+ const [firstLine, ...restLines] = pod.split('\n');
70
+ return [
71
+ firstLine,
72
+ ...[].concat(restLines).map((str) => `${addString}${str}`),
73
+ ].join('\n');
74
+ };
package/src/index.tsx CHANGED
@@ -11,6 +11,7 @@ import 'codemirror/mode/gfm/gfm';
11
11
  import "codemirror/addon/hint/show-hint";
12
12
  import 'codemirror/addon/hint/show-hint.css';
13
13
  import './Editor.css';
14
+ import { addVMargin, getSuggestionContextForLine, templateGetSelectionPos } from './helpers'
14
15
 
15
16
 
16
17
  //@ts-ignore
@@ -253,7 +254,7 @@ useEffect(()=>{
253
254
  }
254
255
  }
255
256
  instanceCMLocal.on('change', onChange);
256
-
257
+
257
258
  CMirror.registerHelper('hint', 'dictionaryHint', function(editor) {
258
259
  var cur = editor.getCursor();
259
260
  var curLine = editor.getLine(cur.line);
@@ -275,8 +276,29 @@ useEffect(()=>{
275
276
  }, []);
276
277
  return dict.sort((a, b) => a.index - b.index).map(i=>i.item)
277
278
  }
279
+ const langMode = sourceType === 'md' ? 'md' : getSuggestionContextForLine(editor.getValue() ,cur.line+1)
280
+ const langDict = dictionary.filter( ({lang='pod6'})=>lang === langMode)
281
+ // apply hint
282
+ const resultDict = (!curWord ? langDict : filterDictByRegex(langDict,regex )).map((item)=>{
283
+ return {...item, hint: function(cm,data, completion){
284
+ const from = completion.from || data.from
285
+ const to = completion.to || data.to
286
+ // add vMargin
287
+ const text = addVMargin(from.ch, typeof completion == "string" ? completion : completion.text)
288
+ const selFromTemplate = templateGetSelectionPos(text)
289
+ console.log({from ,to , text})
290
+ if (selFromTemplate) {
291
+ const {text,start, end} = selFromTemplate
292
+ cm.replaceRange(text, from, to, "complete");
293
+ cm.setSelection({line: start.line + from.line, ch: start.offset + from.ch}, {line: end.line + to.line, ch: end.offset + to.ch -1});
294
+ } else {
295
+ cm.replaceRange(text, from, to, "complete");
296
+ }
297
+
298
+ }}
299
+ })
278
300
  return {
279
- list: (!curWord ? dictionary : filterDictByRegex(dictionary,regex )),
301
+ list: resultDict,
280
302
  from: CMirror.Pos(cur.line, start-1),
281
303
  to: CMirror.Pos(cur.line, end)
282
304
  }
@@ -0,0 +1,86 @@
1
+ import { frozenIds, podlite as podlite_core } from 'podlite';
2
+ import { PodliteDocument } from '@podlite/schema';
3
+ import {
4
+ addVMargin,
5
+ getSuggestionContextForLine,
6
+ templateGetSelectionPos,
7
+ } from '../src/helpers';
8
+
9
+ export const parse = (str: string): PodliteDocument => {
10
+ let podlite = podlite_core({ importPlugins: false });
11
+ let tree = podlite.parse(str);
12
+ const asAst = podlite.toAstResult(tree);
13
+ return frozenIds()(asAst.interator);
14
+ };
15
+
16
+ const pod = `
17
+ =para test
18
+ =Markdown
19
+ header1
20
+ =para text
21
+ =begin Markdown
22
+ new text
23
+ =end Markdown
24
+
25
+ `;
26
+ it('Check suggestion context: pod6', () => {
27
+ expect(getSuggestionContextForLine(pod, 1)).toEqual('pod6');
28
+ });
29
+ it('Check suggestion context: md', () => {
30
+ expect(getSuggestionContextForLine(pod, 4)).toEqual('md');
31
+ });
32
+ it('Check suggestion context: md second block', () => {
33
+ expect(getSuggestionContextForLine(pod, 7)).toEqual('md');
34
+ });
35
+
36
+ it('Selection position', () => {
37
+ const pod = `=begin pod
38
+ {test}
39
+ =end pod
40
+ `;
41
+ const { text, ...pos } = templateGetSelectionPos(pod) || {};
42
+ expect(pos).toEqual({
43
+ start: { line: 1, offset: 0 },
44
+ end: { line: 1, offset: 6 },
45
+ });
46
+ });
47
+
48
+ it('Selection empty position 1', () => {
49
+ const pod = `=begin pod
50
+ {test
51
+ =end pod
52
+ `;
53
+ const pos = templateGetSelectionPos(pod);
54
+ expect(pos).toBeNull;
55
+ });
56
+
57
+ it('Selection empty position 2', () => {
58
+ const pod = `=begin pod
59
+ {}test
60
+ =end pod
61
+ `;
62
+ const { start, end } = templateGetSelectionPos(pod) || {};
63
+ expect({ start, end }).toEqual({
64
+ start: { line: 1, offset: 0 },
65
+ end: { line: 1, offset: 0 },
66
+ });
67
+ });
68
+
69
+ it('Test addVMargin 4', () => {
70
+ const pod = `=begin pod
71
+ test
72
+ =end pod`;
73
+ const pod2 = `=begin pod
74
+ test
75
+ =end pod`;
76
+ const vpod = addVMargin(4, pod);
77
+ expect(vpod).toEqual(pod2);
78
+ });
79
+
80
+ it('Test addVMargin 0', () => {
81
+ const pod = `=begin pod
82
+ test
83
+ =end pod`;
84
+ const vpod = addVMargin(0, pod);
85
+ expect(vpod).toEqual(pod);
86
+ });