diff --git a/markdown-it-plugins/.editorconfig b/markdown-it-plugins/.editorconfig
new file mode 100644
index 000000000..5afb4a0da
--- /dev/null
+++ b/markdown-it-plugins/.editorconfig
@@ -0,0 +1,208 @@
+# SPDX-FileCopyrightText: 2020 The HedgeDoc developers (see AUTHORS file)
+#
+# SPDX-License-Identifier: CC0-1.0
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+max_line_length = 120
+tab_width = 4
+trim_trailing_whitespace = true
+ij_continuation_indent_size = 8
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = false
+ij_smart_tabs = false
+ij_wrap_on_typing = false
+
+[{*.ats,*.ts,*.tsx}]
+indent_size = 2
+tab_width = 2
+ij_continuation_indent_size = 2
+ij_typescript_align_imports = false
+ij_typescript_align_multiline_array_initializer_expression = false
+ij_typescript_align_multiline_binary_operation = false
+ij_typescript_align_multiline_chained_methods = false
+ij_typescript_align_multiline_extends_list = false
+ij_typescript_align_multiline_for = true
+ij_typescript_align_multiline_parameters = true
+ij_typescript_align_multiline_parameters_in_calls = false
+ij_typescript_align_multiline_ternary_operation = false
+ij_typescript_align_object_properties = 0
+ij_typescript_align_union_types = false
+ij_typescript_align_var_statements = 0
+ij_typescript_array_initializer_new_line_after_left_brace = false
+ij_typescript_array_initializer_right_brace_on_new_line = false
+ij_typescript_array_initializer_wrap = off
+ij_typescript_assignment_wrap = off
+ij_typescript_binary_operation_sign_on_next_line = false
+ij_typescript_binary_operation_wrap = off
+ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
+ij_typescript_blank_lines_after_imports = 1
+ij_typescript_blank_lines_around_class = 1
+ij_typescript_blank_lines_around_field = 0
+ij_typescript_blank_lines_around_field_in_interface = 0
+ij_typescript_blank_lines_around_function = 1
+ij_typescript_blank_lines_around_method = 1
+ij_typescript_blank_lines_around_method_in_interface = 1
+ij_typescript_block_brace_style = end_of_line
+ij_typescript_call_parameters_new_line_after_left_paren = false
+ij_typescript_call_parameters_right_paren_on_new_line = false
+ij_typescript_call_parameters_wrap = off
+ij_typescript_catch_on_new_line = false
+ij_typescript_chained_call_dot_on_new_line = true
+ij_typescript_class_brace_style = end_of_line
+ij_typescript_comma_on_new_line = false
+ij_typescript_do_while_brace_force = never
+ij_typescript_else_on_new_line = false
+ij_typescript_enforce_trailing_comma = keep
+ij_typescript_extends_keyword_wrap = off
+ij_typescript_extends_list_wrap = off
+ij_typescript_field_prefix = _
+ij_typescript_file_name_style = relaxed
+ij_typescript_finally_on_new_line = false
+ij_typescript_for_brace_force = never
+ij_typescript_for_statement_new_line_after_left_paren = false
+ij_typescript_for_statement_right_paren_on_new_line = false
+ij_typescript_for_statement_wrap = off
+ij_typescript_force_quote_style = false
+ij_typescript_force_semicolon_style = true
+ij_typescript_function_expression_brace_style = end_of_line
+ij_typescript_if_brace_force = never
+ij_typescript_import_merge_members = global
+ij_typescript_import_prefer_absolute_path = global
+ij_typescript_import_sort_members = true
+ij_typescript_import_sort_module_name = true
+ij_typescript_import_use_node_resolution = true
+ij_typescript_imports_wrap = on_every_item
+ij_typescript_indent_case_from_switch = true
+ij_typescript_indent_chained_calls = false
+ij_typescript_indent_package_children = 0
+ij_typescript_jsdoc_include_types = false
+ij_typescript_jsx_attribute_value = braces
+ij_typescript_keep_blank_lines_in_code = 1
+ij_typescript_keep_first_column_comment = true
+ij_typescript_keep_indents_on_empty_lines = false
+ij_typescript_keep_line_breaks = true
+ij_typescript_keep_simple_blocks_in_one_line = false
+ij_typescript_keep_simple_methods_in_one_line = false
+ij_typescript_line_comment_add_space = true
+ij_typescript_line_comment_at_first_column = false
+ij_typescript_method_brace_style = end_of_line
+ij_typescript_method_call_chain_wrap = off
+ij_typescript_method_parameters_new_line_after_left_paren = false
+ij_typescript_method_parameters_right_paren_on_new_line = false
+ij_typescript_method_parameters_wrap = off
+ij_typescript_object_literal_wrap = on_every_item
+ij_typescript_parentheses_expression_new_line_after_left_paren = false
+ij_typescript_parentheses_expression_right_paren_on_new_line = false
+ij_typescript_place_assignment_sign_on_next_line = false
+ij_typescript_prefer_as_type_cast = false
+ij_typescript_prefer_explicit_types_function_expression_returns = false
+ij_typescript_prefer_explicit_types_function_returns = false
+ij_typescript_prefer_explicit_types_vars_fields = false
+ij_typescript_prefer_parameters_wrap = false
+ij_typescript_reformat_c_style_comments = false
+ij_typescript_space_after_colon = true
+ij_typescript_space_after_comma = true
+ij_typescript_space_after_dots_in_rest_parameter = false
+ij_typescript_space_after_generator_mult = true
+ij_typescript_space_after_property_colon = true
+ij_typescript_space_after_quest = true
+ij_typescript_space_after_type_colon = true
+ij_typescript_space_after_unary_not = false
+ij_typescript_space_before_async_arrow_lparen = true
+ij_typescript_space_before_catch_keyword = true
+ij_typescript_space_before_catch_left_brace = true
+ij_typescript_space_before_catch_parentheses = true
+ij_typescript_space_before_class_lbrace = true
+ij_typescript_space_before_class_left_brace = true
+ij_typescript_space_before_colon = true
+ij_typescript_space_before_comma = false
+ij_typescript_space_before_do_left_brace = true
+ij_typescript_space_before_else_keyword = true
+ij_typescript_space_before_else_left_brace = true
+ij_typescript_space_before_finally_keyword = true
+ij_typescript_space_before_finally_left_brace = true
+ij_typescript_space_before_for_left_brace = true
+ij_typescript_space_before_for_parentheses = true
+ij_typescript_space_before_for_semicolon = false
+ij_typescript_space_before_function_left_parenth = true
+ij_typescript_space_before_generator_mult = false
+ij_typescript_space_before_if_left_brace = true
+ij_typescript_space_before_if_parentheses = true
+ij_typescript_space_before_method_call_parentheses = false
+ij_typescript_space_before_method_left_brace = true
+ij_typescript_space_before_method_parentheses = true
+ij_typescript_space_before_property_colon = false
+ij_typescript_space_before_quest = true
+ij_typescript_space_before_switch_left_brace = true
+ij_typescript_space_before_switch_parentheses = true
+ij_typescript_space_before_try_left_brace = true
+ij_typescript_space_before_type_colon = false
+ij_typescript_space_before_unary_not = false
+ij_typescript_space_before_while_keyword = true
+ij_typescript_space_before_while_left_brace = true
+ij_typescript_space_before_while_parentheses = true
+ij_typescript_spaces_around_additive_operators = true
+ij_typescript_spaces_around_arrow_function_operator = true
+ij_typescript_spaces_around_assignment_operators = true
+ij_typescript_spaces_around_bitwise_operators = true
+ij_typescript_spaces_around_equality_operators = true
+ij_typescript_spaces_around_logical_operators = true
+ij_typescript_spaces_around_multiplicative_operators = true
+ij_typescript_spaces_around_relational_operators = true
+ij_typescript_spaces_around_shift_operators = true
+ij_typescript_spaces_around_unary_operator = false
+ij_typescript_spaces_within_array_initializer_brackets = false
+ij_typescript_spaces_within_brackets = false
+ij_typescript_spaces_within_catch_parentheses = false
+ij_typescript_spaces_within_for_parentheses = false
+ij_typescript_spaces_within_if_parentheses = false
+ij_typescript_spaces_within_imports = true
+ij_typescript_spaces_within_interpolation_expressions = false
+ij_typescript_spaces_within_method_call_parentheses = false
+ij_typescript_spaces_within_method_parentheses = false
+ij_typescript_spaces_within_object_literal_braces = true
+ij_typescript_spaces_within_object_type_braces = true
+ij_typescript_spaces_within_parentheses = false
+ij_typescript_spaces_within_switch_parentheses = false
+ij_typescript_spaces_within_type_assertion = false
+ij_typescript_spaces_within_union_types = true
+ij_typescript_spaces_within_while_parentheses = false
+ij_typescript_special_else_if_treatment = true
+ij_typescript_ternary_operation_signs_on_next_line = false
+ij_typescript_ternary_operation_wrap = off
+ij_typescript_union_types_wrap = on_every_item
+ij_typescript_use_chained_calls_group_indents = false
+ij_typescript_use_double_quotes = false
+ij_typescript_use_explicit_js_extension = global
+ij_typescript_use_path_mapping = always
+ij_typescript_use_public_modifier = false
+ij_typescript_use_semicolon_after_statement = false
+ij_typescript_var_declaration_wrap = normal
+ij_typescript_while_brace_force = never
+ij_typescript_while_on_new_line = false
+ij_typescript_wrap_comments = false
+
+[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
+indent_size = 2
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = true
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+
+[{*.yaml,*.yml}]
+indent_size = 2
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
+
diff --git a/markdown-it-plugins/.eslintrc.json b/markdown-it-plugins/.eslintrc.json
new file mode 100644
index 000000000..6674e87cc
--- /dev/null
+++ b/markdown-it-plugins/.eslintrc.json
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2020 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: CC0-1.0
+ */
+{
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "project": [
+ "./tsconfig.test.json"
+ ]
+ },
+ "plugins": [
+ "@typescript-eslint",
+ "jest",
+ "prettier"
+ ],
+ "env": {
+ "jest": true,
+ "jest/globals": true
+ },
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/eslint-recommended",
+ "plugin:@typescript-eslint/recommended",
+ "prettier"
+ ],
+ "rules": {
+ "prettier/prettier": "error",
+ "jest/no-disabled-tests": "warn",
+ "jest/no-focused-tests": "error",
+ "jest/no-identical-title": "error",
+ "jest/prefer-to-have-length": "warn",
+ "jest/valid-expect": "error"
+ }
+}
diff --git a/markdown-it-plugins/.gitignore b/markdown-it-plugins/.gitignore
new file mode 100644
index 000000000..849ddff3b
--- /dev/null
+++ b/markdown-it-plugins/.gitignore
@@ -0,0 +1 @@
+dist/
diff --git a/markdown-it-plugins/.prettierrc.json b/markdown-it-plugins/.prettierrc.json
new file mode 100644
index 000000000..3421bdfba
--- /dev/null
+++ b/markdown-it-plugins/.prettierrc.json
@@ -0,0 +1,11 @@
+{
+ "parser": "typescript",
+ "singleQuote": true,
+ "jsxSingleQuote": true,
+ "semi": false,
+ "tabWidth": 2,
+ "trailingComma": "none",
+ "bracketSpacing": true,
+ "bracketSameLine": true,
+ "arrowParens": "always"
+}
diff --git a/markdown-it-plugins/.prettierrc.json.license b/markdown-it-plugins/.prettierrc.json.license
new file mode 100644
index 000000000..c223474fb
--- /dev/null
+++ b/markdown-it-plugins/.prettierrc.json.license
@@ -0,0 +1,3 @@
+SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
+
+SPDX-License-Identifier: CC0-1.0
diff --git a/markdown-it-plugins/.renovaterc.json b/markdown-it-plugins/.renovaterc.json
new file mode 100644
index 000000000..b3ef25258
--- /dev/null
+++ b/markdown-it-plugins/.renovaterc.json
@@ -0,0 +1,49 @@
+{
+ "extends": [
+ "config:base",
+ ":gitSignOff",
+ ":preserveSemverRanges",
+ ":prHourlyLimitNone",
+ ":dependencyDashboard",
+ ":maintainLockFilesWeekly"
+ ],
+ "prHourlyLimit": 0,
+ "schedule": [
+ "on Saturday"
+ ],
+ "labels": [
+ "dependencies"
+ ],
+ "packageRules": [
+ {
+ "extends": "packages:linters",
+ "groupName": "linters"
+ },
+ {
+ "extends": "monorepo:typescript-eslint",
+ "groupName": "typescript-eslint monorepo"
+ },
+ {
+ "extends": "monorepo:react",
+ "groupName": "react monorepo"
+ },
+ {
+ "extends": "monorepo:reactrouter",
+ "groupName": "reactrouter monorepo"
+ },
+ {
+ "groupName": "definitelyTyped",
+ "matchPackagePatterns": [
+ "^@types/"
+ ]
+ },
+ {
+ "groupName": "Jest",
+ "matchPackageNames": [
+ "jest",
+ "ts-jest",
+ "@types/jest"
+ ]
+ }
+ ]
+}
diff --git a/markdown-it-plugins/.renovaterc.json.license b/markdown-it-plugins/.renovaterc.json.license
new file mode 100644
index 000000000..a2952f013
--- /dev/null
+++ b/markdown-it-plugins/.renovaterc.json.license
@@ -0,0 +1,3 @@
+SPDX-FileCopyrightText: 2020 The HedgeDoc developers (see AUTHORS file)
+
+SPDX-License-Identifier: CC0-1.0
diff --git a/markdown-it-plugins/LICENSE b/markdown-it-plugins/LICENSE
new file mode 100644
index 000000000..d16914bf4
--- /dev/null
+++ b/markdown-it-plugins/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 The HedgeDoc developers (see AUTHORS file)
+
+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.
diff --git a/markdown-it-plugins/README.md b/markdown-it-plugins/README.md
new file mode 100644
index 000000000..e1711d2b7
--- /dev/null
+++ b/markdown-it-plugins/README.md
@@ -0,0 +1,143 @@
+
+
+# Markdown-It plugins
+
+This repository contains plugins for [Markdown-It](https://github.com/markdown-it/markdown-it) that are used by HedgeDoc.
+All these plugins are (re)created in typescript.
+
+## License
+Everything is licensed under MIT
+
+## Usage
+Install the lib using `yarn install @hedgedoc/markdown-it-plugins` or `npm i @hedgedoc/markdown-it-plugins`
+
+## Development
+If you want to contribute to this lib then:
+- Clone this repository
+- Install the dependencies using `yarn install`. Don't use `npm`!
+- Make your changes
+- Make sure that your changes are covered by tests. Use `yarn test` to run all tests
+- Make sure that your code follows the code style. Use `yarn lint` to check the style
+- Commit your changes (please use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)) and create a pull request
+
+## markdown-it-image-size
+A markdown-it plugin for size-specified image markups. This plugin overloads the original image renderer of markdown-it.
+> This is a typescript port of https://github.com/tatsy/markdown-it-imsize without the local file system support.
+
+### Usage
+
+#### Enable plugin
+
+```ts
+import MarkdownIt from 'markdown-it'
+import { imageSize } from '@hedgedoc/markdown-it-plugins'
+
+const md = new MarkdownIt({
+ html: true,
+ linkify: true,
+ typography: true
+}).use(imageSize);
+```
+
+#### Example
+
+```md
+
+```
+
+is interpreted as
+
+```html
+
+```
+
+## markdown-it-better-task-lists
+
+A markdown-it plugin that renders GitHub-style task-lists. It builds [task/todo lists](https://github.com/blog/1825-task-lists-in-all-markdown-documents) out of Markdown lists with items starting with `[ ]` or `[x]`.
+
+This is a typescript port of [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists).
+
+### Why is this useful?
+
+When you have markdown documentation with checklists, rendering HTML checkboxes
+out of the list items looks nicer than the raw square brackets.
+
+### Usage
+
+Use it the same as a normal markdown-it plugin:
+
+```ts
+import MarkdownIt from 'markdown-it'
+import { taskLists } from '@hedgedoc/markdown-it-plugins'
+
+const parser = new MarkdownIt().use(taskLists)
+
+const result = parser.render(`
+- [ ] Open task
+- [x] Done task
+- Not a task
+`) // markdown string containing task list items
+```
+
+The rendered checkboxes are disabled; to change this, set `enabled` property of the
+plugin options to `true`:
+
+```ts
+const parser = new MarkdownIt().use(taskLists, { enabled: true })
+```
+
+If you need to know which line in the markdown document the generated checkbox comes
+set the `lineNumber` property of the plugin options to `true` for the
+`` tag to be created with a data-line attribute containing the line number:
+
+```ts
+const parser = new MarkdownIt().use(taskLists, { lineNumber: true })
+```
+
+If you'd like to wrap the rendered list items in a `'
+ }
+
+ md.renderer.rules.taskListItemLabel_open = (tokens: Token[]) => {
+ const token = tokens[0]
+ const id = token.attrGet('id')
+ return `