1# prosemirror Plugin for DokuWiki
2[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/cosmocode/dokuwiki-plugin-prosemirror/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/cosmocode/dokuwiki-plugin-prosemirror/?branch=master)
3
4A WYSIWYG editor for DokuWiki
5
6All documentation for this plugin can be found at
7https://www.dokuwiki.org/plugin:prosemirror
8
9If you install this plugin manually, make sure it is installed in
10``lib/plugins/prosemirror/`` - if the folder is called different it
11will not work!
12
13Please refer to http://www.dokuwiki.org/plugins for additional info
14on how to install plugins in DokuWiki.
15
16## Development Setup
17
18Use yarn to install the dependecies
19
20    yarn
21
22Create a develoment bundle:
23
24    yarn dev
25
26Automatically recreate the bundle during development:
27
28    yarn watch
29
30Build a release
31
32    yarn build
33
34We really recommend yarn, but npm should work, too.
35
36## Architecture
37
38### Dataflow
39
40#### Begin Edit-Session: DokuWiki -> Prosemirror
41- `action/editor.php`: `HTML_EDITFORM_OUTPUT` get Instructions and render them to json
42  - see `renderer.php`
43  - `renderer.php` uses the classes `NodeStack` `Node` and `Mark` in `schema` to do its job
44    - this should possibly renamed
45  - to keep information about a Node in as few places as possible,
46  some rendering instructions have been moved to the respective `parser/` classes
47- Prosemirror parses that json in `script/main.js` according to the schema defined in
48`script/schema.js` and creates its `doc`-Node from it.
49
50#### Rendering: Prosemirror -> DokuWiki -> Prosemirror
51- Some Nodes (e.g. images, links) need to be resolved by DokuWiki in order to be rendered properly.
52- So ProseMirror makes ajax requests
53  - triggered by `LinkForm.resolveSubmittedLinkData` in `script/LinkForm.js`
54- the request is handled by `action/ajax.php` which resolves the link/images and returns
55the resolved html to be rendered into Prosemirror
56
57
58#### Saving/Preview: Prosemirror -> DokuWiki
59- Prosemirror synchronizes all changes with the underlying json in the `<input>` field
60- When the Editform is submitted that data has to be parsed by DokuWiki into DokuWiki-Syntax.
61- This starts in `action/parser.php` during the event `ACTION_ACT_PREPROCESS`
62  - The main challenge is that Prosemirror operates on a flat array, whereas DokuWiki-Syntax is usually a tree
63  - This means that the Syntax `**bold __underlined and bold__**` is represented in Prosemirror's data as
64  `[{text: "bold ", marks: [bold]}, {text: "underlined and bold", marks: [bold, underlined]}]`
65  - The creation of that syntax tree is started in `parser/SyntaxTreeBuilder.php`
66  - Handling marks is complex and subtle:
67    - To know in which order we have to open/close marks we need to know which start
68    earlier or end later
69    - for this purpose, `InlineNodeInterface::getStartingNodeMarkScore($markType)`
70    and `Mark::tailLength` play together
71    - for `getStartingNodeMarkScore()` to work, it needs the inline nodes inside a block node to be
72    chained together, so we can ask the previous node whether it has a given node or not
73    - If the marks on a node have the same start/end than they need a stable order in which they appear.
74    That is defined in `Mark::markOrder`
75
76### Our Prosemirror JS setup
77Currently all our prosemirror scripts are in `script/`.
78This definietly needs some better organisation.
79I can see the following possible groups:
80- NodeViews and Forms
81  - if a Node cannot be simply rendered and edited by ProseMirror, it needs a NodeView
82  - Examples are links, images, footnotes(NodeView not yet implemented)
83  - possibly also `<code>` and `<file>`?
84- Menu-Related classes and menu items
85- keyboard commands
86- possibly `commands` in general wich then can be used by menu-items and keyboard-events?
87- the schema
88
89These files are compiled with webpack and transpiled with Babel into `lib/bundle.js`,
90which is the file actually included by DokuWiki.
91
92## Testing
93The central test-data is the collection of DokuWiki-Syntax and corresponding Prosemirror JSON
94in `_test/json/`. This data is used for three sets of tests:
951. Testing the rendering of DokuWiki-Syntax to Prosemirror JSON in `_test/renderer.test.php`
961. Testing the parsing of Prosemirror JSON back to the original DokuWiki-Syntax in `_test/jsonParser.test.php`
971. Testing the validity of the Prosemirror JSON against the schema (`script/schema.js`) in `_jstest/test.js`
98
99The rendering and parsing tests are run as usual DokuWiki tests.
100The javascript tests are run with `yarn test`
101
102The scripts in `script/` are also checked when building with eslint.
103Eslint can also be run on its own with `yarn eslint`.
104
105## Copyright
106Copyright (C) CosmoCode GmbH <dokuwiki@cosmocode.de>
107    Andreas Gohr
108    Michael Grosse
109    Anna Dabrowska
110
111This program is free software; you can redistribute it and/or modify
112it under the terms of the GNU General Public License as published by
113the Free Software Foundation; version 2 of the License
114
115This program is distributed in the hope that it will be useful,
116but WITHOUT ANY WARRANTY; without even the implied warranty of
117MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
118GNU General Public License for more details.
119
120See the COPYING file in your DokuWiki folder for details
121