Premier commit déjà bien avancé
This commit is contained in:
16
frontend/node_modules/@codemirror/lang-markdown/.github/workflows/dispatch.yml
generated
vendored
Normal file
16
frontend/node_modules/@codemirror/lang-markdown/.github/workflows/dispatch.yml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: Trigger CI
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Dispatch to main repo
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Emit repository_dispatch
|
||||
uses: mvasigh/dispatch-action@main
|
||||
with:
|
||||
# You should create a personal access token and store it in your repository
|
||||
token: ${{ secrets.DISPATCH_AUTH }}
|
||||
repo: dev
|
||||
owner: codemirror
|
||||
event_type: push
|
||||
246
frontend/node_modules/@codemirror/lang-markdown/CHANGELOG.md
generated
vendored
Normal file
246
frontend/node_modules/@codemirror/lang-markdown/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
## 6.5.0 (2025-10-23)
|
||||
|
||||
### New features
|
||||
|
||||
Add a variant of `insertNewlineContinueMarkup` that supports configuration options.
|
||||
|
||||
## 6.4.0 (2025-10-02)
|
||||
|
||||
### New features
|
||||
|
||||
The new `pasteURLAsLink` extension allows you to paste URLs over a selection to quickly create a link.
|
||||
|
||||
## 6.3.4 (2025-08-01)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make sure header-based indentation is available even when Markdown isn't the editor's top-level language.
|
||||
|
||||
## 6.3.3 (2025-06-13)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make `insertNewlineContinueMarkup` take effect even when at the end of a nested range of Markdown content.
|
||||
|
||||
## 6.3.2 (2025-01-09)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make Markdown-specific commands return false inside fenced code.
|
||||
|
||||
Fix an infinite loop caused by `insertNewlineContinueMarkup`.
|
||||
|
||||
## 6.3.1 (2024-11-06)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix an issue where `insertNewlineContinueMarkup` didn't work with the cursor directly after an HTML tag.
|
||||
|
||||
## 6.3.0 (2024-09-28)
|
||||
|
||||
### New features
|
||||
|
||||
The new `htmlTagLanguage` option allows client code to configure which language is used to parse HTML tags in the document.
|
||||
|
||||
## 6.2.5 (2024-04-12)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Disable folding for list nodes (since it will shadow the folding on the first list item).
|
||||
|
||||
## 6.2.4 (2024-01-16)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Starting at the third list item, `insertNewlineContinueMarkup` will now keep the tightness of the list, and only require two presses to clear an empty list item.
|
||||
|
||||
## 6.2.3 (2023-11-27)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Support code folding for GFM tables.
|
||||
|
||||
## 6.2.2 (2023-10-06)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug in `insertNewlineContinueMarkup` that caused it to put the cursor in the wrong place when the editor's line break was more than one character long.
|
||||
|
||||
## 6.2.1 (2023-09-14)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make `insertNewlineContinueMarkup` and `deleteMarkupBackward` use tabs for indentation when appropriate.
|
||||
|
||||
## 6.2.0 (2023-06-23)
|
||||
|
||||
### New features
|
||||
|
||||
The markdown package now installs a completion source that completes HTML tags when in Markdown context.
|
||||
|
||||
## 6.1.1 (2023-04-13)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix the declaration of `comentTokens` language data for Markdown.
|
||||
|
||||
Fix a bug in `deleteMarkupBackward` that would cause it to delete pieces of continued paragraphs below list item markers.
|
||||
|
||||
## 6.1.0 (2023-02-17)
|
||||
|
||||
### New features
|
||||
|
||||
Add support for folding entire sections from the header.
|
||||
|
||||
## 6.0.5 (2022-11-10)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make sure task lists are indented correctly even when deeply nested.
|
||||
|
||||
## 6.0.4 (2022-11-02)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix an issue where nested task lists were indented too deeply.
|
||||
|
||||
## 6.0.3 (2022-10-24)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Add a `name` value to the Markdown language object.
|
||||
|
||||
## 6.0.2 (2022-10-10)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Improve `insertNewlineContinueMarkup`'s behavior in a fenced code block.
|
||||
|
||||
## 6.0.1 (2022-07-25)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Ignore text after whitespace in code block metadata, when determining which language the block is.
|
||||
|
||||
## 6.0.0 (2022-06-08)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
Update dependencies to 6.0.0
|
||||
|
||||
## 0.20.1 (2022-05-20)
|
||||
|
||||
### New features
|
||||
|
||||
The `codeLanguages` option to `markdown` may now be a function from an info string to a language.
|
||||
|
||||
## 0.20.0 (2022-04-20)
|
||||
|
||||
### New features
|
||||
|
||||
`insertNewlineContinueMarkup` can now continue task lists. Move highlighting information into @lezer/markdown
|
||||
|
||||
## 0.19.6 (2022-02-04)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix an issue where `deleteMarkupBackward` could get confused when there was only whitespace between the cursor and the start of the line.
|
||||
|
||||
## 0.19.5 (2022-01-28)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make `insertNewlineContinueMarkup` exit blockquotes after two blank lines.
|
||||
|
||||
## 0.19.4 (2022-01-03)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug where list items after a removed item were incorrectly renumbered.
|
||||
|
||||
## 0.19.3 (2021-12-10)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
`insertNewlineContinueMarkup` will no longer exit lists when there is content after the cursor.
|
||||
|
||||
Fix an issue in `deleteMarkupBackward` where it only deleted a single space when after a number marker.
|
||||
|
||||
## 0.19.2 (2021-10-20)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug where the monospace highlighting tag wasn't correctly applied to code block content.
|
||||
|
||||
## 0.19.1 (2021-08-11)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix incorrect versions for @lezer dependencies.
|
||||
|
||||
## 0.19.0 (2021-08-11)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
Update dependencies to 0.19.0
|
||||
|
||||
## 0.18.4 (2021-06-16)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a case where `deleteMarkupBackward` would return true without actually having an effect.
|
||||
|
||||
## 0.18.3 (2021-05-19)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
`insertNewlineContinueMarkup` will not continue moving list markers down when they are after an empty line anymore.
|
||||
|
||||
## 0.18.2 (2021-05-07)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug where `insertNewlineContinueMarkup` could duplicate bits of content when in dededented continued list items.
|
||||
|
||||
## 0.18.1 (2021-04-01)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Add `monospace` style tag to all children of inline code nodes.
|
||||
|
||||
## 0.18.0 (2021-03-03)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
Update dependencies to 0.18.
|
||||
|
||||
## 0.17.3 (2021-02-22)
|
||||
|
||||
### New features
|
||||
|
||||
Include heading depth in style tags.
|
||||
|
||||
## 0.17.2 (2021-02-10)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug where `insertNewlineContinueMarkup` would sometimes duplicate bits of content.
|
||||
|
||||
### New features
|
||||
|
||||
The package now exports both a `commonmarkLanguage`, with just plain CommonMark, and a `markdownLanguage`, with GFM and some other extensions enabled.
|
||||
|
||||
It is now possible to pass lezer-markdown extensions to the `markdown` function to configure the parser.
|
||||
|
||||
## 0.17.1 (2021-01-06)
|
||||
|
||||
### New features
|
||||
|
||||
The package now also exports a CommonJS module.
|
||||
|
||||
## 0.17.0 (2020-12-29)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
First numbered release.
|
||||
|
||||
21
frontend/node_modules/@codemirror/lang-markdown/LICENSE
generated
vendored
Normal file
21
frontend/node_modules/@codemirror/lang-markdown/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2018-2021 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
162
frontend/node_modules/@codemirror/lang-markdown/README.md
generated
vendored
Normal file
162
frontend/node_modules/@codemirror/lang-markdown/README.md
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
<!-- NOTE: README.md is generated from src/README.md -->
|
||||
|
||||
# @codemirror/lang-markdown [](https://www.npmjs.org/package/@codemirror/lang-markdown)
|
||||
|
||||
[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-markdown/blob/main/CHANGELOG.md) ]
|
||||
|
||||
This package implements Markdown language support for the
|
||||
[CodeMirror](https://codemirror.net/) code editor.
|
||||
|
||||
The [project page](https://codemirror.net/) has more information, a
|
||||
number of [examples](https://codemirror.net/examples/) and the
|
||||
[documentation](https://codemirror.net/docs/).
|
||||
|
||||
This code is released under an
|
||||
[MIT license](https://github.com/codemirror/lang-markdown/tree/main/LICENSE).
|
||||
|
||||
We aim to be an inclusive, welcoming community. To make that explicit,
|
||||
we have a [code of
|
||||
conduct](http://contributor-covenant.org/version/1/1/0/) that applies
|
||||
to communication around the project.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
import {EditorView, basicSetup} from "codemirror"
|
||||
import {markdown} from "@codemirror/lang-markdown"
|
||||
|
||||
const view = new EditorView({
|
||||
parent: document.body,
|
||||
doc: `*CodeMirror* Markdown \`mode\``,
|
||||
extensions: [basicSetup, markdown()]
|
||||
})
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
<dl>
|
||||
<dt id="user-content-markdown">
|
||||
<code><strong><a href="#user-content-markdown">markdown</a></strong>(<a id="user-content-markdown^config" href="#user-content-markdown^config">config</a>⁠?: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a> = {}) → <a href="https://codemirror.net/docs/ref#language.LanguageSupport">LanguageSupport</a></code></dt>
|
||||
|
||||
<dd><p>Markdown language support.</p>
|
||||
<dl><dt id="user-content-markdown^config">
|
||||
<code><strong><a href="#user-content-markdown^config">config</a></strong></code></dt>
|
||||
|
||||
<dd><dl><dt id="user-content-markdown^config.defaultcodelanguage">
|
||||
<code><strong><a href="#user-content-markdown^config.defaultcodelanguage">defaultCodeLanguage</a></strong>⁠?: <a href="https://codemirror.net/docs/ref#language.Language">Language</a> | <a href="https://codemirror.net/docs/ref#language.LanguageSupport">LanguageSupport</a></code></dt>
|
||||
|
||||
<dd><p>When given, this language will be used by default to parse code
|
||||
blocks.</p>
|
||||
</dd><dt id="user-content-markdown^config.codelanguages">
|
||||
<code><strong><a href="#user-content-markdown^config.codelanguages">codeLanguages</a></strong>⁠?: readonly <a href="https://codemirror.net/docs/ref#language.LanguageDescription">LanguageDescription</a>[] | fn(<a id="user-content-markdown^config.codelanguages^info" href="#user-content-markdown^config.codelanguages^info">info</a>: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">string</a>) → <a href="https://codemirror.net/docs/ref#language.Language">Language</a> | <a href="https://codemirror.net/docs/ref#language.LanguageDescription">LanguageDescription</a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a></code></dt>
|
||||
|
||||
<dd><p>A source of language support for highlighting fenced code
|
||||
blocks. When it is an array, the parser will use
|
||||
<a href="https://codemirror.net/docs/ref/#language.LanguageDescription%5EmatchLanguageName"><code>LanguageDescription.matchLanguageName</code></a>
|
||||
with the fenced code info to find a matching language. When it
|
||||
is a function, will be called with the info string and may
|
||||
return a language or <code>LanguageDescription</code> object.</p>
|
||||
</dd><dt id="user-content-markdown^config.addkeymap">
|
||||
<code><strong><a href="#user-content-markdown^config.addkeymap">addKeymap</a></strong>⁠?: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">boolean</a></code></dt>
|
||||
|
||||
<dd><p>Set this to false to disable installation of the Markdown
|
||||
<a href="#user-content-markdownkeymap">keymap</a>.</p>
|
||||
</dd><dt id="user-content-markdown^config.extensions">
|
||||
<code><strong><a href="#user-content-markdown^config.extensions">extensions</a></strong>⁠?: <a href="https://github.com/lezer-parser/markdown#user-content-markdownextension">MarkdownExtension</a></code></dt>
|
||||
|
||||
<dd><p>Markdown parser
|
||||
<a href="https://github.com/lezer-parser/markdown#user-content-markdownextension">extensions</a>
|
||||
to add to the parser.</p>
|
||||
</dd><dt id="user-content-markdown^config.base">
|
||||
<code><strong><a href="#user-content-markdown^config.base">base</a></strong>⁠?: <a href="https://codemirror.net/docs/ref#language.Language">Language</a></code></dt>
|
||||
|
||||
<dd><p>The base language to use. Defaults to
|
||||
<a href="#user-content-commonmarklanguage"><code>commonmarkLanguage</code></a>.</p>
|
||||
</dd><dt id="user-content-markdown^config.completehtmltags">
|
||||
<code><strong><a href="#user-content-markdown^config.completehtmltags">completeHTMLTags</a></strong>⁠?: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">boolean</a></code></dt>
|
||||
|
||||
<dd><p>By default, the extension installs an autocompletion source that
|
||||
completes HTML tags when a <code><</code> is typed. Set this to false to
|
||||
disable this.</p>
|
||||
</dd><dt id="user-content-markdown^config.pasteurlaslink">
|
||||
<code><strong><a href="#user-content-markdown^config.pasteurlaslink">pasteURLAsLink</a></strong>⁠?: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">boolean</a></code></dt>
|
||||
|
||||
<dd><p>The returned language contains
|
||||
<a href="#user-content-pasteurlaslink"><code>pasteURLAsLink</code></a> as a support
|
||||
extension unless you set this to false.</p>
|
||||
</dd><dt id="user-content-markdown^config.htmltaglanguage">
|
||||
<code><strong><a href="#user-content-markdown^config.htmltaglanguage">htmlTagLanguage</a></strong>⁠?: <a href="https://codemirror.net/docs/ref#language.LanguageSupport">LanguageSupport</a></code></dt>
|
||||
|
||||
<dd><p>By default, HTML tags in the document are handled by the <a href="https://github.com/codemirror/lang-html">HTML
|
||||
language</a> package with
|
||||
tag matching turned off. You can pass in an alternative language
|
||||
configuration here if you want.</p>
|
||||
</dd></dl></dd></dl></dd>
|
||||
<dt id="user-content-markdownlanguage">
|
||||
<code><strong><a href="#user-content-markdownlanguage">markdownLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.Language">Language</a></code></dt>
|
||||
|
||||
<dd><p>Language support for <a href="https://github.github.com/gfm/">GFM</a> plus
|
||||
subscript, superscript, and emoji syntax.</p>
|
||||
</dd>
|
||||
<dt id="user-content-commonmarklanguage">
|
||||
<code><strong><a href="#user-content-commonmarklanguage">commonmarkLanguage</a></strong>: <a href="https://codemirror.net/docs/ref#language.Language">Language</a></code></dt>
|
||||
|
||||
<dd><p>Language support for strict CommonMark.</p>
|
||||
</dd>
|
||||
<dt id="user-content-insertnewlinecontinuemarkup">
|
||||
<code><strong><a href="#user-content-insertnewlinecontinuemarkup">insertNewlineContinueMarkup</a></strong>: <a href="https://codemirror.net/docs/ref#state.StateCommand">StateCommand</a></code></dt>
|
||||
|
||||
<dd><p>This command, when invoked in Markdown context with cursor
|
||||
selection(s), will create a new line with the markup for
|
||||
blockquotes and lists that were active on the old line. If the
|
||||
cursor was directly after the end of the markup for the old line,
|
||||
trailing whitespace and list markers are removed from that line.</p>
|
||||
<p>The command does nothing in non-Markdown context, so it should
|
||||
not be used as the only binding for Enter (even in a Markdown
|
||||
document, HTML and code regions might use a different language).</p>
|
||||
</dd>
|
||||
<dt id="user-content-insertnewlinecontinuemarkupcommand">
|
||||
<code><strong><a href="#user-content-insertnewlinecontinuemarkupcommand">insertNewlineContinueMarkupCommand</a></strong>(<a id="user-content-insertnewlinecontinuemarkupcommand^config" href="#user-content-insertnewlinecontinuemarkupcommand^config">config</a>⁠?: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a> = {}) → <a href="https://codemirror.net/docs/ref#state.StateCommand">StateCommand</a></code></dt>
|
||||
|
||||
<dd><p>Returns a command like
|
||||
<a href="#user-content-insertnewlinecontinuemarkup"><code>insertNewlineContinueMarkup</code></a>,
|
||||
allowing further configuration.</p>
|
||||
<dl><dt id="user-content-insertnewlinecontinuemarkupcommand^config">
|
||||
<code><strong><a href="#user-content-insertnewlinecontinuemarkupcommand^config">config</a></strong></code></dt>
|
||||
|
||||
<dd><dl><dt id="user-content-insertnewlinecontinuemarkupcommand^config.nontightlists">
|
||||
<code><strong><a href="#user-content-insertnewlinecontinuemarkupcommand^config.nontightlists">nonTightLists</a></strong>⁠?: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">boolean</a></code></dt>
|
||||
|
||||
<dd><p>By default, when pressing enter in a blank second item in a
|
||||
tight (no blank lines between items) list, the command will
|
||||
insert a blank line above that item, starting a non-tight list.
|
||||
Set this to false to disable this behavior.</p>
|
||||
</dd></dl></dd></dl></dd>
|
||||
<dt id="user-content-deletemarkupbackward">
|
||||
<code><strong><a href="#user-content-deletemarkupbackward">deleteMarkupBackward</a></strong>: <a href="https://codemirror.net/docs/ref#state.StateCommand">StateCommand</a></code></dt>
|
||||
|
||||
<dd><p>This command will, when invoked in a Markdown context with the
|
||||
cursor directly after list or blockquote markup, delete one level
|
||||
of markup. When the markup is for a list, it will be replaced by
|
||||
spaces on the first invocation (a further invocation will delete
|
||||
the spaces), to make it easy to continue a list.</p>
|
||||
<p>When not after Markdown block markup, this command will return
|
||||
false, so it is intended to be bound alongside other deletion
|
||||
commands, with a higher precedence than the more generic commands.</p>
|
||||
</dd>
|
||||
<dt id="user-content-markdownkeymap">
|
||||
<code><strong><a href="#user-content-markdownkeymap">markdownKeymap</a></strong>: readonly <a href="https://codemirror.net/docs/ref#view.KeyBinding">KeyBinding</a>[]</code></dt>
|
||||
|
||||
<dd><p>A small keymap with Markdown-specific bindings. Binds Enter to
|
||||
<a href="#user-content-insertnewlinecontinuemarkup"><code>insertNewlineContinueMarkup</code></a>
|
||||
and Backspace to
|
||||
<a href="#user-content-deletemarkupbackward"><code>deleteMarkupBackward</code></a>.</p>
|
||||
</dd>
|
||||
<dt id="user-content-pasteurlaslink">
|
||||
<code><strong><a href="#user-content-pasteurlaslink">pasteURLAsLink</a></strong>: <a href="https://codemirror.net/docs/ref#state.Extension">Extension</a></code></dt>
|
||||
|
||||
<dd><p>An extension that intercepts pastes when the pasted content looks
|
||||
like a URL and the selection is non-empty and selects regular
|
||||
text, making the selection a link with the pasted URL as target.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
501
frontend/node_modules/@codemirror/lang-markdown/dist/index.cjs
generated
vendored
Normal file
501
frontend/node_modules/@codemirror/lang-markdown/dist/index.cjs
generated
vendored
Normal file
@ -0,0 +1,501 @@
|
||||
'use strict';
|
||||
|
||||
var state = require('@codemirror/state');
|
||||
var view = require('@codemirror/view');
|
||||
var language = require('@codemirror/language');
|
||||
var autocomplete = require('@codemirror/autocomplete');
|
||||
var markdown$1 = require('@lezer/markdown');
|
||||
var langHtml = require('@codemirror/lang-html');
|
||||
var common = require('@lezer/common');
|
||||
|
||||
const data = language.defineLanguageFacet({ commentTokens: { block: { open: "<!--", close: "-->" } } });
|
||||
const headingProp = new common.NodeProp();
|
||||
const commonmark = markdown$1.parser.configure({
|
||||
props: [
|
||||
language.foldNodeProp.add(type => {
|
||||
return !type.is("Block") || type.is("Document") || isHeading(type) != null || isList(type) ? undefined
|
||||
: (tree, state) => ({ from: state.doc.lineAt(tree.from).to, to: tree.to });
|
||||
}),
|
||||
headingProp.add(isHeading),
|
||||
language.indentNodeProp.add({
|
||||
Document: () => null
|
||||
}),
|
||||
language.languageDataProp.add({
|
||||
Document: data
|
||||
})
|
||||
]
|
||||
});
|
||||
function isHeading(type) {
|
||||
let match = /^(?:ATX|Setext)Heading(\d)$/.exec(type.name);
|
||||
return match ? +match[1] : undefined;
|
||||
}
|
||||
function isList(type) {
|
||||
return type.name == "OrderedList" || type.name == "BulletList";
|
||||
}
|
||||
function findSectionEnd(headerNode, level) {
|
||||
let last = headerNode;
|
||||
for (;;) {
|
||||
let next = last.nextSibling, heading;
|
||||
if (!next || (heading = isHeading(next.type)) != null && heading <= level)
|
||||
break;
|
||||
last = next;
|
||||
}
|
||||
return last.to;
|
||||
}
|
||||
const headerIndent = language.foldService.of((state, start, end) => {
|
||||
for (let node = language.syntaxTree(state).resolveInner(end, -1); node; node = node.parent) {
|
||||
if (node.from < start)
|
||||
break;
|
||||
let heading = node.type.prop(headingProp);
|
||||
if (heading == null)
|
||||
continue;
|
||||
let upto = findSectionEnd(node, heading);
|
||||
if (upto > end)
|
||||
return { from: end, to: upto };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
function mkLang(parser) {
|
||||
return new language.Language(data, parser, [], "markdown");
|
||||
}
|
||||
/**
|
||||
Language support for strict CommonMark.
|
||||
*/
|
||||
const commonmarkLanguage = mkLang(commonmark);
|
||||
const extended = commonmark.configure([markdown$1.GFM, markdown$1.Subscript, markdown$1.Superscript, markdown$1.Emoji, {
|
||||
props: [
|
||||
language.foldNodeProp.add({
|
||||
Table: (tree, state) => ({ from: state.doc.lineAt(tree.from).to, to: tree.to })
|
||||
})
|
||||
]
|
||||
}]);
|
||||
/**
|
||||
Language support for [GFM](https://github.github.com/gfm/) plus
|
||||
subscript, superscript, and emoji syntax.
|
||||
*/
|
||||
const markdownLanguage = mkLang(extended);
|
||||
function getCodeParser(languages, defaultLanguage) {
|
||||
return (info) => {
|
||||
if (info && languages) {
|
||||
let found = null;
|
||||
// Strip anything after whitespace
|
||||
info = /\S*/.exec(info)[0];
|
||||
if (typeof languages == "function")
|
||||
found = languages(info);
|
||||
else
|
||||
found = language.LanguageDescription.matchLanguageName(languages, info, true);
|
||||
if (found instanceof language.LanguageDescription)
|
||||
return found.support ? found.support.language.parser : language.ParseContext.getSkippingParser(found.load());
|
||||
else if (found)
|
||||
return found.parser;
|
||||
}
|
||||
return defaultLanguage ? defaultLanguage.parser : null;
|
||||
};
|
||||
}
|
||||
|
||||
class Context {
|
||||
constructor(node, from, to, spaceBefore, spaceAfter, type, item) {
|
||||
this.node = node;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.spaceBefore = spaceBefore;
|
||||
this.spaceAfter = spaceAfter;
|
||||
this.type = type;
|
||||
this.item = item;
|
||||
}
|
||||
blank(maxWidth, trailing = true) {
|
||||
let result = this.spaceBefore + (this.node.name == "Blockquote" ? ">" : "");
|
||||
if (maxWidth != null) {
|
||||
while (result.length < maxWidth)
|
||||
result += " ";
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
for (let i = this.to - this.from - result.length - this.spaceAfter.length; i > 0; i--)
|
||||
result += " ";
|
||||
return result + (trailing ? this.spaceAfter : "");
|
||||
}
|
||||
}
|
||||
marker(doc, add) {
|
||||
let number = this.node.name == "OrderedList" ? String((+itemNumber(this.item, doc)[2] + add)) : "";
|
||||
return this.spaceBefore + number + this.type + this.spaceAfter;
|
||||
}
|
||||
}
|
||||
function getContext(node, doc) {
|
||||
let nodes = [], context = [];
|
||||
for (let cur = node; cur; cur = cur.parent) {
|
||||
if (cur.name == "FencedCode")
|
||||
return context;
|
||||
if (cur.name == "ListItem" || cur.name == "Blockquote")
|
||||
nodes.push(cur);
|
||||
}
|
||||
for (let i = nodes.length - 1; i >= 0; i--) {
|
||||
let node = nodes[i], match;
|
||||
let line = doc.lineAt(node.from), startPos = node.from - line.from;
|
||||
if (node.name == "Blockquote" && (match = /^ *>( ?)/.exec(line.text.slice(startPos)))) {
|
||||
context.push(new Context(node, startPos, startPos + match[0].length, "", match[1], ">", null));
|
||||
}
|
||||
else if (node.name == "ListItem" && node.parent.name == "OrderedList" &&
|
||||
(match = /^( *)\d+([.)])( *)/.exec(line.text.slice(startPos)))) {
|
||||
let after = match[3], len = match[0].length;
|
||||
if (after.length >= 4) {
|
||||
after = after.slice(0, after.length - 4);
|
||||
len -= 4;
|
||||
}
|
||||
context.push(new Context(node.parent, startPos, startPos + len, match[1], after, match[2], node));
|
||||
}
|
||||
else if (node.name == "ListItem" && node.parent.name == "BulletList" &&
|
||||
(match = /^( *)([-+*])( {1,4}\[[ xX]\])?( +)/.exec(line.text.slice(startPos)))) {
|
||||
let after = match[4], len = match[0].length;
|
||||
if (after.length > 4) {
|
||||
after = after.slice(0, after.length - 4);
|
||||
len -= 4;
|
||||
}
|
||||
let type = match[2];
|
||||
if (match[3])
|
||||
type += match[3].replace(/[xX]/, ' ');
|
||||
context.push(new Context(node.parent, startPos, startPos + len, match[1], after, type, node));
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
function itemNumber(item, doc) {
|
||||
return /^(\s*)(\d+)(?=[.)])/.exec(doc.sliceString(item.from, item.from + 10));
|
||||
}
|
||||
function renumberList(after, doc, changes, offset = 0) {
|
||||
for (let prev = -1, node = after;;) {
|
||||
if (node.name == "ListItem") {
|
||||
let m = itemNumber(node, doc);
|
||||
let number = +m[2];
|
||||
if (prev >= 0) {
|
||||
if (number != prev + 1)
|
||||
return;
|
||||
changes.push({ from: node.from + m[1].length, to: node.from + m[0].length, insert: String(prev + 2 + offset) });
|
||||
}
|
||||
prev = number;
|
||||
}
|
||||
let next = node.nextSibling;
|
||||
if (!next)
|
||||
break;
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
function normalizeIndent(content, state$1) {
|
||||
let blank = /^[ \t]*/.exec(content)[0].length;
|
||||
if (!blank || state$1.facet(language.indentUnit) != "\t")
|
||||
return content;
|
||||
let col = state.countColumn(content, 4, blank);
|
||||
let space = "";
|
||||
for (let i = col; i > 0;) {
|
||||
if (i >= 4) {
|
||||
space += "\t";
|
||||
i -= 4;
|
||||
}
|
||||
else {
|
||||
space += " ";
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return space + content.slice(blank);
|
||||
}
|
||||
/**
|
||||
Returns a command like
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup),
|
||||
allowing further configuration.
|
||||
*/
|
||||
const insertNewlineContinueMarkupCommand = (config = {}) => ({ state: state$1, dispatch }) => {
|
||||
let tree = language.syntaxTree(state$1), { doc } = state$1;
|
||||
let dont = null, changes = state$1.changeByRange(range => {
|
||||
if (!range.empty || !markdownLanguage.isActiveAt(state$1, range.from, -1) && !markdownLanguage.isActiveAt(state$1, range.from, 1))
|
||||
return dont = { range };
|
||||
let pos = range.from, line = doc.lineAt(pos);
|
||||
let context = getContext(tree.resolveInner(pos, -1), doc);
|
||||
while (context.length && context[context.length - 1].from > pos - line.from)
|
||||
context.pop();
|
||||
if (!context.length)
|
||||
return dont = { range };
|
||||
let inner = context[context.length - 1];
|
||||
if (inner.to - inner.spaceAfter.length > pos - line.from)
|
||||
return dont = { range };
|
||||
let emptyLine = pos >= (inner.to - inner.spaceAfter.length) && !/\S/.test(line.text.slice(inner.to));
|
||||
// Empty line in list
|
||||
if (inner.item && emptyLine) {
|
||||
let first = inner.node.firstChild, second = inner.node.getChild("ListItem", "ListItem");
|
||||
// Not second item or blank line before: delete a level of markup
|
||||
if (first.to >= pos || second && second.to < pos ||
|
||||
line.from > 0 && !/[^\s>]/.test(doc.lineAt(line.from - 1).text) ||
|
||||
config.nonTightLists === false) {
|
||||
let next = context.length > 1 ? context[context.length - 2] : null;
|
||||
let delTo, insert = "";
|
||||
if (next && next.item) { // Re-add marker for the list at the next level
|
||||
delTo = line.from + next.from;
|
||||
insert = next.marker(doc, 1);
|
||||
}
|
||||
else {
|
||||
delTo = line.from + (next ? next.to : 0);
|
||||
}
|
||||
let changes = [{ from: delTo, to: pos, insert }];
|
||||
if (inner.node.name == "OrderedList")
|
||||
renumberList(inner.item, doc, changes, -2);
|
||||
if (next && next.node.name == "OrderedList")
|
||||
renumberList(next.item, doc, changes);
|
||||
return { range: state.EditorSelection.cursor(delTo + insert.length), changes };
|
||||
}
|
||||
else { // Move second item down, making tight two-item list non-tight
|
||||
let insert = blankLine(context, state$1, line);
|
||||
return { range: state.EditorSelection.cursor(pos + insert.length + 1),
|
||||
changes: { from: line.from, insert: insert + state$1.lineBreak } };
|
||||
}
|
||||
}
|
||||
if (inner.node.name == "Blockquote" && emptyLine && line.from) {
|
||||
let prevLine = doc.lineAt(line.from - 1), quoted = />\s*$/.exec(prevLine.text);
|
||||
// Two aligned empty quoted lines in a row
|
||||
if (quoted && quoted.index == inner.from) {
|
||||
let changes = state$1.changes([{ from: prevLine.from + quoted.index, to: prevLine.to },
|
||||
{ from: line.from + inner.from, to: line.to }]);
|
||||
return { range: range.map(changes), changes };
|
||||
}
|
||||
}
|
||||
let changes = [];
|
||||
if (inner.node.name == "OrderedList")
|
||||
renumberList(inner.item, doc, changes);
|
||||
let continued = inner.item && inner.item.from < line.from;
|
||||
let insert = "";
|
||||
// If not dedented
|
||||
if (!continued || /^[\s\d.)\-+*>]*/.exec(line.text)[0].length >= inner.to) {
|
||||
for (let i = 0, e = context.length - 1; i <= e; i++) {
|
||||
insert += i == e && !continued ? context[i].marker(doc, 1)
|
||||
: context[i].blank(i < e ? state.countColumn(line.text, 4, context[i + 1].from) - insert.length : null);
|
||||
}
|
||||
}
|
||||
let from = pos;
|
||||
while (from > line.from && /\s/.test(line.text.charAt(from - line.from - 1)))
|
||||
from--;
|
||||
insert = normalizeIndent(insert, state$1);
|
||||
if (nonTightList(inner.node, state$1.doc))
|
||||
insert = blankLine(context, state$1, line) + state$1.lineBreak + insert;
|
||||
changes.push({ from, to: pos, insert: state$1.lineBreak + insert });
|
||||
return { range: state.EditorSelection.cursor(from + insert.length + 1), changes };
|
||||
});
|
||||
if (dont)
|
||||
return false;
|
||||
dispatch(state$1.update(changes, { scrollIntoView: true, userEvent: "input" }));
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
This command, when invoked in Markdown context with cursor
|
||||
selection(s), will create a new line with the markup for
|
||||
blockquotes and lists that were active on the old line. If the
|
||||
cursor was directly after the end of the markup for the old line,
|
||||
trailing whitespace and list markers are removed from that line.
|
||||
|
||||
The command does nothing in non-Markdown context, so it should
|
||||
not be used as the only binding for Enter (even in a Markdown
|
||||
document, HTML and code regions might use a different language).
|
||||
*/
|
||||
const insertNewlineContinueMarkup = insertNewlineContinueMarkupCommand();
|
||||
function isMark(node) {
|
||||
return node.name == "QuoteMark" || node.name == "ListMark";
|
||||
}
|
||||
function nonTightList(node, doc) {
|
||||
if (node.name != "OrderedList" && node.name != "BulletList")
|
||||
return false;
|
||||
let first = node.firstChild, second = node.getChild("ListItem", "ListItem");
|
||||
if (!second)
|
||||
return false;
|
||||
let line1 = doc.lineAt(first.to), line2 = doc.lineAt(second.from);
|
||||
let empty = /^[\s>]*$/.test(line1.text);
|
||||
return line1.number + (empty ? 0 : 1) < line2.number;
|
||||
}
|
||||
function blankLine(context, state$1, line) {
|
||||
let insert = "";
|
||||
for (let i = 0, e = context.length - 2; i <= e; i++) {
|
||||
insert += context[i].blank(i < e
|
||||
? state.countColumn(line.text, 4, context[i + 1].from) - insert.length
|
||||
: null, i < e);
|
||||
}
|
||||
return normalizeIndent(insert, state$1);
|
||||
}
|
||||
function contextNodeForDelete(tree, pos) {
|
||||
let node = tree.resolveInner(pos, -1), scan = pos;
|
||||
if (isMark(node)) {
|
||||
scan = node.from;
|
||||
node = node.parent;
|
||||
}
|
||||
for (let prev; prev = node.childBefore(scan);) {
|
||||
if (isMark(prev)) {
|
||||
scan = prev.from;
|
||||
}
|
||||
else if (prev.name == "OrderedList" || prev.name == "BulletList") {
|
||||
node = prev.lastChild;
|
||||
scan = node.to;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
This command will, when invoked in a Markdown context with the
|
||||
cursor directly after list or blockquote markup, delete one level
|
||||
of markup. When the markup is for a list, it will be replaced by
|
||||
spaces on the first invocation (a further invocation will delete
|
||||
the spaces), to make it easy to continue a list.
|
||||
|
||||
When not after Markdown block markup, this command will return
|
||||
false, so it is intended to be bound alongside other deletion
|
||||
commands, with a higher precedence than the more generic commands.
|
||||
*/
|
||||
const deleteMarkupBackward = ({ state: state$1, dispatch }) => {
|
||||
let tree = language.syntaxTree(state$1);
|
||||
let dont = null, changes = state$1.changeByRange(range => {
|
||||
let pos = range.from, { doc } = state$1;
|
||||
if (range.empty && markdownLanguage.isActiveAt(state$1, range.from)) {
|
||||
let line = doc.lineAt(pos);
|
||||
let context = getContext(contextNodeForDelete(tree, pos), doc);
|
||||
if (context.length) {
|
||||
let inner = context[context.length - 1];
|
||||
let spaceEnd = inner.to - inner.spaceAfter.length + (inner.spaceAfter ? 1 : 0);
|
||||
// Delete extra trailing space after markup
|
||||
if (pos - line.from > spaceEnd && !/\S/.test(line.text.slice(spaceEnd, pos - line.from)))
|
||||
return { range: state.EditorSelection.cursor(line.from + spaceEnd),
|
||||
changes: { from: line.from + spaceEnd, to: pos } };
|
||||
if (pos - line.from == spaceEnd &&
|
||||
// Only apply this if we're on the line that has the
|
||||
// construct's syntax, or there's only indentation in the
|
||||
// target range
|
||||
(!inner.item || line.from <= inner.item.from || !/\S/.test(line.text.slice(0, inner.to)))) {
|
||||
let start = line.from + inner.from;
|
||||
// Replace a list item marker with blank space
|
||||
if (inner.item && inner.node.from < inner.item.from && /\S/.test(line.text.slice(inner.from, inner.to))) {
|
||||
let insert = inner.blank(state.countColumn(line.text, 4, inner.to) - state.countColumn(line.text, 4, inner.from));
|
||||
if (start == line.from)
|
||||
insert = normalizeIndent(insert, state$1);
|
||||
return { range: state.EditorSelection.cursor(start + insert.length),
|
||||
changes: { from: start, to: line.from + inner.to, insert } };
|
||||
}
|
||||
// Delete one level of indentation
|
||||
if (start < pos)
|
||||
return { range: state.EditorSelection.cursor(start), changes: { from: start, to: pos } };
|
||||
}
|
||||
}
|
||||
}
|
||||
return dont = { range };
|
||||
});
|
||||
if (dont)
|
||||
return false;
|
||||
dispatch(state$1.update(changes, { scrollIntoView: true, userEvent: "delete" }));
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
A small keymap with Markdown-specific bindings. Binds Enter to
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup)
|
||||
and Backspace to
|
||||
[`deleteMarkupBackward`](https://codemirror.net/6/docs/ref/#lang-markdown.deleteMarkupBackward).
|
||||
*/
|
||||
const markdownKeymap = [
|
||||
{ key: "Enter", run: insertNewlineContinueMarkup },
|
||||
{ key: "Backspace", run: deleteMarkupBackward }
|
||||
];
|
||||
const htmlNoMatch = langHtml.html({ matchClosingTags: false });
|
||||
/**
|
||||
Markdown language support.
|
||||
*/
|
||||
function markdown(config = {}) {
|
||||
let { codeLanguages, defaultCodeLanguage, addKeymap = true, base: { parser } = commonmarkLanguage, completeHTMLTags = true, pasteURLAsLink: pasteURL = true, htmlTagLanguage = htmlNoMatch } = config;
|
||||
if (!(parser instanceof markdown$1.MarkdownParser))
|
||||
throw new RangeError("Base parser provided to `markdown` should be a Markdown parser");
|
||||
let extensions = config.extensions ? [config.extensions] : [];
|
||||
let support = [htmlTagLanguage.support, headerIndent], defaultCode;
|
||||
if (pasteURL)
|
||||
support.push(pasteURLAsLink);
|
||||
if (defaultCodeLanguage instanceof language.LanguageSupport) {
|
||||
support.push(defaultCodeLanguage.support);
|
||||
defaultCode = defaultCodeLanguage.language;
|
||||
}
|
||||
else if (defaultCodeLanguage) {
|
||||
defaultCode = defaultCodeLanguage;
|
||||
}
|
||||
let codeParser = codeLanguages || defaultCode ? getCodeParser(codeLanguages, defaultCode) : undefined;
|
||||
extensions.push(markdown$1.parseCode({ codeParser, htmlParser: htmlTagLanguage.language.parser }));
|
||||
if (addKeymap)
|
||||
support.push(state.Prec.high(view.keymap.of(markdownKeymap)));
|
||||
let lang = mkLang(parser.configure(extensions));
|
||||
if (completeHTMLTags)
|
||||
support.push(lang.data.of({ autocomplete: htmlTagCompletion }));
|
||||
return new language.LanguageSupport(lang, support);
|
||||
}
|
||||
function htmlTagCompletion(context) {
|
||||
let { state, pos } = context, m = /<[:\-\.\w\u00b7-\uffff]*$/.exec(state.sliceDoc(pos - 25, pos));
|
||||
if (!m)
|
||||
return null;
|
||||
let tree = language.syntaxTree(state).resolveInner(pos, -1);
|
||||
while (tree && !tree.type.isTop) {
|
||||
if (tree.name == "CodeBlock" || tree.name == "FencedCode" || tree.name == "ProcessingInstructionBlock" ||
|
||||
tree.name == "CommentBlock" || tree.name == "Link" || tree.name == "Image")
|
||||
return null;
|
||||
tree = tree.parent;
|
||||
}
|
||||
return {
|
||||
from: pos - m[0].length, to: pos,
|
||||
options: htmlTagCompletions(),
|
||||
validFor: /^<[:\-\.\w\u00b7-\uffff]*$/
|
||||
};
|
||||
}
|
||||
let _tagCompletions = null;
|
||||
function htmlTagCompletions() {
|
||||
if (_tagCompletions)
|
||||
return _tagCompletions;
|
||||
let result = langHtml.htmlCompletionSource(new autocomplete.CompletionContext(state.EditorState.create({ extensions: htmlNoMatch }), 0, true));
|
||||
return _tagCompletions = result ? result.options : [];
|
||||
}
|
||||
const nonPlainText = /code|horizontalrule|html|link|comment|processing|escape|entity|image|mark|url/i;
|
||||
/**
|
||||
An extension that intercepts pastes when the pasted content looks
|
||||
like a URL and the selection is non-empty and selects regular
|
||||
text, making the selection a link with the pasted URL as target.
|
||||
*/
|
||||
const pasteURLAsLink = view.EditorView.domEventHandlers({
|
||||
paste: (event, view) => {
|
||||
var _a;
|
||||
let { main } = view.state.selection;
|
||||
if (main.empty)
|
||||
return false;
|
||||
let link = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/plain");
|
||||
if (!link || !/^(https?:\/\/|mailto:|xmpp:|www\.)/.test(link))
|
||||
return false;
|
||||
if (/^www\./.test(link))
|
||||
link = "https://" + link;
|
||||
if (!markdownLanguage.isActiveAt(view.state, main.from, 1))
|
||||
return false;
|
||||
let tree = language.syntaxTree(view.state), crossesNode = false;
|
||||
// Verify that no nodes are started/ended between the selection
|
||||
// points, and we're not inside any non-plain-text construct.
|
||||
tree.iterate({
|
||||
from: main.from, to: main.to,
|
||||
enter: node => { if (node.from > main.from || nonPlainText.test(node.name))
|
||||
crossesNode = true; },
|
||||
leave: node => { if (node.to < main.to)
|
||||
crossesNode = true; }
|
||||
});
|
||||
if (crossesNode)
|
||||
return false;
|
||||
view.dispatch({
|
||||
changes: [{ from: main.from, insert: "[" }, { from: main.to, insert: `](${link})` }],
|
||||
userEvent: "input.paste",
|
||||
scrollIntoView: true
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
exports.commonmarkLanguage = commonmarkLanguage;
|
||||
exports.deleteMarkupBackward = deleteMarkupBackward;
|
||||
exports.insertNewlineContinueMarkup = insertNewlineContinueMarkup;
|
||||
exports.insertNewlineContinueMarkupCommand = insertNewlineContinueMarkupCommand;
|
||||
exports.markdown = markdown;
|
||||
exports.markdownKeymap = markdownKeymap;
|
||||
exports.markdownLanguage = markdownLanguage;
|
||||
exports.pasteURLAsLink = pasteURLAsLink;
|
||||
124
frontend/node_modules/@codemirror/lang-markdown/dist/index.d.cts
generated
vendored
Normal file
124
frontend/node_modules/@codemirror/lang-markdown/dist/index.d.cts
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
import * as _codemirror_state from '@codemirror/state';
|
||||
import { StateCommand } from '@codemirror/state';
|
||||
import { KeyBinding } from '@codemirror/view';
|
||||
import { Language, LanguageSupport, LanguageDescription } from '@codemirror/language';
|
||||
import { MarkdownExtension } from '@lezer/markdown';
|
||||
|
||||
/**
|
||||
Language support for strict CommonMark.
|
||||
*/
|
||||
declare const commonmarkLanguage: Language;
|
||||
/**
|
||||
Language support for [GFM](https://github.github.com/gfm/) plus
|
||||
subscript, superscript, and emoji syntax.
|
||||
*/
|
||||
declare const markdownLanguage: Language;
|
||||
|
||||
/**
|
||||
Returns a command like
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup),
|
||||
allowing further configuration.
|
||||
*/
|
||||
declare const insertNewlineContinueMarkupCommand: (config?: {
|
||||
/**
|
||||
By default, when pressing enter in a blank second item in a
|
||||
tight (no blank lines between items) list, the command will
|
||||
insert a blank line above that item, starting a non-tight list.
|
||||
Set this to false to disable this behavior.
|
||||
*/
|
||||
nonTightLists?: boolean;
|
||||
}) => StateCommand;
|
||||
/**
|
||||
This command, when invoked in Markdown context with cursor
|
||||
selection(s), will create a new line with the markup for
|
||||
blockquotes and lists that were active on the old line. If the
|
||||
cursor was directly after the end of the markup for the old line,
|
||||
trailing whitespace and list markers are removed from that line.
|
||||
|
||||
The command does nothing in non-Markdown context, so it should
|
||||
not be used as the only binding for Enter (even in a Markdown
|
||||
document, HTML and code regions might use a different language).
|
||||
*/
|
||||
declare const insertNewlineContinueMarkup: StateCommand;
|
||||
/**
|
||||
This command will, when invoked in a Markdown context with the
|
||||
cursor directly after list or blockquote markup, delete one level
|
||||
of markup. When the markup is for a list, it will be replaced by
|
||||
spaces on the first invocation (a further invocation will delete
|
||||
the spaces), to make it easy to continue a list.
|
||||
|
||||
When not after Markdown block markup, this command will return
|
||||
false, so it is intended to be bound alongside other deletion
|
||||
commands, with a higher precedence than the more generic commands.
|
||||
*/
|
||||
declare const deleteMarkupBackward: StateCommand;
|
||||
|
||||
/**
|
||||
A small keymap with Markdown-specific bindings. Binds Enter to
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup)
|
||||
and Backspace to
|
||||
[`deleteMarkupBackward`](https://codemirror.net/6/docs/ref/#lang-markdown.deleteMarkupBackward).
|
||||
*/
|
||||
declare const markdownKeymap: readonly KeyBinding[];
|
||||
/**
|
||||
Markdown language support.
|
||||
*/
|
||||
declare function markdown(config?: {
|
||||
/**
|
||||
When given, this language will be used by default to parse code
|
||||
blocks.
|
||||
*/
|
||||
defaultCodeLanguage?: Language | LanguageSupport;
|
||||
/**
|
||||
A source of language support for highlighting fenced code
|
||||
blocks. When it is an array, the parser will use
|
||||
[`LanguageDescription.matchLanguageName`](https://codemirror.net/6/docs/ref/#language.LanguageDescription^matchLanguageName)
|
||||
with the fenced code info to find a matching language. When it
|
||||
is a function, will be called with the info string and may
|
||||
return a language or `LanguageDescription` object.
|
||||
*/
|
||||
codeLanguages?: readonly LanguageDescription[] | ((info: string) => Language | LanguageDescription | null);
|
||||
/**
|
||||
Set this to false to disable installation of the Markdown
|
||||
[keymap](https://codemirror.net/6/docs/ref/#lang-markdown.markdownKeymap).
|
||||
*/
|
||||
addKeymap?: boolean;
|
||||
/**
|
||||
Markdown parser
|
||||
[extensions](https://github.com/lezer-parser/markdown#user-content-markdownextension)
|
||||
to add to the parser.
|
||||
*/
|
||||
extensions?: MarkdownExtension;
|
||||
/**
|
||||
The base language to use. Defaults to
|
||||
[`commonmarkLanguage`](https://codemirror.net/6/docs/ref/#lang-markdown.commonmarkLanguage).
|
||||
*/
|
||||
base?: Language;
|
||||
/**
|
||||
By default, the extension installs an autocompletion source that
|
||||
completes HTML tags when a `<` is typed. Set this to false to
|
||||
disable this.
|
||||
*/
|
||||
completeHTMLTags?: boolean;
|
||||
/**
|
||||
The returned language contains
|
||||
[`pasteURLAsLink`](https://codemirror.net/6/docs/ref/#lang-markdown.pasteURLAsLink) as a support
|
||||
extension unless you set this to false.
|
||||
*/
|
||||
pasteURLAsLink?: boolean;
|
||||
/**
|
||||
By default, HTML tags in the document are handled by the [HTML
|
||||
language](https://github.com/codemirror/lang-html) package with
|
||||
tag matching turned off. You can pass in an alternative language
|
||||
configuration here if you want.
|
||||
*/
|
||||
htmlTagLanguage?: LanguageSupport;
|
||||
}): LanguageSupport;
|
||||
/**
|
||||
An extension that intercepts pastes when the pasted content looks
|
||||
like a URL and the selection is non-empty and selects regular
|
||||
text, making the selection a link with the pasted URL as target.
|
||||
*/
|
||||
declare const pasteURLAsLink: _codemirror_state.Extension;
|
||||
|
||||
export { commonmarkLanguage, deleteMarkupBackward, insertNewlineContinueMarkup, insertNewlineContinueMarkupCommand, markdown, markdownKeymap, markdownLanguage, pasteURLAsLink };
|
||||
124
frontend/node_modules/@codemirror/lang-markdown/dist/index.d.ts
generated
vendored
Normal file
124
frontend/node_modules/@codemirror/lang-markdown/dist/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
import * as _codemirror_state from '@codemirror/state';
|
||||
import { StateCommand } from '@codemirror/state';
|
||||
import { KeyBinding } from '@codemirror/view';
|
||||
import { Language, LanguageSupport, LanguageDescription } from '@codemirror/language';
|
||||
import { MarkdownExtension } from '@lezer/markdown';
|
||||
|
||||
/**
|
||||
Language support for strict CommonMark.
|
||||
*/
|
||||
declare const commonmarkLanguage: Language;
|
||||
/**
|
||||
Language support for [GFM](https://github.github.com/gfm/) plus
|
||||
subscript, superscript, and emoji syntax.
|
||||
*/
|
||||
declare const markdownLanguage: Language;
|
||||
|
||||
/**
|
||||
Returns a command like
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup),
|
||||
allowing further configuration.
|
||||
*/
|
||||
declare const insertNewlineContinueMarkupCommand: (config?: {
|
||||
/**
|
||||
By default, when pressing enter in a blank second item in a
|
||||
tight (no blank lines between items) list, the command will
|
||||
insert a blank line above that item, starting a non-tight list.
|
||||
Set this to false to disable this behavior.
|
||||
*/
|
||||
nonTightLists?: boolean;
|
||||
}) => StateCommand;
|
||||
/**
|
||||
This command, when invoked in Markdown context with cursor
|
||||
selection(s), will create a new line with the markup for
|
||||
blockquotes and lists that were active on the old line. If the
|
||||
cursor was directly after the end of the markup for the old line,
|
||||
trailing whitespace and list markers are removed from that line.
|
||||
|
||||
The command does nothing in non-Markdown context, so it should
|
||||
not be used as the only binding for Enter (even in a Markdown
|
||||
document, HTML and code regions might use a different language).
|
||||
*/
|
||||
declare const insertNewlineContinueMarkup: StateCommand;
|
||||
/**
|
||||
This command will, when invoked in a Markdown context with the
|
||||
cursor directly after list or blockquote markup, delete one level
|
||||
of markup. When the markup is for a list, it will be replaced by
|
||||
spaces on the first invocation (a further invocation will delete
|
||||
the spaces), to make it easy to continue a list.
|
||||
|
||||
When not after Markdown block markup, this command will return
|
||||
false, so it is intended to be bound alongside other deletion
|
||||
commands, with a higher precedence than the more generic commands.
|
||||
*/
|
||||
declare const deleteMarkupBackward: StateCommand;
|
||||
|
||||
/**
|
||||
A small keymap with Markdown-specific bindings. Binds Enter to
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup)
|
||||
and Backspace to
|
||||
[`deleteMarkupBackward`](https://codemirror.net/6/docs/ref/#lang-markdown.deleteMarkupBackward).
|
||||
*/
|
||||
declare const markdownKeymap: readonly KeyBinding[];
|
||||
/**
|
||||
Markdown language support.
|
||||
*/
|
||||
declare function markdown(config?: {
|
||||
/**
|
||||
When given, this language will be used by default to parse code
|
||||
blocks.
|
||||
*/
|
||||
defaultCodeLanguage?: Language | LanguageSupport;
|
||||
/**
|
||||
A source of language support for highlighting fenced code
|
||||
blocks. When it is an array, the parser will use
|
||||
[`LanguageDescription.matchLanguageName`](https://codemirror.net/6/docs/ref/#language.LanguageDescription^matchLanguageName)
|
||||
with the fenced code info to find a matching language. When it
|
||||
is a function, will be called with the info string and may
|
||||
return a language or `LanguageDescription` object.
|
||||
*/
|
||||
codeLanguages?: readonly LanguageDescription[] | ((info: string) => Language | LanguageDescription | null);
|
||||
/**
|
||||
Set this to false to disable installation of the Markdown
|
||||
[keymap](https://codemirror.net/6/docs/ref/#lang-markdown.markdownKeymap).
|
||||
*/
|
||||
addKeymap?: boolean;
|
||||
/**
|
||||
Markdown parser
|
||||
[extensions](https://github.com/lezer-parser/markdown#user-content-markdownextension)
|
||||
to add to the parser.
|
||||
*/
|
||||
extensions?: MarkdownExtension;
|
||||
/**
|
||||
The base language to use. Defaults to
|
||||
[`commonmarkLanguage`](https://codemirror.net/6/docs/ref/#lang-markdown.commonmarkLanguage).
|
||||
*/
|
||||
base?: Language;
|
||||
/**
|
||||
By default, the extension installs an autocompletion source that
|
||||
completes HTML tags when a `<` is typed. Set this to false to
|
||||
disable this.
|
||||
*/
|
||||
completeHTMLTags?: boolean;
|
||||
/**
|
||||
The returned language contains
|
||||
[`pasteURLAsLink`](https://codemirror.net/6/docs/ref/#lang-markdown.pasteURLAsLink) as a support
|
||||
extension unless you set this to false.
|
||||
*/
|
||||
pasteURLAsLink?: boolean;
|
||||
/**
|
||||
By default, HTML tags in the document are handled by the [HTML
|
||||
language](https://github.com/codemirror/lang-html) package with
|
||||
tag matching turned off. You can pass in an alternative language
|
||||
configuration here if you want.
|
||||
*/
|
||||
htmlTagLanguage?: LanguageSupport;
|
||||
}): LanguageSupport;
|
||||
/**
|
||||
An extension that intercepts pastes when the pasted content looks
|
||||
like a URL and the selection is non-empty and selects regular
|
||||
text, making the selection a link with the pasted URL as target.
|
||||
*/
|
||||
declare const pasteURLAsLink: _codemirror_state.Extension;
|
||||
|
||||
export { commonmarkLanguage, deleteMarkupBackward, insertNewlineContinueMarkup, insertNewlineContinueMarkupCommand, markdown, markdownKeymap, markdownLanguage, pasteURLAsLink };
|
||||
492
frontend/node_modules/@codemirror/lang-markdown/dist/index.js
generated
vendored
Normal file
492
frontend/node_modules/@codemirror/lang-markdown/dist/index.js
generated
vendored
Normal file
@ -0,0 +1,492 @@
|
||||
import { EditorSelection, countColumn, Prec, EditorState } from '@codemirror/state';
|
||||
import { EditorView, keymap } from '@codemirror/view';
|
||||
import { defineLanguageFacet, foldNodeProp, indentNodeProp, languageDataProp, foldService, syntaxTree, Language, LanguageDescription, ParseContext, indentUnit, LanguageSupport } from '@codemirror/language';
|
||||
import { CompletionContext } from '@codemirror/autocomplete';
|
||||
import { parser, GFM, Subscript, Superscript, Emoji, MarkdownParser, parseCode } from '@lezer/markdown';
|
||||
import { html, htmlCompletionSource } from '@codemirror/lang-html';
|
||||
import { NodeProp } from '@lezer/common';
|
||||
|
||||
const data = /*@__PURE__*/defineLanguageFacet({ commentTokens: { block: { open: "<!--", close: "-->" } } });
|
||||
const headingProp = /*@__PURE__*/new NodeProp();
|
||||
const commonmark = /*@__PURE__*/parser.configure({
|
||||
props: [
|
||||
/*@__PURE__*/foldNodeProp.add(type => {
|
||||
return !type.is("Block") || type.is("Document") || isHeading(type) != null || isList(type) ? undefined
|
||||
: (tree, state) => ({ from: state.doc.lineAt(tree.from).to, to: tree.to });
|
||||
}),
|
||||
/*@__PURE__*/headingProp.add(isHeading),
|
||||
/*@__PURE__*/indentNodeProp.add({
|
||||
Document: () => null
|
||||
}),
|
||||
/*@__PURE__*/languageDataProp.add({
|
||||
Document: data
|
||||
})
|
||||
]
|
||||
});
|
||||
function isHeading(type) {
|
||||
let match = /^(?:ATX|Setext)Heading(\d)$/.exec(type.name);
|
||||
return match ? +match[1] : undefined;
|
||||
}
|
||||
function isList(type) {
|
||||
return type.name == "OrderedList" || type.name == "BulletList";
|
||||
}
|
||||
function findSectionEnd(headerNode, level) {
|
||||
let last = headerNode;
|
||||
for (;;) {
|
||||
let next = last.nextSibling, heading;
|
||||
if (!next || (heading = isHeading(next.type)) != null && heading <= level)
|
||||
break;
|
||||
last = next;
|
||||
}
|
||||
return last.to;
|
||||
}
|
||||
const headerIndent = /*@__PURE__*/foldService.of((state, start, end) => {
|
||||
for (let node = syntaxTree(state).resolveInner(end, -1); node; node = node.parent) {
|
||||
if (node.from < start)
|
||||
break;
|
||||
let heading = node.type.prop(headingProp);
|
||||
if (heading == null)
|
||||
continue;
|
||||
let upto = findSectionEnd(node, heading);
|
||||
if (upto > end)
|
||||
return { from: end, to: upto };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
function mkLang(parser) {
|
||||
return new Language(data, parser, [], "markdown");
|
||||
}
|
||||
/**
|
||||
Language support for strict CommonMark.
|
||||
*/
|
||||
const commonmarkLanguage = /*@__PURE__*/mkLang(commonmark);
|
||||
const extended = /*@__PURE__*/commonmark.configure([GFM, Subscript, Superscript, Emoji, {
|
||||
props: [
|
||||
/*@__PURE__*/foldNodeProp.add({
|
||||
Table: (tree, state) => ({ from: state.doc.lineAt(tree.from).to, to: tree.to })
|
||||
})
|
||||
]
|
||||
}]);
|
||||
/**
|
||||
Language support for [GFM](https://github.github.com/gfm/) plus
|
||||
subscript, superscript, and emoji syntax.
|
||||
*/
|
||||
const markdownLanguage = /*@__PURE__*/mkLang(extended);
|
||||
function getCodeParser(languages, defaultLanguage) {
|
||||
return (info) => {
|
||||
if (info && languages) {
|
||||
let found = null;
|
||||
// Strip anything after whitespace
|
||||
info = /\S*/.exec(info)[0];
|
||||
if (typeof languages == "function")
|
||||
found = languages(info);
|
||||
else
|
||||
found = LanguageDescription.matchLanguageName(languages, info, true);
|
||||
if (found instanceof LanguageDescription)
|
||||
return found.support ? found.support.language.parser : ParseContext.getSkippingParser(found.load());
|
||||
else if (found)
|
||||
return found.parser;
|
||||
}
|
||||
return defaultLanguage ? defaultLanguage.parser : null;
|
||||
};
|
||||
}
|
||||
|
||||
class Context {
|
||||
constructor(node, from, to, spaceBefore, spaceAfter, type, item) {
|
||||
this.node = node;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.spaceBefore = spaceBefore;
|
||||
this.spaceAfter = spaceAfter;
|
||||
this.type = type;
|
||||
this.item = item;
|
||||
}
|
||||
blank(maxWidth, trailing = true) {
|
||||
let result = this.spaceBefore + (this.node.name == "Blockquote" ? ">" : "");
|
||||
if (maxWidth != null) {
|
||||
while (result.length < maxWidth)
|
||||
result += " ";
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
for (let i = this.to - this.from - result.length - this.spaceAfter.length; i > 0; i--)
|
||||
result += " ";
|
||||
return result + (trailing ? this.spaceAfter : "");
|
||||
}
|
||||
}
|
||||
marker(doc, add) {
|
||||
let number = this.node.name == "OrderedList" ? String((+itemNumber(this.item, doc)[2] + add)) : "";
|
||||
return this.spaceBefore + number + this.type + this.spaceAfter;
|
||||
}
|
||||
}
|
||||
function getContext(node, doc) {
|
||||
let nodes = [], context = [];
|
||||
for (let cur = node; cur; cur = cur.parent) {
|
||||
if (cur.name == "FencedCode")
|
||||
return context;
|
||||
if (cur.name == "ListItem" || cur.name == "Blockquote")
|
||||
nodes.push(cur);
|
||||
}
|
||||
for (let i = nodes.length - 1; i >= 0; i--) {
|
||||
let node = nodes[i], match;
|
||||
let line = doc.lineAt(node.from), startPos = node.from - line.from;
|
||||
if (node.name == "Blockquote" && (match = /^ *>( ?)/.exec(line.text.slice(startPos)))) {
|
||||
context.push(new Context(node, startPos, startPos + match[0].length, "", match[1], ">", null));
|
||||
}
|
||||
else if (node.name == "ListItem" && node.parent.name == "OrderedList" &&
|
||||
(match = /^( *)\d+([.)])( *)/.exec(line.text.slice(startPos)))) {
|
||||
let after = match[3], len = match[0].length;
|
||||
if (after.length >= 4) {
|
||||
after = after.slice(0, after.length - 4);
|
||||
len -= 4;
|
||||
}
|
||||
context.push(new Context(node.parent, startPos, startPos + len, match[1], after, match[2], node));
|
||||
}
|
||||
else if (node.name == "ListItem" && node.parent.name == "BulletList" &&
|
||||
(match = /^( *)([-+*])( {1,4}\[[ xX]\])?( +)/.exec(line.text.slice(startPos)))) {
|
||||
let after = match[4], len = match[0].length;
|
||||
if (after.length > 4) {
|
||||
after = after.slice(0, after.length - 4);
|
||||
len -= 4;
|
||||
}
|
||||
let type = match[2];
|
||||
if (match[3])
|
||||
type += match[3].replace(/[xX]/, ' ');
|
||||
context.push(new Context(node.parent, startPos, startPos + len, match[1], after, type, node));
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
function itemNumber(item, doc) {
|
||||
return /^(\s*)(\d+)(?=[.)])/.exec(doc.sliceString(item.from, item.from + 10));
|
||||
}
|
||||
function renumberList(after, doc, changes, offset = 0) {
|
||||
for (let prev = -1, node = after;;) {
|
||||
if (node.name == "ListItem") {
|
||||
let m = itemNumber(node, doc);
|
||||
let number = +m[2];
|
||||
if (prev >= 0) {
|
||||
if (number != prev + 1)
|
||||
return;
|
||||
changes.push({ from: node.from + m[1].length, to: node.from + m[0].length, insert: String(prev + 2 + offset) });
|
||||
}
|
||||
prev = number;
|
||||
}
|
||||
let next = node.nextSibling;
|
||||
if (!next)
|
||||
break;
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
function normalizeIndent(content, state) {
|
||||
let blank = /^[ \t]*/.exec(content)[0].length;
|
||||
if (!blank || state.facet(indentUnit) != "\t")
|
||||
return content;
|
||||
let col = countColumn(content, 4, blank);
|
||||
let space = "";
|
||||
for (let i = col; i > 0;) {
|
||||
if (i >= 4) {
|
||||
space += "\t";
|
||||
i -= 4;
|
||||
}
|
||||
else {
|
||||
space += " ";
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return space + content.slice(blank);
|
||||
}
|
||||
/**
|
||||
Returns a command like
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup),
|
||||
allowing further configuration.
|
||||
*/
|
||||
const insertNewlineContinueMarkupCommand = (config = {}) => ({ state, dispatch }) => {
|
||||
let tree = syntaxTree(state), { doc } = state;
|
||||
let dont = null, changes = state.changeByRange(range => {
|
||||
if (!range.empty || !markdownLanguage.isActiveAt(state, range.from, -1) && !markdownLanguage.isActiveAt(state, range.from, 1))
|
||||
return dont = { range };
|
||||
let pos = range.from, line = doc.lineAt(pos);
|
||||
let context = getContext(tree.resolveInner(pos, -1), doc);
|
||||
while (context.length && context[context.length - 1].from > pos - line.from)
|
||||
context.pop();
|
||||
if (!context.length)
|
||||
return dont = { range };
|
||||
let inner = context[context.length - 1];
|
||||
if (inner.to - inner.spaceAfter.length > pos - line.from)
|
||||
return dont = { range };
|
||||
let emptyLine = pos >= (inner.to - inner.spaceAfter.length) && !/\S/.test(line.text.slice(inner.to));
|
||||
// Empty line in list
|
||||
if (inner.item && emptyLine) {
|
||||
let first = inner.node.firstChild, second = inner.node.getChild("ListItem", "ListItem");
|
||||
// Not second item or blank line before: delete a level of markup
|
||||
if (first.to >= pos || second && second.to < pos ||
|
||||
line.from > 0 && !/[^\s>]/.test(doc.lineAt(line.from - 1).text) ||
|
||||
config.nonTightLists === false) {
|
||||
let next = context.length > 1 ? context[context.length - 2] : null;
|
||||
let delTo, insert = "";
|
||||
if (next && next.item) { // Re-add marker for the list at the next level
|
||||
delTo = line.from + next.from;
|
||||
insert = next.marker(doc, 1);
|
||||
}
|
||||
else {
|
||||
delTo = line.from + (next ? next.to : 0);
|
||||
}
|
||||
let changes = [{ from: delTo, to: pos, insert }];
|
||||
if (inner.node.name == "OrderedList")
|
||||
renumberList(inner.item, doc, changes, -2);
|
||||
if (next && next.node.name == "OrderedList")
|
||||
renumberList(next.item, doc, changes);
|
||||
return { range: EditorSelection.cursor(delTo + insert.length), changes };
|
||||
}
|
||||
else { // Move second item down, making tight two-item list non-tight
|
||||
let insert = blankLine(context, state, line);
|
||||
return { range: EditorSelection.cursor(pos + insert.length + 1),
|
||||
changes: { from: line.from, insert: insert + state.lineBreak } };
|
||||
}
|
||||
}
|
||||
if (inner.node.name == "Blockquote" && emptyLine && line.from) {
|
||||
let prevLine = doc.lineAt(line.from - 1), quoted = />\s*$/.exec(prevLine.text);
|
||||
// Two aligned empty quoted lines in a row
|
||||
if (quoted && quoted.index == inner.from) {
|
||||
let changes = state.changes([{ from: prevLine.from + quoted.index, to: prevLine.to },
|
||||
{ from: line.from + inner.from, to: line.to }]);
|
||||
return { range: range.map(changes), changes };
|
||||
}
|
||||
}
|
||||
let changes = [];
|
||||
if (inner.node.name == "OrderedList")
|
||||
renumberList(inner.item, doc, changes);
|
||||
let continued = inner.item && inner.item.from < line.from;
|
||||
let insert = "";
|
||||
// If not dedented
|
||||
if (!continued || /^[\s\d.)\-+*>]*/.exec(line.text)[0].length >= inner.to) {
|
||||
for (let i = 0, e = context.length - 1; i <= e; i++) {
|
||||
insert += i == e && !continued ? context[i].marker(doc, 1)
|
||||
: context[i].blank(i < e ? countColumn(line.text, 4, context[i + 1].from) - insert.length : null);
|
||||
}
|
||||
}
|
||||
let from = pos;
|
||||
while (from > line.from && /\s/.test(line.text.charAt(from - line.from - 1)))
|
||||
from--;
|
||||
insert = normalizeIndent(insert, state);
|
||||
if (nonTightList(inner.node, state.doc))
|
||||
insert = blankLine(context, state, line) + state.lineBreak + insert;
|
||||
changes.push({ from, to: pos, insert: state.lineBreak + insert });
|
||||
return { range: EditorSelection.cursor(from + insert.length + 1), changes };
|
||||
});
|
||||
if (dont)
|
||||
return false;
|
||||
dispatch(state.update(changes, { scrollIntoView: true, userEvent: "input" }));
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
This command, when invoked in Markdown context with cursor
|
||||
selection(s), will create a new line with the markup for
|
||||
blockquotes and lists that were active on the old line. If the
|
||||
cursor was directly after the end of the markup for the old line,
|
||||
trailing whitespace and list markers are removed from that line.
|
||||
|
||||
The command does nothing in non-Markdown context, so it should
|
||||
not be used as the only binding for Enter (even in a Markdown
|
||||
document, HTML and code regions might use a different language).
|
||||
*/
|
||||
const insertNewlineContinueMarkup = /*@__PURE__*/insertNewlineContinueMarkupCommand();
|
||||
function isMark(node) {
|
||||
return node.name == "QuoteMark" || node.name == "ListMark";
|
||||
}
|
||||
function nonTightList(node, doc) {
|
||||
if (node.name != "OrderedList" && node.name != "BulletList")
|
||||
return false;
|
||||
let first = node.firstChild, second = node.getChild("ListItem", "ListItem");
|
||||
if (!second)
|
||||
return false;
|
||||
let line1 = doc.lineAt(first.to), line2 = doc.lineAt(second.from);
|
||||
let empty = /^[\s>]*$/.test(line1.text);
|
||||
return line1.number + (empty ? 0 : 1) < line2.number;
|
||||
}
|
||||
function blankLine(context, state, line) {
|
||||
let insert = "";
|
||||
for (let i = 0, e = context.length - 2; i <= e; i++) {
|
||||
insert += context[i].blank(i < e
|
||||
? countColumn(line.text, 4, context[i + 1].from) - insert.length
|
||||
: null, i < e);
|
||||
}
|
||||
return normalizeIndent(insert, state);
|
||||
}
|
||||
function contextNodeForDelete(tree, pos) {
|
||||
let node = tree.resolveInner(pos, -1), scan = pos;
|
||||
if (isMark(node)) {
|
||||
scan = node.from;
|
||||
node = node.parent;
|
||||
}
|
||||
for (let prev; prev = node.childBefore(scan);) {
|
||||
if (isMark(prev)) {
|
||||
scan = prev.from;
|
||||
}
|
||||
else if (prev.name == "OrderedList" || prev.name == "BulletList") {
|
||||
node = prev.lastChild;
|
||||
scan = node.to;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
This command will, when invoked in a Markdown context with the
|
||||
cursor directly after list or blockquote markup, delete one level
|
||||
of markup. When the markup is for a list, it will be replaced by
|
||||
spaces on the first invocation (a further invocation will delete
|
||||
the spaces), to make it easy to continue a list.
|
||||
|
||||
When not after Markdown block markup, this command will return
|
||||
false, so it is intended to be bound alongside other deletion
|
||||
commands, with a higher precedence than the more generic commands.
|
||||
*/
|
||||
const deleteMarkupBackward = ({ state, dispatch }) => {
|
||||
let tree = syntaxTree(state);
|
||||
let dont = null, changes = state.changeByRange(range => {
|
||||
let pos = range.from, { doc } = state;
|
||||
if (range.empty && markdownLanguage.isActiveAt(state, range.from)) {
|
||||
let line = doc.lineAt(pos);
|
||||
let context = getContext(contextNodeForDelete(tree, pos), doc);
|
||||
if (context.length) {
|
||||
let inner = context[context.length - 1];
|
||||
let spaceEnd = inner.to - inner.spaceAfter.length + (inner.spaceAfter ? 1 : 0);
|
||||
// Delete extra trailing space after markup
|
||||
if (pos - line.from > spaceEnd && !/\S/.test(line.text.slice(spaceEnd, pos - line.from)))
|
||||
return { range: EditorSelection.cursor(line.from + spaceEnd),
|
||||
changes: { from: line.from + spaceEnd, to: pos } };
|
||||
if (pos - line.from == spaceEnd &&
|
||||
// Only apply this if we're on the line that has the
|
||||
// construct's syntax, or there's only indentation in the
|
||||
// target range
|
||||
(!inner.item || line.from <= inner.item.from || !/\S/.test(line.text.slice(0, inner.to)))) {
|
||||
let start = line.from + inner.from;
|
||||
// Replace a list item marker with blank space
|
||||
if (inner.item && inner.node.from < inner.item.from && /\S/.test(line.text.slice(inner.from, inner.to))) {
|
||||
let insert = inner.blank(countColumn(line.text, 4, inner.to) - countColumn(line.text, 4, inner.from));
|
||||
if (start == line.from)
|
||||
insert = normalizeIndent(insert, state);
|
||||
return { range: EditorSelection.cursor(start + insert.length),
|
||||
changes: { from: start, to: line.from + inner.to, insert } };
|
||||
}
|
||||
// Delete one level of indentation
|
||||
if (start < pos)
|
||||
return { range: EditorSelection.cursor(start), changes: { from: start, to: pos } };
|
||||
}
|
||||
}
|
||||
}
|
||||
return dont = { range };
|
||||
});
|
||||
if (dont)
|
||||
return false;
|
||||
dispatch(state.update(changes, { scrollIntoView: true, userEvent: "delete" }));
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
A small keymap with Markdown-specific bindings. Binds Enter to
|
||||
[`insertNewlineContinueMarkup`](https://codemirror.net/6/docs/ref/#lang-markdown.insertNewlineContinueMarkup)
|
||||
and Backspace to
|
||||
[`deleteMarkupBackward`](https://codemirror.net/6/docs/ref/#lang-markdown.deleteMarkupBackward).
|
||||
*/
|
||||
const markdownKeymap = [
|
||||
{ key: "Enter", run: insertNewlineContinueMarkup },
|
||||
{ key: "Backspace", run: deleteMarkupBackward }
|
||||
];
|
||||
const htmlNoMatch = /*@__PURE__*/html({ matchClosingTags: false });
|
||||
/**
|
||||
Markdown language support.
|
||||
*/
|
||||
function markdown(config = {}) {
|
||||
let { codeLanguages, defaultCodeLanguage, addKeymap = true, base: { parser } = commonmarkLanguage, completeHTMLTags = true, pasteURLAsLink: pasteURL = true, htmlTagLanguage = htmlNoMatch } = config;
|
||||
if (!(parser instanceof MarkdownParser))
|
||||
throw new RangeError("Base parser provided to `markdown` should be a Markdown parser");
|
||||
let extensions = config.extensions ? [config.extensions] : [];
|
||||
let support = [htmlTagLanguage.support, headerIndent], defaultCode;
|
||||
if (pasteURL)
|
||||
support.push(pasteURLAsLink);
|
||||
if (defaultCodeLanguage instanceof LanguageSupport) {
|
||||
support.push(defaultCodeLanguage.support);
|
||||
defaultCode = defaultCodeLanguage.language;
|
||||
}
|
||||
else if (defaultCodeLanguage) {
|
||||
defaultCode = defaultCodeLanguage;
|
||||
}
|
||||
let codeParser = codeLanguages || defaultCode ? getCodeParser(codeLanguages, defaultCode) : undefined;
|
||||
extensions.push(parseCode({ codeParser, htmlParser: htmlTagLanguage.language.parser }));
|
||||
if (addKeymap)
|
||||
support.push(Prec.high(keymap.of(markdownKeymap)));
|
||||
let lang = mkLang(parser.configure(extensions));
|
||||
if (completeHTMLTags)
|
||||
support.push(lang.data.of({ autocomplete: htmlTagCompletion }));
|
||||
return new LanguageSupport(lang, support);
|
||||
}
|
||||
function htmlTagCompletion(context) {
|
||||
let { state, pos } = context, m = /<[:\-\.\w\u00b7-\uffff]*$/.exec(state.sliceDoc(pos - 25, pos));
|
||||
if (!m)
|
||||
return null;
|
||||
let tree = syntaxTree(state).resolveInner(pos, -1);
|
||||
while (tree && !tree.type.isTop) {
|
||||
if (tree.name == "CodeBlock" || tree.name == "FencedCode" || tree.name == "ProcessingInstructionBlock" ||
|
||||
tree.name == "CommentBlock" || tree.name == "Link" || tree.name == "Image")
|
||||
return null;
|
||||
tree = tree.parent;
|
||||
}
|
||||
return {
|
||||
from: pos - m[0].length, to: pos,
|
||||
options: htmlTagCompletions(),
|
||||
validFor: /^<[:\-\.\w\u00b7-\uffff]*$/
|
||||
};
|
||||
}
|
||||
let _tagCompletions = null;
|
||||
function htmlTagCompletions() {
|
||||
if (_tagCompletions)
|
||||
return _tagCompletions;
|
||||
let result = htmlCompletionSource(new CompletionContext(EditorState.create({ extensions: htmlNoMatch }), 0, true));
|
||||
return _tagCompletions = result ? result.options : [];
|
||||
}
|
||||
const nonPlainText = /code|horizontalrule|html|link|comment|processing|escape|entity|image|mark|url/i;
|
||||
/**
|
||||
An extension that intercepts pastes when the pasted content looks
|
||||
like a URL and the selection is non-empty and selects regular
|
||||
text, making the selection a link with the pasted URL as target.
|
||||
*/
|
||||
const pasteURLAsLink = /*@__PURE__*/EditorView.domEventHandlers({
|
||||
paste: (event, view) => {
|
||||
var _a;
|
||||
let { main } = view.state.selection;
|
||||
if (main.empty)
|
||||
return false;
|
||||
let link = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/plain");
|
||||
if (!link || !/^(https?:\/\/|mailto:|xmpp:|www\.)/.test(link))
|
||||
return false;
|
||||
if (/^www\./.test(link))
|
||||
link = "https://" + link;
|
||||
if (!markdownLanguage.isActiveAt(view.state, main.from, 1))
|
||||
return false;
|
||||
let tree = syntaxTree(view.state), crossesNode = false;
|
||||
// Verify that no nodes are started/ended between the selection
|
||||
// points, and we're not inside any non-plain-text construct.
|
||||
tree.iterate({
|
||||
from: main.from, to: main.to,
|
||||
enter: node => { if (node.from > main.from || nonPlainText.test(node.name))
|
||||
crossesNode = true; },
|
||||
leave: node => { if (node.to < main.to)
|
||||
crossesNode = true; }
|
||||
});
|
||||
if (crossesNode)
|
||||
return false;
|
||||
view.dispatch({
|
||||
changes: [{ from: main.from, insert: "[" }, { from: main.to, insert: `](${link})` }],
|
||||
userEvent: "input.paste",
|
||||
scrollIntoView: true
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
export { commonmarkLanguage, deleteMarkupBackward, insertNewlineContinueMarkup, insertNewlineContinueMarkupCommand, markdown, markdownKeymap, markdownLanguage, pasteURLAsLink };
|
||||
44
frontend/node_modules/@codemirror/lang-markdown/package.json
generated
vendored
Normal file
44
frontend/node_modules/@codemirror/lang-markdown/package.json
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@codemirror/lang-markdown",
|
||||
"version": "6.5.0",
|
||||
"description": "Markdown language support for the CodeMirror code editor",
|
||||
"scripts": {
|
||||
"test": "cm-runtests",
|
||||
"prepare": "cm-buildhelper src/index.ts"
|
||||
},
|
||||
"keywords": [
|
||||
"editor",
|
||||
"code"
|
||||
],
|
||||
"author": {
|
||||
"name": "Marijn Haverbeke",
|
||||
"email": "marijn@haverbeke.berlin",
|
||||
"url": "http://marijnhaverbeke.nl"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
"exports": {
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"types": "dist/index.d.ts",
|
||||
"module": "dist/index.js",
|
||||
"sideEffects": false,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.7.1",
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/language": "^6.3.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/markdown": "^1.0.0",
|
||||
"@lezer/common": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codemirror/buildhelper": "^1.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codemirror/lang-markdown.git"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user