├── static ├── .gitkeep ├── logo-96px.png └── logo-small.png ├── src ├── renderer │ ├── assets │ │ ├── .gitkeep │ │ ├── images │ │ │ └── logo.png │ │ └── icons │ │ │ ├── searchIcons │ │ │ ├── iconRegex.svg │ │ │ └── iconWord.svg │ │ │ ├── toc.svg │ │ │ ├── pref_fontsize.svg │ │ │ ├── close.svg │ │ │ ├── pref_spellcheck.svg │ │ │ ├── search.svg │ │ │ ├── pref_image.svg │ │ │ ├── files.svg │ │ │ ├── pref_lineheight.svg │ │ │ ├── pref_email.svg │ │ │ └── markdown.svg │ ├── bus │ │ └── index.js │ ├── services │ │ ├── index.js │ │ └── notification │ │ │ └── index.html │ ├── prefComponents │ │ ├── theme │ │ │ ├── theme.md │ │ │ └── config.js │ │ ├── common │ │ │ └── separator │ │ │ │ └── index.vue │ │ ├── image │ │ │ ├── config.js │ │ │ └── components │ │ │ │ └── uploader │ │ │ │ └── legalNoticesCheckbox.vue │ │ └── general │ │ │ └── config.js │ ├── axios │ │ └── index.js │ ├── codeMirror │ │ └── index.css │ ├── util │ │ ├── markdownToHtml.js │ │ ├── day.js │ │ ├── themeColor.js │ │ ├── clipboard.js │ │ ├── dompurify.js │ │ └── listToTree.js │ ├── jsconfig.json │ ├── store │ │ ├── tweet.js │ │ ├── notification.js │ │ └── listenForMain.js │ ├── components │ │ └── sideBar │ │ │ ├── help.js │ │ │ └── icon.vue │ ├── contextMenu │ │ ├── tabs │ │ │ ├── actions.js │ │ │ └── index.js │ │ └── sideBar │ │ │ ├── index.js │ │ │ └── actions.js │ ├── config.js │ ├── commands │ │ └── utils.js │ └── node │ │ └── paths.js ├── muya │ ├── README.md │ ├── lib │ │ ├── assets │ │ │ ├── pngicon │ │ │ │ ├── code │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── copy │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── html │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── math │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── chart │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── delete │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── image │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── mermaid │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── quote │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── unlink │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── warning │ │ │ │ │ └── 2.png │ │ │ │ ├── flowchart │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── footnote │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── heading_1 │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── heading_2 │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── heading_3 │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── heading_4 │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── heading_5 │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── heading_6 │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── highlight │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── imageEdit │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── link_jump │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── new_table │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── paragraph │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── plantuml │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── sequence │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── table │ │ │ │ │ ├── table.png │ │ │ │ │ ├── table@2x.png │ │ │ │ │ └── table@3x.png │ │ │ │ ├── todolist │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── turninto │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── algin_center │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── algin_left │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── algin_right │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── bullet_list │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_clear │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_image │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_link │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_math │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── front_matter │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── image_delete │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── image_fail │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── inline_image │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── order_list │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── quote_block │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── table_delete │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_strike │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_strong │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_emphasis │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ ├── format_underline │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ │ └── horizontal_line │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ └── 3.png │ │ │ ├── icons │ │ │ │ ├── image_dark.png │ │ │ │ ├── image_light.png │ │ │ │ ├── image_dark_fail.png │ │ │ │ ├── image_light_fail.png │ │ │ │ ├── quote.svg │ │ │ │ ├── format_emphasis.svg │ │ │ │ ├── horizontal_line.svg │ │ │ │ ├── bullet_list.svg │ │ │ │ ├── add_close.svg │ │ │ │ ├── folder.svg │ │ │ │ ├── header_4.svg │ │ │ │ ├── header_1.svg │ │ │ │ ├── mermaid.svg │ │ │ │ ├── html.svg │ │ │ │ ├── paragraph.svg │ │ │ │ ├── enter.svg │ │ │ │ ├── todolist.svg │ │ │ │ ├── image.svg │ │ │ │ ├── table.svg │ │ │ │ ├── format_underline.svg │ │ │ │ ├── sequence.svg │ │ │ │ ├── new_table.svg │ │ │ │ ├── table_add.svg │ │ │ │ ├── copy.svg │ │ │ │ ├── align_center.svg │ │ │ │ ├── align_left.svg │ │ │ │ ├── align_right.svg │ │ │ │ ├── format_clear.svg │ │ │ │ ├── format_link.svg │ │ │ │ ├── delete.svg │ │ │ │ ├── header_2.svg │ │ │ │ ├── format_image.svg │ │ │ │ ├── format_strong.svg │ │ │ │ └── format_code.svg │ │ │ └── styles │ │ │ │ ├── danielbd.woff │ │ │ │ ├── danielbd.woff2 │ │ │ │ └── sequence-diagram.css │ │ ├── utils │ │ │ ├── dompurify.js │ │ │ ├── random.js │ │ │ ├── getParentCheckBox.js │ │ │ ├── cumputeCheckBoxStatus.js │ │ │ ├── hash.js │ │ │ ├── getLinkInfo.js │ │ │ ├── markdownFile.js │ │ │ ├── domManipulate.js │ │ │ ├── url.js │ │ │ └── getImageInfo.js │ │ ├── ui │ │ │ ├── imagePicker │ │ │ │ └── index.css │ │ │ ├── linkTools │ │ │ │ └── config.js │ │ │ ├── transformer │ │ │ │ └── index.css │ │ │ ├── fileIcons │ │ │ │ └── index.js │ │ │ ├── tableTools │ │ │ │ ├── config.js │ │ │ │ └── index.css │ │ │ ├── tooltip │ │ │ │ └── index.css │ │ │ ├── imageToolbar │ │ │ │ └── config.js │ │ │ ├── baseFloat │ │ │ │ └── index.css │ │ │ └── footnoteTool │ │ │ │ └── index.css │ │ ├── parser │ │ │ ├── render │ │ │ │ ├── renderBlock │ │ │ │ │ ├── renderFootnoteJump.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── renderTableDargBar.js │ │ │ │ │ ├── renderBlock.js │ │ │ │ │ ├── renderCopyButton.js │ │ │ │ │ ├── renderContainerEditIcon.js │ │ │ │ │ └── renderLineNumber.js │ │ │ │ ├── sequence.js │ │ │ │ ├── renderInlines │ │ │ │ │ ├── del.js │ │ │ │ │ ├── em.js │ │ │ │ │ ├── strong.js │ │ │ │ │ ├── text.js │ │ │ │ │ ├── hr.js │ │ │ │ │ ├── multipleMath.js │ │ │ │ │ ├── softLineBreak.js │ │ │ │ │ ├── backlash.js │ │ │ │ │ ├── tailHeader.js │ │ │ │ │ ├── codeFense.js │ │ │ │ │ ├── hardLineBreak.js │ │ │ │ │ ├── htmlEscape.js │ │ │ │ │ ├── autoLinkExtension.js │ │ │ │ │ ├── inlineCode.js │ │ │ │ │ ├── header.js │ │ │ │ │ ├── superSubScript.js │ │ │ │ │ ├── footnoteIdentifier.js │ │ │ │ │ ├── backlashInToken.js │ │ │ │ │ ├── highlight.js │ │ │ │ │ ├── autoLink.js │ │ │ │ │ ├── htmlRuby.js │ │ │ │ │ └── delEmStringFactory.js │ │ │ │ └── snabbdom.js │ │ │ └── marked │ │ │ │ ├── README.md │ │ │ │ ├── slugger.js │ │ │ │ ├── index.js │ │ │ │ ├── options.js │ │ │ │ └── LICENSE │ │ ├── contentState │ │ │ └── tocCtrl.js │ │ ├── eventHandler │ │ │ └── resize.js │ │ └── renderers │ │ │ └── index.js │ ├── themes │ │ └── fonts │ │ │ ├── DejaVuSansMono.ttf │ │ │ ├── DejaVuSansMono-Bold.ttf │ │ │ ├── DejaVuSansMono-Oblique.ttf │ │ │ ├── DejaVuSansMono-BoldOblique.ttf │ │ │ ├── open-sans-v27-latin-ext_latin-300.woff │ │ │ ├── open-sans-v27-latin-ext_latin-600.woff │ │ │ ├── open-sans-v27-latin-ext_latin-700.woff │ │ │ ├── open-sans-v27-latin-ext_latin-italic.woff │ │ │ ├── open-sans-v27-latin-ext_latin-300italic.woff │ │ │ ├── open-sans-v27-latin-ext_latin-600italic.woff │ │ │ ├── open-sans-v27-latin-ext_latin-700italic.woff │ │ │ └── open-sans-v27-latin-ext_latin-regular.woff │ └── package.json ├── main │ ├── menu │ │ ├── actions │ │ │ ├── theme.js │ │ │ ├── help.js │ │ │ ├── index.js │ │ │ └── window.js │ │ └── templates │ │ │ ├── dock.js │ │ │ └── prefEdit.js │ ├── globalSetting.js │ ├── jsconfig.json │ ├── commands │ │ └── file.js │ ├── utils │ │ └── createGitHubIssue.js │ ├── dataCenter │ │ └── schema.json │ ├── index.dev.js │ ├── cli │ │ └── parser.js │ └── app │ │ └── paths.js └── common │ └── keybinding │ └── index.js ├── test ├── unit │ ├── data │ │ ├── .editorconfig │ │ ├── gfm │ │ │ ├── BasicTextFormatting.md │ │ │ ├── Lists.md │ │ │ └── Tables.md │ │ └── common │ │ │ ├── Images.md │ │ │ ├── Escapes.md │ │ │ ├── Links.md │ │ │ ├── CodeBlocks.md │ │ │ ├── Headings.md │ │ │ └── BasicTextFormatting.md │ ├── specs │ │ └── LandingPage.spec.js_disabled │ └── index.js ├── specs │ ├── config.js │ ├── gfm │ │ ├── gfm.0.29.md │ │ └── compare.marked.md │ └── help.js ├── .eslintrc └── e2e │ ├── playwright.config.js │ ├── launch.spec.js │ ├── xss.spec.js │ └── data │ └── xss.md ├── docs ├── doutu.jpg ├── focus.gif ├── source.gif ├── brew-cask.gif ├── marktext.png ├── typewriter.gif ├── sponsor │ ├── readme.png │ └── qordoba.png ├── themeImages │ ├── dark.png │ ├── one-dark.png │ ├── materal-dark.png │ ├── cadmium-light.png │ ├── graphite-light.png │ └── ulysses-light.png ├── assets │ ├── marktext-default.png │ ├── marktext-settings.png │ ├── marktext-export-pdf.png │ ├── marktext-focus-mode.png │ ├── marktext-image-popup.png │ ├── marktext-interface-1.png │ ├── marktext-interface-2.png │ ├── marktext-table-gif.gif │ ├── marktext-table-tools.png │ ├── marktext-emoji-picker.png │ ├── marktext-export-header.png │ ├── marktext-format-popup.png │ ├── marktext-image-viewer.png │ ├── marktext-link-preview.png │ ├── marktext-quick-insert.png │ ├── marktext-line-transformer.png │ ├── marktext-table_drag_drop.png │ ├── marktext-spellchecker-menu.png │ └── marktext-spelling-settings.png ├── dev │ ├── assets │ │ └── marktext-interface.png │ ├── code │ │ └── README.md │ ├── README.md │ └── RELEASE_HOTFIX.md ├── THEMES.md ├── APPLICATION_DATA_DIRECTORY.md ├── PORTABLE.md ├── CLI.md ├── README.md ├── IMAGE_UPLOADER_CONFIGRATION.md ├── KEYBINDINGS.md ├── ENVIRONMENT.md └── EXPORT.md ├── resources ├── icons │ ├── md.icns │ ├── md.ico │ ├── icon.icns │ ├── icon.ico │ ├── icon.png │ ├── 16x16 │ │ ├── md.png │ │ └── marktext.png │ ├── 24x24 │ │ ├── md.png │ │ └── marktext.png │ ├── 32x32 │ │ ├── md.png │ │ └── marktext.png │ ├── 48x48 │ │ ├── md.png │ │ └── marktext.png │ ├── 64x64 │ │ ├── md.png │ │ └── marktext.png │ ├── 128x128 │ │ ├── md.png │ │ └── marktext.png │ ├── 256x256 │ │ ├── md.png │ │ └── marktext.png │ └── 512x512 │ │ ├── md.png │ │ └── marktext.png ├── linux │ ├── img │ │ ├── img1.png │ │ ├── img2.png │ │ ├── img3.png │ │ ├── img4.png │ │ ├── img5.png │ │ └── img6.png │ └── marktext.desktop └── windows │ └── installer.nsh ├── .eslintignore ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── question.md │ ├── feature_request.md │ └── bug_report.md └── PULL_REQUEST_TEMPLATE.md ├── vetur.config.js ├── tools └── validateLicenses.js ├── .editorconfig ├── .gitignore ├── .electron-vue ├── preinstall.js └── thirdPartyChecker.js ├── .vscode └── settings.json └── LICENSE /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/renderer/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/README.md: -------------------------------------------------------------------------------- 1 | ### Muya 2 | 3 | A browser based Markdown editor. -------------------------------------------------------------------------------- /test/unit/data/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.md] 2 | trim_trailing_whitespace = false 3 | -------------------------------------------------------------------------------- /src/renderer/bus/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | export default new Vue() 3 | -------------------------------------------------------------------------------- /docs/doutu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/doutu.jpg -------------------------------------------------------------------------------- /docs/focus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/focus.gif -------------------------------------------------------------------------------- /docs/source.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/source.gif -------------------------------------------------------------------------------- /docs/brew-cask.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/brew-cask.gif -------------------------------------------------------------------------------- /docs/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/marktext.png -------------------------------------------------------------------------------- /docs/typewriter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/typewriter.gif -------------------------------------------------------------------------------- /static/logo-96px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/static/logo-96px.png -------------------------------------------------------------------------------- /static/logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/static/logo-small.png -------------------------------------------------------------------------------- /docs/sponsor/readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/sponsor/readme.png -------------------------------------------------------------------------------- /resources/icons/md.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/md.icns -------------------------------------------------------------------------------- /resources/icons/md.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/md.ico -------------------------------------------------------------------------------- /docs/sponsor/qordoba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/sponsor/qordoba.png -------------------------------------------------------------------------------- /docs/themeImages/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/themeImages/dark.png -------------------------------------------------------------------------------- /resources/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/icon.icns -------------------------------------------------------------------------------- /resources/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/icon.ico -------------------------------------------------------------------------------- /resources/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/icon.png -------------------------------------------------------------------------------- /resources/icons/16x16/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/16x16/md.png -------------------------------------------------------------------------------- /resources/icons/24x24/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/24x24/md.png -------------------------------------------------------------------------------- /resources/icons/32x32/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/32x32/md.png -------------------------------------------------------------------------------- /resources/icons/48x48/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/48x48/md.png -------------------------------------------------------------------------------- /resources/icons/64x64/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/64x64/md.png -------------------------------------------------------------------------------- /resources/linux/img/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/linux/img/img1.png -------------------------------------------------------------------------------- /resources/linux/img/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/linux/img/img2.png -------------------------------------------------------------------------------- /resources/linux/img/img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/linux/img/img3.png -------------------------------------------------------------------------------- /resources/linux/img/img4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/linux/img/img4.png -------------------------------------------------------------------------------- /resources/linux/img/img5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/linux/img/img5.png -------------------------------------------------------------------------------- /resources/linux/img/img6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/linux/img/img6.png -------------------------------------------------------------------------------- /docs/themeImages/one-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/themeImages/one-dark.png -------------------------------------------------------------------------------- /resources/icons/128x128/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/128x128/md.png -------------------------------------------------------------------------------- /resources/icons/256x256/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/256x256/md.png -------------------------------------------------------------------------------- /resources/icons/512x512/md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/512x512/md.png -------------------------------------------------------------------------------- /docs/assets/marktext-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-default.png -------------------------------------------------------------------------------- /docs/assets/marktext-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-settings.png -------------------------------------------------------------------------------- /docs/themeImages/materal-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/themeImages/materal-dark.png -------------------------------------------------------------------------------- /docs/assets/marktext-export-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-export-pdf.png -------------------------------------------------------------------------------- /docs/assets/marktext-focus-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-focus-mode.png -------------------------------------------------------------------------------- /docs/assets/marktext-image-popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-image-popup.png -------------------------------------------------------------------------------- /docs/assets/marktext-interface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-interface-1.png -------------------------------------------------------------------------------- /docs/assets/marktext-interface-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-interface-2.png -------------------------------------------------------------------------------- /docs/assets/marktext-table-gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-table-gif.gif -------------------------------------------------------------------------------- /docs/assets/marktext-table-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-table-tools.png -------------------------------------------------------------------------------- /docs/themeImages/cadmium-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/themeImages/cadmium-light.png -------------------------------------------------------------------------------- /docs/themeImages/graphite-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/themeImages/graphite-light.png -------------------------------------------------------------------------------- /docs/themeImages/ulysses-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/themeImages/ulysses-light.png -------------------------------------------------------------------------------- /resources/icons/128x128/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/128x128/marktext.png -------------------------------------------------------------------------------- /resources/icons/16x16/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/16x16/marktext.png -------------------------------------------------------------------------------- /resources/icons/24x24/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/24x24/marktext.png -------------------------------------------------------------------------------- /resources/icons/256x256/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/256x256/marktext.png -------------------------------------------------------------------------------- /resources/icons/32x32/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/32x32/marktext.png -------------------------------------------------------------------------------- /resources/icons/48x48/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/48x48/marktext.png -------------------------------------------------------------------------------- /resources/icons/512x512/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/512x512/marktext.png -------------------------------------------------------------------------------- /resources/icons/64x64/marktext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/resources/icons/64x64/marktext.png -------------------------------------------------------------------------------- /src/renderer/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/renderer/assets/images/logo.png -------------------------------------------------------------------------------- /src/renderer/services/index.js: -------------------------------------------------------------------------------- 1 | import notification from './notification' 2 | 3 | export default [ 4 | notification 5 | ] 6 | -------------------------------------------------------------------------------- /docs/assets/marktext-emoji-picker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-emoji-picker.png -------------------------------------------------------------------------------- /docs/assets/marktext-export-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-export-header.png -------------------------------------------------------------------------------- /docs/assets/marktext-format-popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-format-popup.png -------------------------------------------------------------------------------- /docs/assets/marktext-image-viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-image-viewer.png -------------------------------------------------------------------------------- /docs/assets/marktext-link-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-link-preview.png -------------------------------------------------------------------------------- /docs/assets/marktext-quick-insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-quick-insert.png -------------------------------------------------------------------------------- /docs/dev/assets/marktext-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/dev/assets/marktext-interface.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/code/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/code/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/code/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/code/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/code/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/code/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/copy/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/copy/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/copy/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/copy/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/copy/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/copy/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/html/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/html/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/html/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/html/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/html/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/html/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/math/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/math/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/math/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/math/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/math/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/math/3.png -------------------------------------------------------------------------------- /docs/assets/marktext-line-transformer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-line-transformer.png -------------------------------------------------------------------------------- /docs/assets/marktext-table_drag_drop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-table_drag_drop.png -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/image_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/icons/image_dark.png -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/image_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/icons/image_light.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/chart/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/chart/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/chart/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/chart/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/chart/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/chart/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/delete/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/delete/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/delete/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/delete/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/delete/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/delete/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/mermaid/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/mermaid/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/mermaid/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/mermaid/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/mermaid/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/mermaid/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/quote/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/quote/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/quote/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/quote/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/quote/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/quote/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/unlink/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/unlink/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/unlink/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/unlink/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/unlink/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/unlink/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/warning/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/warning/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/styles/danielbd.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/styles/danielbd.woff -------------------------------------------------------------------------------- /src/muya/lib/assets/styles/danielbd.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/styles/danielbd.woff2 -------------------------------------------------------------------------------- /src/muya/themes/fonts/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /docs/THEMES.md: -------------------------------------------------------------------------------- 1 | # Themes 2 | 3 | MarkText currently doesn't support user-defined application themes. This feature is planned for v0.17.0. 4 | -------------------------------------------------------------------------------- /docs/assets/marktext-spellchecker-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-spellchecker-menu.png -------------------------------------------------------------------------------- /docs/assets/marktext-spelling-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/docs/assets/marktext-spelling-settings.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/flowchart/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/flowchart/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/flowchart/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/flowchart/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/flowchart/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/flowchart/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/footnote/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/footnote/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/footnote/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/footnote/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/footnote/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/footnote/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_1/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_1/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_1/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_1/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_1/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_1/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_2/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_2/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_2/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_2/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_2/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_2/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_3/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_3/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_3/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_3/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_3/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_3/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_4/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_4/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_4/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_4/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_4/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_4/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_5/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_5/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_5/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_5/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_5/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_5/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_6/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_6/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_6/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_6/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/heading_6/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/heading_6/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/highlight/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/highlight/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/highlight/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/highlight/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/highlight/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/highlight/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/imageEdit/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/imageEdit/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/imageEdit/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/imageEdit/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/imageEdit/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/imageEdit/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/link_jump/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/link_jump/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/link_jump/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/link_jump/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/link_jump/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/link_jump/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/new_table/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/new_table/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/new_table/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/new_table/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/new_table/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/new_table/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/paragraph/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/paragraph/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/paragraph/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/paragraph/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/paragraph/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/paragraph/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/plantuml/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/plantuml/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/plantuml/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/plantuml/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/plantuml/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/plantuml/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/sequence/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/sequence/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/sequence/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/sequence/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/sequence/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/sequence/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/table/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/table/table.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/todolist/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/todolist/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/todolist/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/todolist/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/todolist/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/todolist/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/turninto/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/turninto/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/turninto/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/turninto/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/turninto/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/turninto/3.png -------------------------------------------------------------------------------- /test/unit/data/gfm/BasicTextFormatting.md: -------------------------------------------------------------------------------- 1 | # Basic Text Formatting 2 | 3 | ~~this is strike through text~~ 4 | 5 | \~\~and this not\~\~ 6 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/image_dark_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/icons/image_dark_fail.png -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/image_light_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/icons/image_light_fail.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_center/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_center/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_center/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_center/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_center/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_center/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_left/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_left/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_left/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_left/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_left/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_left/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_right/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_right/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_right/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_right/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/algin_right/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/algin_right/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/bullet_list/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/bullet_list/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/bullet_list/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/bullet_list/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/bullet_list/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/bullet_list/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_clear/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_clear/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_clear/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_clear/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_clear/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_clear/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_image/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_image/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_image/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_image/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_link/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_link/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_link/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_link/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_link/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_link/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_math/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_math/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_math/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_math/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_math/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_math/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/front_matter/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/front_matter/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/front_matter/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/front_matter/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/front_matter/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/front_matter/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image_delete/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image_delete/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image_delete/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image_delete/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image_delete/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image_delete/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image_fail/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image_fail/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image_fail/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image_fail/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/image_fail/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/image_fail/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/inline_image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/inline_image/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/inline_image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/inline_image/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/inline_image/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/inline_image/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/order_list/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/order_list/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/order_list/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/order_list/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/order_list/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/order_list/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/quote_block/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/quote_block/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/quote_block/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/quote_block/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/quote_block/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/quote_block/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/table/table@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/table/table@2x.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/table/table@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/table/table@3x.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/table_delete/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/table_delete/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/table_delete/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/table_delete/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/table_delete/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/table_delete/3.png -------------------------------------------------------------------------------- /src/muya/themes/fonts/DejaVuSansMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/DejaVuSansMono-Bold.ttf -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_strike/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_strike/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_strike/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_strike/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_strike/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_strike/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_strong/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_strong/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_strong/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_strong/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_strong/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_strong/3.png -------------------------------------------------------------------------------- /src/muya/themes/fonts/DejaVuSansMono-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/DejaVuSansMono-Oblique.ttf -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test/unit/coverage/** 2 | test/unit/*.js 3 | test/e2e/*.js 4 | src/renderer/assets/symbolIcon/index.js 5 | src/muya/lib/assets/libs/*.js 6 | -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_emphasis/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_emphasis/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_emphasis/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_emphasis/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_emphasis/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_emphasis/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_underline/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_underline/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_underline/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_underline/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/format_underline/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/format_underline/3.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/horizontal_line/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/horizontal_line/1.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/horizontal_line/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/horizontal_line/2.png -------------------------------------------------------------------------------- /src/muya/lib/assets/pngicon/horizontal_line/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/lib/assets/pngicon/horizontal_line/3.png -------------------------------------------------------------------------------- /src/muya/lib/utils/dompurify.js: -------------------------------------------------------------------------------- 1 | import { sanitize, isValidAttribute } from 'dompurify' 2 | 3 | export { isValidAttribute } 4 | 5 | export default sanitize 6 | -------------------------------------------------------------------------------- /src/muya/themes/fonts/DejaVuSansMono-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/DejaVuSansMono-BoldOblique.ttf -------------------------------------------------------------------------------- /test/specs/config.js: -------------------------------------------------------------------------------- 1 | export const MT_MARKED_OPTIONS = Object.freeze({ 2 | headerIds: false, 3 | emoji: false, 4 | math: false, 5 | frontMatter: false 6 | }) 7 | -------------------------------------------------------------------------------- /test/unit/data/common/Images.md: -------------------------------------------------------------------------------- 1 | # Images 2 | 3 | ![alternate text](https://raw.githubusercontent.com/marktext/marktext/master/resources/icons/128x128/marktext.png) 4 | -------------------------------------------------------------------------------- /src/renderer/prefComponents/theme/theme.md: -------------------------------------------------------------------------------- 1 | ### {theme} 2 | 3 | **Lorem Ipsum** is simply [dummy](http://marktext.app) text of the printing and typesetting industry. 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: ranluo 4 | open_collective: marktext 5 | custom: https://paypal.me/ranluo?locale.x=zh_XC 6 | -------------------------------------------------------------------------------- /src/main/menu/actions/theme.js: -------------------------------------------------------------------------------- 1 | import { ipcMain } from 'electron' 2 | 3 | export const selectTheme = theme => { 4 | ipcMain.emit('set-user-preference', { theme }) 5 | } 6 | -------------------------------------------------------------------------------- /src/muya/lib/ui/imagePicker/index.css: -------------------------------------------------------------------------------- 1 | .ag-image-picker-wrapper { 2 | z-index: 100000; 3 | } 4 | 5 | .ag-image-picker-wrapper .ag-list-picker { 6 | width: 450px; 7 | } 8 | -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-300.woff -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-600.woff -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-700.woff -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-italic.woff -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question about MarkText 4 | --- 5 | 6 | ### Question description 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-300italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-300italic.woff -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-600italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-600italic.woff -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-700italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-700italic.woff -------------------------------------------------------------------------------- /src/muya/themes/fonts/open-sans-v27-latin-ext_latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code/app-marktext/develop/src/muya/themes/fonts/open-sans-v27-latin-ext_latin-regular.woff -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/renderFootnoteJump.js: -------------------------------------------------------------------------------- 1 | import { h } from '../snabbdom' 2 | 3 | export const footnoteJumpIcon = () => { 4 | return h('i.ag-footnote-backlink', '↩︎') 5 | } 6 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/sequence.js: -------------------------------------------------------------------------------- 1 | 2 | import Diagram from '../../assets/libs/sequence-diagram-snap' 3 | import '../../assets/styles/sequence-diagram.css' 4 | 5 | export default Diagram 6 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/del.js: -------------------------------------------------------------------------------- 1 | export default function del (h, cursor, block, token, outerClass) { 2 | return this.delEmStrongFac('del', h, cursor, block, token, outerClass) 3 | } 4 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/em.js: -------------------------------------------------------------------------------- 1 | export default function em (h, cursor, block, token, outerClass) { 2 | return this.delEmStrongFac('em', h, cursor, block, token, outerClass) 3 | } 4 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "assert": true, 7 | "expect": true, 8 | "should": true, 9 | "__static": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/strong.js: -------------------------------------------------------------------------------- 1 | export default function strong (h, cursor, block, token, outerClass) { 2 | return this.delEmStrongFac('strong', h, cursor, block, token, outerClass) 3 | } 4 | -------------------------------------------------------------------------------- /vetur.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | projects: [ 3 | { 4 | root: './src/renderer', 5 | package: '../../package.json', 6 | tsconfig: './jsconfig.json' 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/muya/lib/utils/random.js: -------------------------------------------------------------------------------- 1 | const ID_PREFIX = 'ag-' 2 | let id = 0 3 | 4 | export const getUniqueId = () => `${ID_PREFIX}${id++}` 5 | 6 | export const getLongUniqueId = () => `${getUniqueId()}-${(+new Date()).toString(32)}` 7 | -------------------------------------------------------------------------------- /test/e2e/playwright.config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | workers: 1, 3 | use: { 4 | headless: false, 5 | viewport: { width: 1280, height: 720 }, 6 | timeout: 30000 7 | } 8 | } 9 | module.exports = config 10 | -------------------------------------------------------------------------------- /src/renderer/axios/index.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import adapter from 'axios/lib/adapters/http' 3 | 4 | axios.defaults.adapter = adapter 5 | 6 | const http = axios.create({ 7 | adapter 8 | }) 9 | 10 | export default http 11 | -------------------------------------------------------------------------------- /resources/windows/installer.nsh: -------------------------------------------------------------------------------- 1 | !macro customUnInstall 2 | MessageBox MB_YESNO "Do you want to delete user settings?" /SD IDNO IDNO SkipRemoval 3 | SetShellVarContext current 4 | RMDir /r "$APPDATA\marktext" 5 | SkipRemoval: 6 | !macroend -------------------------------------------------------------------------------- /src/main/globalSetting.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | 3 | // Set `__static` path to static files in production. 4 | if (process.env.NODE_ENV !== 'development') { 5 | global.__static = path.join(__dirname, '/static').replace(/\\/g, '\\\\') 6 | } 7 | -------------------------------------------------------------------------------- /docs/dev/code/README.md: -------------------------------------------------------------------------------- 1 | # Internal Documentation 2 | 3 | WIP documentation of MarkText internals. 4 | 5 | - [Block addition properties and its value](BLOCK_ADDITION_PROPERTY.md) 6 | - [Commands](COMMANDS.md) 7 | - [Inter-Process Communication (IPC)](IPC.md) 8 | -------------------------------------------------------------------------------- /src/renderer/codeMirror/index.css: -------------------------------------------------------------------------------- 1 | .CodeMirror { 2 | background: transparent; 3 | height: auto; 4 | } 5 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { 6 | background: rgb(178, 215, 254); 7 | } -------------------------------------------------------------------------------- /tools/validateLicenses.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const thirdPartyChecker = require('../.electron-vue/thirdPartyChecker.js') 5 | const rootDir = path.resolve(__dirname, '..') 6 | 7 | thirdPartyChecker.validateLicenses(rootDir) 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | # Unix-style newlines with a newline ending every file 4 | [*] 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /src/main/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "target": "es2020", 6 | "paths": { 7 | "common/*": ["../common/*"] 8 | } 9 | }, 10 | "include": ["."] 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dist/ 3 | */dist/* 4 | build/* 5 | static/themes/* 6 | src/muya/node_modules/ 7 | coverage 8 | .vscode 9 | node_modules/ 10 | npm-debug.log 11 | npm-debug.log.* 12 | yarn-error.log 13 | thumbs.db 14 | !.gitkeep 15 | .idea 16 | .env 17 | .eslintcache 18 | -------------------------------------------------------------------------------- /src/renderer/prefComponents/common/separator/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/text.js: -------------------------------------------------------------------------------- 1 | // render token of text type to vdom. 2 | export default function text (h, cursor, block, token) { 3 | const { start, end } = token.range 4 | return [ 5 | h('span.ag-plain-text', this.highlight(h, block, start, end, token)) 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /src/renderer/util/markdownToHtml.js: -------------------------------------------------------------------------------- 1 | import ExportHtml from 'muya/lib/utils/exportHtml' 2 | 3 | const markdownToHtml = async markdown => { 4 | const html = await new ExportHtml(markdown).renderHtml() 5 | return `
${html}
` 6 | } 7 | 8 | export default markdownToHtml 9 | -------------------------------------------------------------------------------- /src/renderer/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "target": "es2020", 6 | "paths": { 7 | "common/*": ["../common/*"], 8 | "muya/*": ["../muya/*"], 9 | "@/*": ["./*"] 10 | } 11 | }, 12 | "include": ["."] 13 | } 14 | -------------------------------------------------------------------------------- /src/main/menu/actions/help.js: -------------------------------------------------------------------------------- 1 | export const showAboutDialog = win => { 2 | if (win && win.webContents) { 3 | win.webContents.send('mt::about-dialog') 4 | } 5 | } 6 | 7 | export const showTweetDialog = (win, type) => { 8 | if (win && win.webContents) { 9 | win.webContents.send('mt::tweet', type) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/renderer/util/day.js: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs/esm' 2 | import relativeTime from 'dayjs/esm/plugin/relativeTime' 3 | 4 | // `en` is a built in locale. no need to import it. 5 | // import 'dayjs/esm/locale/en' // load on demand 6 | // dayjs.locale('en') // use en locale globally 7 | 8 | dayjs.extend(relativeTime) 9 | 10 | export default dayjs 11 | -------------------------------------------------------------------------------- /src/muya/lib/ui/linkTools/config.js: -------------------------------------------------------------------------------- 1 | import unlinkIcon from '../../assets/pngicon/unlink/2.png' 2 | import linkJumpIcon from '../../assets/pngicon/link_jump/2.png' 3 | 4 | const icons = [ 5 | { 6 | type: 'unlink', 7 | icon: unlinkIcon 8 | }, { 9 | type: 'jump', 10 | icon: linkJumpIcon 11 | } 12 | ] 13 | 14 | export default icons 15 | -------------------------------------------------------------------------------- /src/muya/lib/utils/getParentCheckBox.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../config' 2 | 3 | export const getParentCheckBox = function (checkbox) { 4 | const parent = checkbox.parentElement.parentElement.parentElement 5 | if (parent.id !== CLASS_OR_ID.AG_EDITOR_ID) { 6 | return parent.firstElementChild 7 | } else { 8 | return null 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/index.js: -------------------------------------------------------------------------------- 1 | import renderBlock from './renderBlock' 2 | import renderLeafBlock from './renderLeafBlock' 3 | import renderContainerBlock from './renderContainerBlock' 4 | import renderIcon from './renderIcon' 5 | 6 | export default { 7 | renderBlock, 8 | renderLeafBlock, 9 | renderContainerBlock, 10 | renderIcon 11 | } 12 | -------------------------------------------------------------------------------- /src/main/commands/file.js: -------------------------------------------------------------------------------- 1 | import { COMMANDS } from './index' 2 | 3 | const openQuickOpenDialog = win => { 4 | if (win && win.webContents) { 5 | win.webContents.send('mt::execute-command-by-id', 'file.quick-open') 6 | } 7 | } 8 | 9 | export const loadFileCommands = commandManager => { 10 | commandManager.add(COMMANDS.FILE_QUICK_OPEN, openQuickOpenDialog) 11 | } 12 | -------------------------------------------------------------------------------- /src/renderer/prefComponents/image/config.js: -------------------------------------------------------------------------------- 1 | export const imageActions = [{ 2 | label: 'Upload image to cloud using selected uploader (must be configured below)', 3 | value: 'upload' 4 | }, { 5 | label: 'Copy image to designated relative assets or global local folder', 6 | value: 'folder' 7 | }, { 8 | label: 'Keep original location', 9 | value: 'path' 10 | }] 11 | -------------------------------------------------------------------------------- /test/unit/data/common/Escapes.md: -------------------------------------------------------------------------------- 1 | # Escapes 2 | 3 | \# This isn't a heading 4 | 5 | \*this isn't in italic\* and \_so is this\_ 6 | 7 | \*\*this isn't in bold\*\* and \_\_so is this\_\_ 8 | 9 | \`\`\` 10 | This isn't a code block without language identifier. 11 | \`\`\` 12 | 13 | \$ You can also escape math \$. 14 | 15 | \$\$ 16 | This isn't a math block. 17 | \$\$ 18 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/hr.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function hr (h, cursor, block, token, outerClass) { 4 | const { start, end } = token.range 5 | const content = this.highlight(h, block, start, end, token) 6 | return [ 7 | h(`span.${CLASS_OR_ID.AG_GRAY}.${CLASS_OR_ID.AG_REMOVE}`, content) 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /test/unit/data/gfm/Lists.md: -------------------------------------------------------------------------------- 1 | # GFM Lists 2 | 3 | To start a check list, write this: 4 | 5 | - [ ] this is not checked 6 | - [ ] this is too 7 | - [x] but this is checked 8 | 9 | --- 10 | 11 | * [x] this is checked 12 | * [ ] this is not checked 13 | * [x] but this is checked 14 | 15 | --- 16 | 17 | + [ ] this is not checked 18 | + [ ] this is too 19 | + [x] but this is checked 20 | -------------------------------------------------------------------------------- /docs/dev/README.md: -------------------------------------------------------------------------------- 1 | # Developer Documentation 2 | 3 | Welcome to developer documentation of MarkText. 4 | 5 | - [Project architecture](ARCHITECTURE.md) 6 | - [Build instructions](BUILD.md) 7 | - [Debugging](DEBUGGING.md) 8 | - [Interface](INTERFACE.md) 9 | - [Steps to release MarkText](RELEASE.md) 10 | - [Prepare a hotfix](RELEASE_HOTFIX.md) 11 | - [Internal documentation](code/README.md) 12 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/multipleMath.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function multipleMath (h, cursor, block, token, outerClass) { 4 | const { start, end } = token.range 5 | const content = this.highlight(h, block, start, end, token) 6 | return [ 7 | h(`span.${CLASS_OR_ID.AG_GRAY}.${CLASS_OR_ID.AG_REMOVE}`, content) 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.electron-vue/preinstall.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const nodeMajor = Number(process.versions.node.match(/^(\d+)\./)[1]) 4 | if (nodeMajor < 14) { 5 | console.error('[ERROR] Node.js v14 or above is required.\n') 6 | process.exit(1) 7 | } 8 | 9 | if (!/yarn\.js$/.test(process.env.npm_execpath)) { 10 | console.error('[ERROR] Please use yarn to install dependencies.\n') 11 | process.exit(1) 12 | } 13 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/renderTableDargBar.js: -------------------------------------------------------------------------------- 1 | import { h } from '../snabbdom' 2 | 3 | export const renderLeftBar = () => { 4 | return h('span.ag-drag-handler.left', { 5 | attrs: { contenteditable: 'false' } 6 | }) 7 | } 8 | 9 | export const renderBottomBar = () => { 10 | return h('span.ag-drag-handler.bottom', { 11 | attrs: { contenteditable: 'false' } 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /src/muya/lib/utils/cumputeCheckBoxStatus.js: -------------------------------------------------------------------------------- 1 | export const cumputeCheckboxStatus = function (parentCheckbox) { 2 | const children = parentCheckbox.parentElement.lastElementChild.children 3 | const len = children.length 4 | for (let i = 0; i < len; i++) { 5 | const checkbox = children[i].firstElementChild 6 | if (checkbox.checked === false) { 7 | return false 8 | } 9 | } 10 | return true 11 | } 12 | -------------------------------------------------------------------------------- /src/muya/lib/assets/styles/sequence-diagram.css: -------------------------------------------------------------------------------- 1 | /** js sequence diagrams 2 | * https://bramp.github.io/js-sequence-diagrams/ 3 | * (c) 2012-2017 Andrew Brampton (bramp.net) 4 | * Simplified BSD license. 5 | */ 6 | @font-face { 7 | font-family: 'danielbd'; 8 | src: url('danielbd.woff2') format('woff2'), 9 | url('danielbd.woff') format('woff'); 10 | font-weight: normal; 11 | font-style: normal; 12 | } 13 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/softLineBreak.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function hardLineBreak (h, cursor, block, token, outerClass) { 4 | const { lineBreak, isAtEnd } = token 5 | let selector = `span.${CLASS_OR_ID.AG_SOFT_LINE_BREAK}` 6 | if (isAtEnd) { 7 | selector += `.${CLASS_OR_ID.AG_LINE_END}` 8 | } 9 | 10 | return [ 11 | h(selector, lineBreak) 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /resources/linux/marktext.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=MarkText 3 | Comment=Next generation markdown editor 4 | Exec=marktext %F 5 | Terminal=false 6 | Type=Application 7 | Icon=marktext 8 | Categories=Office;TextEditor;Utility; 9 | MimeType=text/markdown; 10 | Keywords=marktext; 11 | StartupWMClass=marktext 12 | Actions=NewWindow; 13 | 14 | [Desktop Action NewWindow] 15 | Name=New Window 16 | Exec=marktext --new-window %F 17 | Icon=marktext 18 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/backlash.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function backlash (h, cursor, block, token, outerClass) { 4 | const className = this.getClassName(outerClass, block, token, cursor) 5 | const { start, end } = token.range 6 | const content = this.highlight(h, block, start, end, token) 7 | 8 | return [ 9 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, content) 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/renderer/store/tweet.js: -------------------------------------------------------------------------------- 1 | import { ipcRenderer } from 'electron' 2 | import bus from '../bus' 3 | 4 | const state = {} 5 | 6 | const getters = {} 7 | 8 | const mutations = {} 9 | 10 | const actions = { 11 | LISTEN_FOR_TWEET () { 12 | ipcRenderer.on('mt::tweet', (e, type) => { 13 | if (type === 'twitter') { 14 | bus.$emit('tweetDialog') 15 | } 16 | }) 17 | } 18 | } 19 | 20 | export default { state, getters, mutations, actions } 21 | -------------------------------------------------------------------------------- /docs/APPLICATION_DATA_DIRECTORY.md: -------------------------------------------------------------------------------- 1 | # Application Data Directory 2 | 3 | The per-user application data directory is located in the following directory: 4 | 5 | - `%APPDATA%\marktext` on Windows 6 | - `$XDG_CONFIG_HOME/marktext` or `~/.config/marktext` on Linux 7 | - `~/Library/Application Support/marktext` on macOS 8 | 9 | When [portable mode](PORTABLE.md) is enabled, the directory location is either the `--user-data-dir` parameter or `marktext-user-data` directory. 10 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/tailHeader.js: -------------------------------------------------------------------------------- 1 | export default function tailHeader (h, cursor, block, token, outerClass) { 2 | const className = this.getClassName(outerClass, block, token, cursor) 3 | const { start, end } = token.range 4 | const content = this.highlight(h, block, start, end, token) 5 | if (/^h\d$/.test(block.type)) { 6 | return [ 7 | h(`span.${className}`, content) 8 | ] 9 | } else { 10 | return content 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/renderBlock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * [renderBlock render one block, no matter it is a container block or text block] 3 | */ 4 | export default function renderBlock (parent, block, activeBlocks, matches, useCache = false) { 5 | const method = Array.isArray(block.children) && block.children.length > 0 6 | ? 'renderContainerBlock' 7 | : 'renderLeafBlock' 8 | 9 | return this[method](parent, block, activeBlocks, matches, useCache) 10 | } 11 | -------------------------------------------------------------------------------- /test/unit/specs/LandingPage.spec.js_disabled: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import LandingPage from '@/components/LandingPage' 3 | 4 | describe('LandingPage.vue', () => { 5 | it('should render correct contents', () => { 6 | const vm = new Vue({ 7 | el: document.createElement('div'), 8 | render: h => h(LandingPage) 9 | }).$mount() 10 | 11 | expect(vm.$el.querySelector('.title').textContent).to.contain('Welcome to your new project!') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/specs/gfm/gfm.0.29.md: -------------------------------------------------------------------------------- 1 | ## Test Result 2 | 3 | Total test 24 examples, and failed 0 examples: 4 | 5 | | Section | Failed/Total | Percentage | 6 | |:-----------------:|:-------------:|:-------------:| 7 | | Tables | 0/8 | 100.00% | 8 | | Task list items | 0/2 | 100.00% | 9 | | Strikethrough | 0/2 | 100.00% | 10 | | Autolinks | 0/11 | 100.00% | 11 | |Disallowed Raw HTML| 0/1 | 100.00% | 12 | 13 | -------------------------------------------------------------------------------- /src/main/menu/templates/dock.js: -------------------------------------------------------------------------------- 1 | import { app, Menu } from 'electron' 2 | import * as actions from '../actions/file' 3 | 4 | const dockMenu = Menu.buildFromTemplate([{ 5 | label: 'Open...', 6 | click (menuItem, browserWindow) { 7 | if (browserWindow) { 8 | actions.openFile(browserWindow) 9 | } else { 10 | actions.newEditorWindow() 11 | } 12 | } 13 | }, { 14 | label: 'Clear Recent', 15 | click () { 16 | app.clearRecentDocuments() 17 | } 18 | }]) 19 | 20 | export default dockMenu 21 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.insertSpaces": true, 3 | "editor.tabSize": 2, 4 | // Issues with unit test files 5 | //"editor.trimAutoWhitespace": false, 6 | "files.eol": "\n", 7 | "files.insertFinalNewline": true, 8 | 9 | "search.exclude": { 10 | "**/.git": true, 11 | "**/build": true, 12 | "**/node_modules": true, 13 | "**/dist": true 14 | }, 15 | "files.watcherExclude": { 16 | "**/.git": true, 17 | "**/build": true, 18 | "**/node_modules": true, 19 | "**/dist": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/utils/createGitHubIssue.js: -------------------------------------------------------------------------------- 1 | import { shell } from 'electron' 2 | import { GITHUB_REPO_URL } from '../config' 3 | 4 | export const createGitHubIssueUrl = (title, msg) => { 5 | const issueUrl = new URL(`${GITHUB_REPO_URL}/issues/new`) 6 | if (title) { 7 | issueUrl.searchParams.set('title', title) 8 | } 9 | if (msg) { 10 | issueUrl.searchParams.set('body', msg) 11 | } 12 | return issueUrl.toString() 13 | } 14 | 15 | export const createAndOpenGitHubIssueUrl = (title, msg) => { 16 | shell.openExternal(createGitHubIssueUrl(title, msg)) 17 | } 18 | -------------------------------------------------------------------------------- /src/renderer/prefComponents/theme/config.js: -------------------------------------------------------------------------------- 1 | export const themes = [ 2 | { 3 | name: 'light' 4 | }, 5 | { 6 | name: 'dark' 7 | }, 8 | { 9 | name: 'graphite' 10 | }, 11 | { 12 | name: 'material-dark' 13 | }, 14 | { 15 | name: 'ulysses' 16 | }, 17 | { 18 | name: 'one-dark' 19 | } 20 | ] 21 | 22 | export const autoSwitchThemeOptions = [{ 23 | label: 'Adjust theme at startup', // Always 24 | value: 0 25 | }, /* { 26 | label: 'Only at runtime', 27 | value: 1 28 | }, */ { 29 | label: 'Never', 30 | value: 2 31 | }] 32 | -------------------------------------------------------------------------------- /test/unit/data/gfm/Tables.md: -------------------------------------------------------------------------------- 1 | # Tables 2 | 3 | | First Header | Second Header | 4 | | -------------- | ---------------- | 5 | | Co`nten`t Cell | Content Cell | 6 | | Content Cell | **Content Cell** | 7 | 8 | | First \| Header | Second Header | 9 | | --------------- | --------------- | 10 | | Content Cell | Content Cell | 11 | | Content \|Cell | Content \| Cell | 12 | 13 | ## Failing Tests 14 | 15 | ``` 16 | First Header | Second Header 17 | ------------ | ------------- 18 | Content Cell | Content Cell 19 | Content Cell | Content Cell 20 | ``` 21 | -------------------------------------------------------------------------------- /src/muya/lib/ui/transformer/index.css: -------------------------------------------------------------------------------- 1 | .ag-transformer .circle { 2 | position: absolute; 3 | width: 14px; 4 | height: 14px; 5 | display: inline-block; 6 | border-radius: 50%; 7 | background: var(--themeColor); 8 | border: 2px solid var(--editorBgColor); 9 | box-sizing: border-box; 10 | box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.15); 11 | } 12 | 13 | .ag-transformer .top-left, 14 | .ag-transformer .bottom-right { 15 | cursor: nwse-resize 16 | } 17 | 18 | .ag-transformer .top-right, 19 | .ag-transformer .bottom-left { 20 | cursor: nesw-resize 21 | } 22 | -------------------------------------------------------------------------------- /docs/PORTABLE.md: -------------------------------------------------------------------------------- 1 | # Portable Mode 2 | 3 | MarkText stores all user configuration inside the [application data directory](APPLICATION_DATA_DIRECTORY.md) that can be changed with `--user-data-dir` command-line flag. 4 | 5 | ## Linux and Windows 6 | 7 | On Linux and Windows you can also create a directory called `marktext-user-data` to save all user data inside the directory. Like: 8 | 9 | ``` 10 | marktext-portable/ 11 | ├── marktext (Linux) or MarkText.exe (Windows) 12 | ├── marktext-user-data/ 13 | ├── resources/ 14 | ├── THIRD-PARTY-LICENSES.txt 15 | └── ... 16 | ``` 17 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/quote.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/searchIcons/iconRegex.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/dev/RELEASE_HOTFIX.md: -------------------------------------------------------------------------------- 1 | # Prepare a hotfix 2 | 3 | - Create a hotfix branch: `git checkout -b hotfix-vX.Y.Z` 4 | - Make changes to the code and/or `cherry-pick` changes from another branch and commit changes. 5 | - Test the hotfix and binaries. 6 | - [Release](RELEASE.md) a new MarkText version. 7 | 8 | **How to cherry pick?** 9 | 10 | You can pick commits from another branch and apply the commit to the current one. 11 | 12 | - `git checkout hotfix-vX.Y.Z` 13 | - `git cherry-pick ` 14 | - Please resolve all conflicts and `git commit` the changes if needed. 15 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_emphasis.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest an idea for MarkText 4 | --- 5 | 6 | 9 | 10 | ### Describe your feature request 11 | 12 | 13 | 14 | ### What problem does this feature solve? [optional] 15 | 16 | 17 | 18 | ### Additional context [optional] 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/muya/lib/ui/fileIcons/index.js: -------------------------------------------------------------------------------- 1 | // Because the sidebar also use the file icons, So I put this file out of floatBox directory. 2 | import '@marktext/file-icons/build/index.css' 3 | import fileIcons from '@marktext/file-icons' 4 | 5 | fileIcons.getClassByName = function (name) { 6 | const icon = fileIcons.matchName(name) 7 | 8 | return icon ? icon.getClass(0, false) : null 9 | } 10 | 11 | fileIcons.getClassByLanguage = function (lang) { 12 | const icon = fileIcons.matchLanguage(lang) 13 | 14 | return icon ? icon.getClass(0, false) : null 15 | } 16 | 17 | export default fileIcons 18 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/horizontal_line.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/utils/hash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * generate constants map hash, the value is lowercase of the key, 3 | * also translate `_` to `-`] 4 | */ 5 | export const genUpper2LowerKeyHash = keys => { 6 | return keys.reduce((acc, key) => { 7 | const value = key.toLowerCase().replace(/_/g, '-') 8 | return Object.assign(acc, { [key]: value }) 9 | }, {}) 10 | } 11 | 12 | /** 13 | * generate constants map, the value is the key. 14 | */ 15 | export const generateKeyHash = keys => { 16 | return keys.reduce((acc, key) => { 17 | return Object.assign(acc, { [key]: key }) 18 | }, {}) 19 | } 20 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/toc.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 3 | 4 | | Q | A 5 | | ----------------- | --- 6 | | Bug fix? | yes/no 7 | | New feature? | yes/no 8 | | Breaking changes? | yes/no 9 | | Deprecations? | yes/no 10 | | New tests added? | yes/not needed 11 | | Fixed tickets | Fixes #ticket number (set to none if no tickets are fixed, repeat template for each ticket fixed) 12 | | License | MIT 13 | 14 | ### Description 15 | 16 | [Description of the bug or feature] 17 | -------------------------------------------------------------------------------- /src/renderer/components/sideBar/help.js: -------------------------------------------------------------------------------- 1 | import FilesIcon from '@/assets/icons/files.svg' 2 | import SearchIcon from '@/assets/icons/search.svg' 3 | import TocIcon from '@/assets/icons/toc.svg' 4 | import SettingIcon from '@/assets/icons/setting.svg' 5 | 6 | export const sideBarIcons = [ 7 | { 8 | name: 'files', 9 | icon: FilesIcon 10 | }, { 11 | name: 'search', 12 | icon: SearchIcon 13 | }, { 14 | name: 'toc', 15 | icon: TocIcon 16 | } 17 | ] 18 | 19 | export const sideBarBottomIcons = [ 20 | { 21 | name: 'settings', 22 | icon: SettingIcon 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | Vue.config.devtools = false 3 | Vue.config.productionTip = false 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | 9 | // require all src files except main.js for coverage. 10 | // you can also change this to match only the subset of files that 11 | // you want coverage for. 12 | const srcContext = require.context('../../src/renderer', true, /^\.\/(?!main(\.js)?$).+\.(?:js|vue)$/) 13 | srcContext.keys().forEach(srcContext) 14 | -------------------------------------------------------------------------------- /src/muya/lib/utils/getLinkInfo.js: -------------------------------------------------------------------------------- 1 | import { findNearestParagraph } from '../selection/dom' 2 | import { tokenizer } from '../parser' 3 | 4 | export const getLinkInfo = a => { 5 | const paragraph = findNearestParagraph(a) 6 | const raw = a.getAttribute('data-raw') 7 | const start = a.getAttribute('data-start') 8 | const end = a.getAttribute('data-end') 9 | const tokens = tokenizer(raw) 10 | const token = tokens[0] 11 | const href = a.getAttribute('href') 12 | token.range = { 13 | start, 14 | end 15 | } 16 | return { 17 | key: paragraph.id, 18 | token, 19 | href 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/pref_fontsize.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/renderCopyButton.js: -------------------------------------------------------------------------------- 1 | import { h } from '../snabbdom' 2 | import copyIcon from '../../../assets/pngicon/copy/2.png' 3 | 4 | const renderCopyButton = () => { 5 | const selector = 'a.ag-code-copy' 6 | const iconVnode = h('i.icon', h('i.icon-inner', { 7 | style: { 8 | background: `url(${copyIcon}) no-repeat`, 9 | 'background-size': '100%' 10 | } 11 | }, '')) 12 | 13 | return h(selector, { 14 | attrs: { 15 | title: 'Copy content', 16 | contenteditable: 'false' 17 | } 18 | }, iconVnode) 19 | } 20 | 21 | export default renderCopyButton 22 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/bullet_list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/renderContainerEditIcon.js: -------------------------------------------------------------------------------- 1 | import { h } from '../snabbdom' 2 | import { CLASS_OR_ID } from '../../../config' 3 | import htmlIcon from '../../../assets/pngicon/html/2.png' 4 | 5 | export const renderEditIcon = () => { 6 | const selector = `a.${CLASS_OR_ID.AG_CONTAINER_ICON}` 7 | const iconVnode = h('i.icon', h('i.icon-inner', { 8 | style: { 9 | background: `url(${htmlIcon}) no-repeat`, 10 | 'background-size': '100%' 11 | } 12 | }, '')) 13 | 14 | return h(selector, { 15 | attrs: { 16 | contenteditable: 'false' 17 | } 18 | }, iconVnode) 19 | } 20 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/add_close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderBlock/renderLineNumber.js: -------------------------------------------------------------------------------- 1 | import { h } from '../snabbdom' 2 | 3 | const NEW_LINE_EXP = /\n(?!$)/g 4 | 5 | const renderLineNumberRows = codeContent => { 6 | const { text } = codeContent 7 | const match = text.match(NEW_LINE_EXP) 8 | let linesNum = match ? match.length + 1 : 1 9 | if (text.endsWith('\n')) { 10 | linesNum++ 11 | } 12 | const data = { 13 | attrs: { 14 | 'aria-hidden': true 15 | } 16 | } 17 | const children = [...new Array(linesNum)].map(() => h('span')) 18 | 19 | return h('span.line-numbers-rows', data, children) 20 | } 21 | 22 | export default renderLineNumberRows 23 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/codeFense.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function codeFense (h, cursor, block, token, outerClass) { 4 | const { start, end } = token.range 5 | const { marker } = token 6 | 7 | const markerContent = this.highlight(h, block, start, start + marker.length, token) 8 | const content = this.highlight(h, block, start + marker.length, end, token) 9 | 10 | return [ 11 | h(`span.${CLASS_OR_ID.AG_GRAY}`, markerContent), 12 | h(`span.${CLASS_OR_ID.AG_LANGUAGE}`, { 13 | attrs: { 14 | spellcheck: 'false' 15 | } 16 | }, content) 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/muya/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "muya", 3 | "version": "0.1.2", 4 | "description": "A browser based markdown editor that powers MarkText", 5 | "main": "dist/muya.min.js", 6 | "scripts": { 7 | "test": "npm run test" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/marktext/muya.git" 12 | }, 13 | "keywords": [ 14 | "markdown", 15 | "editor", 16 | "brower" 17 | ], 18 | "author": "ransixi@gmail.com", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/marktext/muya/issues" 22 | }, 23 | "homepage": "https://github.com/marktext/muya#readme" 24 | } 25 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/hardLineBreak.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function softLineBreak (h, cursor, block, token, outerClass) { 4 | const { spaces, lineBreak, isAtEnd } = token 5 | const className = CLASS_OR_ID.AG_HARD_LINE_BREAK 6 | const spaceClass = CLASS_OR_ID.AG_HARD_LINE_BREAK_SPACE 7 | if (isAtEnd) { 8 | return [ 9 | h(`span.${className}`, h(`span.${spaceClass}`, spaces)), 10 | h(`span.${CLASS_OR_ID.AG_LINE_END}`, lineBreak) 11 | ] 12 | } else { 13 | return [ 14 | h(`span.${className}`, [h(`span.${spaceClass}`, spaces), lineBreak]) 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/muya/lib/utils/markdownFile.js: -------------------------------------------------------------------------------- 1 | // __MARKTEXT_ONLY__ 2 | 3 | const MARKDOWN_EXTENSIONS = Object.freeze([ 4 | 'markdown', 5 | 'mdown', 6 | 'mkdn', 7 | 'md', 8 | 'mkd', 9 | 'mdwn', 10 | 'mdtxt', 11 | 'mdtext', 12 | 'mdx', 13 | 'text', 14 | 'txt' 15 | ]) 16 | 17 | /** 18 | * Returns true if the filename matches one of the markdown extensions allowed in MarkText. 19 | * 20 | * @param {string} filename Path or filename 21 | */ 22 | export const hasMarkdownExtension = filename => { 23 | if (!filename || typeof filename !== 'string') return false 24 | return MARKDOWN_EXTENSIONS.some(ext => filename.toLowerCase().endsWith(`.${ext}`)) 25 | } 26 | -------------------------------------------------------------------------------- /test/e2e/launch.spec.js: -------------------------------------------------------------------------------- 1 | const { expect, test } = require('@playwright/test') 2 | const { launchElectron } = require('./helpers') 3 | 4 | test.describe('Check Launch MarkText', async () => { 5 | let app = null 6 | let page = null 7 | 8 | test.beforeAll(async () => { 9 | const { app: electronApp, page: firstPage } = await launchElectron() 10 | app = electronApp 11 | page = firstPage 12 | }) 13 | 14 | test.afterAll(async () => { 15 | await app.close() 16 | }) 17 | 18 | test('Empty MarkText', async () => { 19 | const title = await page.title() 20 | expect(/^MarkText|Untitled-1 - MarkText$/.test(title)).toBeTruthy() 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /test/unit/data/common/Links.md: -------------------------------------------------------------------------------- 1 | # Links 2 | 3 | [title](http://127.0.0.1) 4 | 5 | [title with spaces](https://localhost) 6 | 7 | - [title](http://127.0.0.1) 8 | 9 | - [title with spaces](https://localhost) 10 | 11 | - [ ] [title](http://127.0.0.1) 12 | 13 | - [x] [title with spaces](https://localhost) 14 | 15 | ## Reference Links 16 | 17 | You can also put the [link URL][1] below the current paragraph like [this][2]. 18 | 19 | [1]: http://url.local 20 | [2]: http://another.url 21 | 22 | Or you can use a [shortcut][] reference, which links the text "shortcut" to the link named "[shortcut]" on the next paragraph. 23 | 24 | [shortcut]: http://goes/with/the/link/name/text 25 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/htmlEscape.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | import escapeCharactersMap from '../../escapeCharacter' 3 | 4 | export default function htmlEscape (h, cursor, block, token, outerClass) { 5 | const className = this.getClassName(outerClass, block, token, cursor) 6 | const { escapeCharacter } = token 7 | const { start, end } = token.range 8 | 9 | const content = this.highlight(h, block, start, end, token) 10 | 11 | return [ 12 | h(`span.${className}.${CLASS_OR_ID.AG_HTML_ESCAPE}`, { 13 | dataset: { 14 | character: escapeCharactersMap[escapeCharacter] 15 | } 16 | }, content) 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/header_4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/menu/templates/prefEdit.js: -------------------------------------------------------------------------------- 1 | export default function (keybindings) { 2 | return { 3 | label: 'Edit', 4 | submenu: [{ 5 | label: 'Cut', 6 | accelerator: keybindings.getAccelerator('edit.cut'), 7 | role: 'cut' 8 | }, { 9 | label: 'Copy', 10 | accelerator: keybindings.getAccelerator('edit.copy'), 11 | role: 'copy' 12 | }, { 13 | label: 'Paste', 14 | accelerator: keybindings.getAccelerator('edit.paste'), 15 | role: 'paste' 16 | }, { 17 | type: 'separator' 18 | }, { 19 | label: 'Select All', 20 | accelerator: keybindings.getAccelerator('edit.select-all'), 21 | role: 'selectAll' 22 | }] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/header_1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/utils/domManipulate.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * [description `add` or `remove` className of element 4 | */ 5 | export const operateClassName = (element, ctrl, className) => { 6 | element.classList[ctrl](className) 7 | } 8 | 9 | export const insertBefore = (newNode, originNode) => { 10 | const parentNode = originNode.parentNode 11 | parentNode.insertBefore(newNode, originNode) 12 | } 13 | 14 | // DOM operations 15 | export const insertAfter = (newNode, originNode) => { 16 | const parentNode = originNode.parentNode 17 | 18 | if (originNode.nextSibling) { 19 | parentNode.insertBefore(newNode, originNode.nextSibling) 20 | } else { 21 | parentNode.appendChild(newNode) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/mermaid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/menu/actions/index.js: -------------------------------------------------------------------------------- 1 | import { loadEditCommands } from './edit' 2 | import { loadFileCommands } from './file' 3 | import { loadFormatCommands } from './format' 4 | import { loadMarktextCommands } from './marktext' 5 | import { loadParagraphCommands } from './paragraph' 6 | import { loadViewCommands } from './view' 7 | import { loadWindowCommands } from './window' 8 | 9 | export const loadMenuCommands = commandManager => { 10 | loadEditCommands(commandManager) 11 | loadFileCommands(commandManager) 12 | loadFormatCommands(commandManager) 13 | loadMarktextCommands(commandManager) 14 | loadParagraphCommands(commandManager) 15 | loadViewCommands(commandManager) 16 | loadWindowCommands(commandManager) 17 | } 18 | -------------------------------------------------------------------------------- /src/renderer/contextMenu/tabs/actions.js: -------------------------------------------------------------------------------- 1 | import bus from '../../bus' 2 | 3 | export const closeThis = (tabId) => { 4 | bus.$emit('TABS::close-this', tabId) 5 | } 6 | 7 | export const closeOthers = (tabId) => { 8 | bus.$emit('TABS::close-others', tabId) 9 | } 10 | 11 | export const closeSaved = () => { 12 | bus.$emit('TABS::close-saved') 13 | } 14 | 15 | export const closeAll = () => { 16 | bus.$emit('TABS::close-all') 17 | } 18 | 19 | export const rename = (tabId) => { 20 | bus.$emit('TABS::rename', tabId) 21 | } 22 | 23 | export const copyPath = (tabId) => { 24 | bus.$emit('TABS::copy-path', tabId) 25 | } 26 | 27 | export const showInFolder = (tabId) => { 28 | bus.$emit('TABS::show-in-folder', tabId) 29 | } 30 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/html.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/paragraph.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/contentState/tocCtrl.js: -------------------------------------------------------------------------------- 1 | const tocCtrl = ContentState => { 2 | ContentState.prototype.getTOC = function () { 3 | const { blocks } = this 4 | const toc = [] 5 | 6 | for (const block of blocks) { 7 | if (/^h\d$/.test(block.type)) { 8 | const { headingStyle, key, type } = block 9 | const { text } = block.children[0] 10 | const content = headingStyle === 'setext' ? text.trim() : text.replace(/^\s*#{1,6}\s{1,}/, '').trim() 11 | const lvl = +type.substring(1) 12 | const slug = key 13 | toc.push({ 14 | content, 15 | lvl, 16 | slug 17 | }) 18 | } 19 | } 20 | 21 | return toc 22 | } 23 | } 24 | 25 | export default tocCtrl 26 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/searchIcons/iconWord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/pref_spellcheck.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/dataCenter/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "imageFolderPath": { 3 | "description": "The image folder to store local images.", 4 | "type": "string" 5 | }, 6 | "screenshotFolderPath": { 7 | "description": "The place to store screen capture images.", 8 | "type": "string" 9 | }, 10 | "webImages": { 11 | "description": "Images from web which you used in MarkText", 12 | "type": "array" 13 | }, 14 | "cloudImages": { 15 | "description": "Images which you upload to cloud", 16 | "type": "array" 17 | }, 18 | "currentUploader": { 19 | "description": "The current image uploader", 20 | "type": "string" 21 | }, 22 | "imageBed": { 23 | "description": "The image bed configration", 24 | "type": "object" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/index.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used specifically and only for development. It installs 3 | * `vue-devtools`. There shouldn't be any need to modify this file, 4 | * but it can be used to extend your development environment. 5 | */ 6 | 7 | /* eslint-disable */ 8 | require('dotenv').config() 9 | 10 | // Install `vue-devtools` 11 | require('electron').app.on('ready', () => { 12 | const { default: installExtension, VUEJS_DEVTOOLS } = require('electron-devtools-installer') 13 | installExtension(VUEJS_DEVTOOLS) 14 | .then(() => {}) 15 | .catch(err => { 16 | console.log('Unable to install `vue-devtools`: \n', err) 17 | }) 18 | }) 19 | 20 | /* eslint-enable */ 21 | 22 | // Require `main` process to boot app 23 | require('./index') 24 | -------------------------------------------------------------------------------- /src/muya/lib/parser/marked/README.md: -------------------------------------------------------------------------------- 1 | # Marked 2 | 3 | This folder contains a patched [Marked.js](https://github.com/markedjs/marked/) version based on `v0.8.2` and bug fixes from `v1.2.5`, no breaking changes from `v1.0.0` are included. 4 | 5 | ## Changes 6 | 7 | ### Features 8 | 9 | - Markdown Extra: frontmatter and inline and block math 10 | - GFM like: emojis 11 | 12 | ### (Inline) Lexer 13 | 14 | - `disableInline` mode 15 | - Custom list and list item implementation based on an older marked.js version 16 | - Slightly modified definition due `disableInline` 17 | - More token information like list item bullet type 18 | 19 | ### Renderer 20 | 21 | - Emoji renderer 22 | - Frontmatter renderer 23 | - Inline and block (`multiplemath`) math renderer 24 | 25 | ## License 26 | 27 | [MIT](LICENSE) 28 | -------------------------------------------------------------------------------- /test/unit/data/common/CodeBlocks.md: -------------------------------------------------------------------------------- 1 | # Code Blocks 2 | 3 | ## Indent Code Block 4 | 5 | This line won't *have any markdown* formatting applied. 6 | I can even write HTML and it will show up as text. 7 | This is great for showing program source code, or HTML or even 8 | Markdown. this won't show up as HTML but 9 | exactly as you see it in this text file. 10 | 11 | Within a paragraph, you can use backquotes to do the same thing. 12 | `This won't be *italic* or **bold** at all.` 13 | 14 | ## Fence Code Block 15 | 16 | ```cpp 17 | #include 18 | 19 | int main(int argc, const char* argv[]) { 20 | std::cout << "C++ code block test" << std::endl; 21 | return 0; 22 | } 23 | ``` 24 | 25 | ``` 26 | This is a code block without language identifier. 27 | ``` 28 | -------------------------------------------------------------------------------- /src/renderer/config.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | export const PATH_SEPARATOR = path.sep 3 | 4 | export const THEME_STYLE_ID = 'ag-theme' 5 | export const COMMON_STYLE_ID = 'ag-common-style' 6 | 7 | export const DEFAULT_EDITOR_FONT_FAMILY = '"Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, Segoe UI Emoji, Apple Color Emoji, "Noto Color Emoji"' 8 | export const DEFAULT_CODE_FONT_FAMILY = '"DejaVu Sans Mono", "Source Code Pro", "Droid Sans Mono", monospace' 9 | export const DEFAULT_STYLE = Object.freeze({ 10 | codeFontFamily: DEFAULT_CODE_FONT_FAMILY, 11 | codeFontSize: '14px', 12 | hideScrollbar: false, 13 | theme: 'light' 14 | }) 15 | 16 | export const railscastsThemes = Object.freeze(['dark', 'material-dark']) 17 | export const oneDarkThemes = Object.freeze(['one-dark']) 18 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/enter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/snabbdom.js: -------------------------------------------------------------------------------- 1 | import { 2 | init, 3 | classModule, 4 | attributesModule, 5 | datasetModule, 6 | propsModule, 7 | styleModule, 8 | eventListenersModule, 9 | h as sh, 10 | toVNode as sToVNode 11 | } from 'snabbdom' 12 | 13 | export const patch = init([ 14 | classModule, 15 | attributesModule, 16 | styleModule, 17 | propsModule, 18 | datasetModule, 19 | eventListenersModule 20 | ]) 21 | 22 | export const h = sh 23 | export const toVNode = sToVNode 24 | 25 | export const toHTML = require('snabbdom-to-html') // helper function for convert vnode to HTML string 26 | export const htmlToVNode = html => { // helper function for convert html to vnode 27 | const wrapper = document.createElement('div') 28 | wrapper.innerHTML = html 29 | 30 | return toVNode(wrapper).children 31 | } 32 | -------------------------------------------------------------------------------- /test/unit/data/common/Headings.md: -------------------------------------------------------------------------------- 1 | # Headings 2 | 3 | ## Setext heading 4 | 5 | This is a huge header 6 | === 7 | 8 | this is a smaller header 9 | --- 10 | 11 | header 12 | --- 13 | 14 | This is a huge header 15 | ================== 16 | 17 | this is a smaller header 18 | ------------------ 19 | 20 | ## Atx heading 21 | 22 | ## ATX Headings 23 | 24 | # foo 25 | 26 | bar 27 | 28 | ## foo 29 | 30 | bar 31 | 32 | ### foo 33 | 34 | bar 35 | 36 | #### foo 37 | 38 | bar 39 | 40 | ##### foo 41 | 42 | bar 43 | 44 | ###### foo 45 | 46 | bar 47 | 48 | ####### This isn't a heading 49 | 50 | bar 51 | 52 | #5 This isn't a heading 53 | 54 | #This isn't a heading 55 | 56 | ## Horizontal Rule 57 | 58 | --- 59 | 60 | foo 61 | 62 | --- 63 | 64 | bar 65 | 66 | ## Horizontal Rule 67 | 68 | - - - - -- --- --- ---- 69 | -------------------------------------------------------------------------------- /src/muya/lib/utils/url.js: -------------------------------------------------------------------------------- 1 | import { isValidAttribute } from '../utils/dompurify' 2 | import { isWin } from '../config' // __MARKTEXT_PATCH__ 3 | import { hasMarkdownExtension } from './markdownFile' // __MARKTEXT_PATCH__ 4 | 5 | export const sanitizeHyperlink = rawLink => { 6 | if (rawLink && typeof rawLink === 'string') { 7 | if (isValidAttribute('a', 'href', rawLink)) { 8 | return rawLink 9 | } 10 | 11 | // __MARKTEXT_PATCH__ 12 | if (isWin && /^[a-zA-Z]:[/\\].+/.test(rawLink) && hasMarkdownExtension(rawLink)) { 13 | // Create and try UNC path on Windows because "C:\file.md" isn't allowed. 14 | const uncPath = `\\\\?\\${rawLink}` 15 | if (isValidAttribute('a', 'href', uncPath)) { 16 | return uncPath 17 | } 18 | } 19 | // END __MARKTEXT_PATCH__ 20 | } 21 | return '' 22 | } 23 | -------------------------------------------------------------------------------- /src/muya/lib/eventHandler/resize.js: -------------------------------------------------------------------------------- 1 | // import resizeCodeBlockLineNumber from '../utils/resizeCodeLineNumber' 2 | // import { throttle } from '../utils' 3 | 4 | class Resize { 5 | constructor (muya) { 6 | this.muya = muya 7 | this.listen() 8 | } 9 | 10 | listen () { 11 | // FIXME: Disabled due to #1648. 12 | // const { codeBlockLineNumbers } = this.muya.options 13 | // if (!codeBlockLineNumbers) { 14 | // return 15 | // } 16 | // 17 | // window.addEventListener('resize', throttle(() => { 18 | // const codeBlocks = document.querySelectorAll('pre.line-numbers') 19 | // if (codeBlocks.length) { 20 | // for (const ele of codeBlocks) { 21 | // resizeCodeBlockLineNumber(ele) 22 | // } 23 | // } 24 | // }, 300)) 25 | } 26 | } 27 | 28 | export default Resize 29 | -------------------------------------------------------------------------------- /src/muya/lib/ui/tableTools/config.js: -------------------------------------------------------------------------------- 1 | export const toolList = { 2 | left: [{ 3 | label: 'Insert Row Above', 4 | action: 'insert', 5 | location: 'previous', 6 | target: 'row' 7 | }, { 8 | label: 'Insert Row Below', 9 | action: 'insert', 10 | location: 'next', 11 | target: 'row' 12 | }, { 13 | label: 'Remove Row', 14 | action: 'remove', 15 | location: 'current', 16 | target: 'row' 17 | }], 18 | bottom: [{ 19 | label: 'Insert Column Left', 20 | action: 'insert', 21 | location: 'left', 22 | target: 'column' 23 | }, { 24 | label: 'Insert Column Right', 25 | action: 'insert', 26 | location: 'right', 27 | target: 'column' 28 | }, { 29 | label: 'Remove Column', 30 | action: 'remove', 31 | location: 'current', 32 | target: 'column' 33 | }] 34 | } 35 | -------------------------------------------------------------------------------- /src/renderer/components/sideBar/icon.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 29 | 30 | 36 | -------------------------------------------------------------------------------- /test/unit/data/common/BasicTextFormatting.md: -------------------------------------------------------------------------------- 1 | ## Basic Text Formatting 2 | 3 | **Strong** text __Also Strong__ 4 | 5 | ~~strike~~ and `inline code` 6 | 7 | under line and 43 H2O 8 | 9 | *this is in italic* and _so is this_ 10 | 11 | **this is in bold** and __so is this__ 12 | 13 | ***this is bold and italic*** and ___so is this___ 14 | 15 | this will be bold 16 | 17 | this will be bold 18 | 19 | this is strike through text 20 | 21 | So _a_ single _word_ followed _b_y _a_nother 22 | 23 | So __a__ single __word__ followed __b__y __a__nother 24 | 25 | ## Some markdown extentions 26 | 27 | This is emoji :man: 28 | 29 | This is inline math $a \ne b$ 30 | 31 | ## Paragraph 32 | 33 | A two trailing spaces and a new line 34 | makes a line break. 35 | 36 | Two new lines make a new paragraph. 37 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/todolist.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/image.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/ui/tooltip/index.css: -------------------------------------------------------------------------------- 1 | .ag-tooltip { 2 | transition: opacity .2s ease-in; 3 | position: absolute; 4 | font-size: 12px; 5 | padding: 5px 7px; 6 | border-radius: 5px; 7 | background: var(--floatBgColor); 8 | color: var(--editorColor); 9 | box-shadow: 0 4px 8px 0 var(--floatBorderColor); 10 | border: 1px solid var(--floatBorderColor); 11 | box-sizing: border-box; 12 | z-index: 1000; 13 | opacity: 0; 14 | } 15 | 16 | .ag-tooltip.active { 17 | opacity: 1; 18 | transform: translateY(-5px); 19 | } 20 | 21 | .ag-tooltip:after { 22 | top: -2px; 23 | left: 50%; 24 | content: ''; 25 | background: inherit; 26 | border: 1px solid var(--floatBorderColor); 27 | border-right: none; 28 | border-bottom: none; 29 | width: 8px; 30 | height: 8px; 31 | position: absolute; 32 | display: block; 33 | transform: rotate(45deg) translateX(-50%); 34 | } 35 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_underline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/autoLinkExtension.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | import { sanitizeHyperlink } from '../../../utils/url' 3 | 4 | // render auto_link to vdom 5 | export default function autoLinkExtension (h, cursor, block, token, outerClass) { 6 | const { linkType, www, url, email } = token 7 | const { start, end } = token.range 8 | 9 | const content = this.highlight(h, block, start, end, token) 10 | const hyperlink = linkType === 'www' ? encodeURI(`http://${www}`) : (linkType === 'url' ? encodeURI(url) : `mailto:${email}`) 11 | 12 | return [ 13 | h(`a.${CLASS_OR_ID.AG_INLINE_RULE}.${CLASS_OR_ID.AG_AUTO_LINK_EXTENSION}`, { 14 | attrs: { 15 | spellcheck: 'false' 16 | }, 17 | props: { 18 | href: sanitizeHyperlink(hyperlink), 19 | target: '_blank' 20 | } 21 | }, content) 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/services/notification/index.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 12 |
13 | {{title}} 14 | 17 |
18 |
19 |
{{message}}
20 |
21 | 24 |
25 |
26 |
27 |
-------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/inlineCode.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function inlineCode (h, cursor, block, token, outerClass) { 4 | const className = this.getClassName(outerClass, block, token, cursor) 5 | const { marker } = token 6 | const { start, end } = token.range 7 | 8 | const startMarker = this.highlight(h, block, start, start + marker.length, token) 9 | const endMarker = this.highlight(h, block, end - marker.length, end, token) 10 | const content = this.highlight(h, block, start + marker.length, end - marker.length, token) 11 | 12 | return [ 13 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, startMarker), 14 | h(`code.${CLASS_OR_ID.AG_INLINE_RULE}`, { 15 | attrs: { 16 | spellcheck: 'false' 17 | } 18 | }, content), 19 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, endMarker) 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/pref_image.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/specs/gfm/compare.marked.md: -------------------------------------------------------------------------------- 1 | ## Compare with `marked.js` 2 | 3 | Marked.js failed examples count: 1 4 | MarkText failed examples count: 0 5 | 6 | **Example653** 7 | 8 | MarkText success and marked.js fail 9 | 10 | ```markdown 11 | Markdown content 12 | <style> <em> 13 | 14 | <blockquote> 15 | <xmp> is disallowed. <XMP> is also disallowed. 16 | </blockquote> 17 | Expected Html 18 | <p><strong> <title> <style> <em></p> 19 | <blockquote> 20 | <xmp> is disallowed. <XMP> is also disallowed. 21 | </blockquote> 22 | Actural Html 23 | <p><strong> <title> <style> <em></p> 24 | <blockquote> 25 | <xmp> is disallowed. <XMP> is also disallowed. 26 | </blockquote> 27 | marked.js html 28 | <p><strong> <title> <style> <em></p> 29 | <blockquote> 30 | <xmp> is disallowed. <XMP> is also disallowed. 31 | </blockquote> 32 | ``` 33 | 34 | There are 1 examples are different with marked.js. -------------------------------------------------------------------------------- /src/renderer/assets/icons/files.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M963.2 796.8c0 22.4-12.8 70.4-73.6 70.4h-28.8V268.8c3.2-83.2-44.8-160-144-160H220.8v-16c0-51.2 28.8-80 76.8-80h512c96 0 156.8 76.8 156.8 166.4v617.6z" /><path d="M806.4 940.8c0 22.4-12.8 70.4-73.6 70.4H147.2c-64 0-86.4-25.6-86.4-86.4V236.8c0-51.2 28.8-80 76.8-80h553.6c73.6 0 115.2 60.8 115.2 112v672z m-112-480c0-19.2-16-32-35.2-32H272c-19.2 0-35.2 16-35.2 32 0 19.2 16 32 35.2 32h387.2c19.2 0 35.2-16 35.2-32z m0 179.2c0-19.2-16-32-35.2-32H208c-19.2 0-35.2 16-35.2 32 0 19.2 16 32 35.2 32h451.2c19.2 0 35.2-12.8 35.2-32z m0 179.2c0-16-16-32-35.2-32H208c-19.2 0-35.2 12.8-35.2 32 0 16 16 32 35.2 32h451.2c19.2 0 35.2-12.8 35.2-32z" /></svg> 2 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/pref_lineheight.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M179.42702 205.00814 102.678032 307.33876 164.076404 307.33876 164.076404 716.66124 102.678032 716.66124 179.42702 818.99186 256.173962 716.66124 194.77559 716.66124 194.77559 307.33876 256.173962 307.33876ZM102.678032 102.33062l818.644959 0 0 30.699186-818.644959 0 0-30.699186ZM102.678032 890.970194l818.644959 0 0 30.699186-818.644959 0 0-30.699186ZM683.91493 256.17345 531.800463 256.17345l-186.242751 511.653099 99.765191 0 50.167586-142.602835L716.785571 625.223714l50.16861 142.602835 103.202477 0L683.91493 256.17345zM526.202978 538.654057l67.264986-187.677427 25.296129 0 67.007113 187.677427L526.202978 538.654057z" /></svg> 2 | -------------------------------------------------------------------------------- /src/renderer/contextMenu/sideBar/index.js: -------------------------------------------------------------------------------- 1 | import { getCurrentWindow, Menu as RemoteMenu, MenuItem as RemoteMenuItem } from '@electron/remote' 2 | import { 3 | SEPARATOR, 4 | NEW_FILE, 5 | NEW_DIRECTORY, 6 | COPY, 7 | CUT, 8 | PASTE, 9 | RENAME, 10 | DELETE, 11 | SHOW_IN_FOLDER 12 | } from './menuItems' 13 | 14 | export const showContextMenu = (event, hasPathCache) => { 15 | const menu = new RemoteMenu() 16 | const win = getCurrentWindow() 17 | const CONTEXT_ITEMS = [ 18 | NEW_FILE, 19 | NEW_DIRECTORY, 20 | SEPARATOR, 21 | COPY, 22 | CUT, 23 | PASTE, 24 | SEPARATOR, 25 | RENAME, 26 | DELETE, 27 | SEPARATOR, 28 | SHOW_IN_FOLDER 29 | ] 30 | 31 | PASTE.enabled = hasPathCache 32 | 33 | CONTEXT_ITEMS.forEach(item => { 34 | menu.append(new RemoteMenuItem(item)) 35 | }) 36 | menu.popup([{ window: win, x: event.clientX, y: event.clientY }]) 37 | } 38 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/header.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function header (h, cursor, block, token, outerClass) { 4 | const { content } = token 5 | const { start, end } = token.range 6 | const className = this.getClassName(outerClass, block, { 7 | range: { 8 | start, 9 | end: end - content.length 10 | } 11 | }, cursor) 12 | const markerVnode = this.highlight(h, block, start, end - content.length, token) 13 | const contentVnode = this.highlight(h, block, end - content.length, end, token) 14 | const spaceSelector = className === CLASS_OR_ID.AG_HIDE 15 | ? `span.${CLASS_OR_ID.AG_HEADER_TIGHT_SPACE}.${CLASS_OR_ID.AG_REMOVE}` 16 | : `span.${CLASS_OR_ID.AG_GRAY}.${CLASS_OR_ID.AG_REMOVE}` 17 | 18 | return [ 19 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, markerVnode), 20 | h(spaceSelector, contentVnode) 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/muya/lib/ui/tableTools/index.css: -------------------------------------------------------------------------------- 1 | .ag-table-bar-tools { 2 | width: 150px; 3 | } 4 | .ag-table-bar-tools ul, 5 | .ag-table-bar-tools li { 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | .ag-table-bar-tools ul { 11 | padding: 5px 0; 12 | } 13 | 14 | .ag-table-bar-tools li.item { 15 | height: 25px; 16 | line-height: 25px; 17 | color: var(--editorColor); 18 | padding: 0 8px; 19 | cursor: pointer; 20 | position: relative; 21 | font-size: 13px; 22 | } 23 | 24 | .ag-table-bar-tools li.item[data-label=remove] { 25 | margin-top: 10px; 26 | } 27 | 28 | .ag-table-bar-tools li.item[data-label=remove]::before { 29 | content: ''; 30 | width: calc(100% - 16px); 31 | position: absolute; 32 | height: 1px; 33 | background: var(--editorColor04); 34 | top: -5px; 35 | display: block; 36 | left: 8px; 37 | } 38 | 39 | .ag-table-bar-tools li.item:hover { 40 | background-color: var(--floatHoverColor); 41 | } 42 | -------------------------------------------------------------------------------- /docs/CLI.md: -------------------------------------------------------------------------------- 1 | # Command Line Interface 2 | 3 | ``` 4 | Usage: marktext [commands] [path ...] 5 | 6 | Available commands: 7 | 8 | --debug Enable debug mode 9 | --safe Disable plugins and other user configuration 10 | -n, --new-window Open a new window on second-instance 11 | --user-data-dir Change the user data directory 12 | --disable-gpu Disable GPU hardware acceleration 13 | -v, --verbose Be verbose 14 | --version Print version information 15 | -h, --help Print this help message 16 | ``` 17 | 18 | `marktext` should point to your installation of MarkText. The exact location will vary from platform to platform. On macOS, you can create a convenient alias like: 19 | 20 | ```sh 21 | alias marktext="/Applications/Mark\ Text.app/Contents/MacOS/Mark\ Text" 22 | ``` 23 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/pref_email.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M981.333333 255.2c-0.533333-70.133333-57.6-127.2-128-127.2H170.666667c-70.4 0-127.466667 56.8-128 127.2V768c0 70.666667 57.333333 128 128 128h682.666666c70.666667 0 128-57.333333 128-128V256.533333v-1.333333zM170.666667 213.333333h682.666666c16.8 0 31.2 9.6 38.133334 23.733334L512 502.666667 132.533333 237.066667c6.933333-14.133333 21.333333-23.733333 38.133334-23.733334z m682.666666 597.333334H170.666667c-23.466667 0-42.666667-19.2-42.666667-42.666667V337.866667l359.466667 251.733333c7.466667 5.066667 16 7.733333 24.533333 7.733333s17.066667-2.666667 24.533333-7.733333L896 337.866667V768c0 23.466667-19.2 42.666667-42.666667 42.666667z" /></svg> 2 | -------------------------------------------------------------------------------- /src/renderer/contextMenu/sideBar/actions.js: -------------------------------------------------------------------------------- 1 | import bus from '../../bus' 2 | 3 | export const newFile = (menuItem, browserWindow) => { 4 | bus.$emit('SIDEBAR::new', 'file') 5 | } 6 | 7 | export const newDirectory = (menuItem, browserWindow) => { 8 | bus.$emit('SIDEBAR::new', 'directory') 9 | } 10 | 11 | export const copy = (menuItem, browserWindow) => { 12 | bus.$emit('SIDEBAR::copy-cut', 'copy') 13 | } 14 | 15 | export const cut = (menuItem, browserWindow) => { 16 | bus.$emit('SIDEBAR::copy-cut', 'cut') 17 | } 18 | 19 | export const paste = (menuItem, browserWindow) => { 20 | bus.$emit('SIDEBAR::paste') 21 | } 22 | 23 | export const rename = (menuItem, browserWindow) => { 24 | bus.$emit('SIDEBAR::rename') 25 | } 26 | 27 | export const remove = (menuItem, browserWindow) => { 28 | bus.$emit('SIDEBAR::remove') 29 | } 30 | 31 | export const showInFolder = (menuItem, browserWindow) => { 32 | bus.$emit('SIDEBAR::show-in-folder') 33 | } 34 | -------------------------------------------------------------------------------- /src/renderer/util/themeColor.js: -------------------------------------------------------------------------------- 1 | import darkTheme from '../assets/themes/dark.theme.css' 2 | import graphiteTheme from '../assets/themes/graphite.theme.css' 3 | import materialDarkTheme from '../assets/themes/material-dark.theme.css' 4 | import oneDarkTheme from '../assets/themes/one-dark.theme.css' 5 | import ulyssesTheme from '../assets/themes/ulysses.theme.css' 6 | 7 | import darkPrismTheme from '../assets/themes/prismjs/dark.theme.css' 8 | import oneDarkPrismTheme from '../assets/themes/prismjs/one-dark.theme.css' 9 | 10 | export const dark = () => { 11 | return darkTheme + '\n' + darkPrismTheme 12 | } 13 | 14 | export const graphite = () => { 15 | return graphiteTheme 16 | } 17 | 18 | export const materialDark = () => { 19 | return materialDarkTheme + '\n' + darkPrismTheme 20 | } 21 | 22 | export const oneDark = () => { 23 | return oneDarkTheme + '\n' + oneDarkPrismTheme 24 | } 25 | 26 | export const ulysses = () => { 27 | return ulyssesTheme 28 | } 29 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/sequence.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895472381" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M358.4 256h460.8v51.2H358.4zM358.4 665.6h460.8v51.2H358.4zM358.4 358.4h256v51.2H358.4zM358.4 768h256v51.2H358.4z" fill="#000000" p-id="4315"></path><path d="M153.6 409.6h51.2v204.8H153.6zM153.6 153.6h51.2v102.4H153.6zM153.6 768h51.2v102.4H153.6z" fill="#000000" p-id="4316"></path><path d="M179.2 435.2a102.4 102.4 0 1 1 0-204.8 102.4 102.4 0 0 1 0 204.8z m0-51.2a51.2 51.2 0 1 0 0-102.4 51.2 51.2 0 0 0 0 102.4zM179.2 793.6a102.4 102.4 0 1 1 0-204.8 102.4 102.4 0 0 1 0 204.8z m0-51.2a51.2 51.2 0 1 0 0-102.4 51.2 51.2 0 0 0 0 102.4z" fill="#000000" p-id="4317"></path></svg> -------------------------------------------------------------------------------- /src/renderer/util/clipboard.js: -------------------------------------------------------------------------------- 1 | import { isLinux, isOsx, isWindows } from './index' 2 | import plist from 'plist' 3 | import { clipboard as remoteClipboard } from '@electron/remote' 4 | 5 | const hasClipboardFiles = () => { 6 | return remoteClipboard.has('NSFilenamesPboardType') 7 | } 8 | 9 | const getClipboardFiles = () => { 10 | if (!hasClipboardFiles()) { return [] } 11 | return plist.parse(remoteClipboard.read('NSFilenamesPboardType')) 12 | } 13 | 14 | export const guessClipboardFilePath = () => { 15 | if (isLinux) return '' 16 | if (isOsx) { 17 | const result = getClipboardFiles() 18 | return Array.isArray(result) && result.length ? result[0] : '' 19 | } else if (isWindows) { 20 | const rawFilePath = remoteClipboard.read('FileNameW') 21 | const filePath = rawFilePath.replace(new RegExp(String.fromCharCode(0), 'g'), '') 22 | return filePath && typeof filePath === 'string' ? filePath : '' 23 | } else { 24 | return '' 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/new_table.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1553742013821" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3934" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M153.6 256a51.2 51.2 0 0 0-51.2 51.2v460.8a51.2 51.2 0 0 0 51.2 51.2h716.8a51.2 51.2 0 0 0 51.2-51.2V307.2a51.2 51.2 0 0 0-51.2-51.2H153.6z m0-51.2h716.8a102.4 102.4 0 0 1 102.4 102.4v460.8a102.4 102.4 0 0 1-102.4 102.4H153.6a102.4 102.4 0 0 1-102.4-102.4V307.2a102.4 102.4 0 0 1 102.4-102.4z" fill="#000000" p-id="3935"></path><path d="M51.2 358.4h921.6V256a102.4 102.4 0 0 0-102.4-102.4H153.6a102.4 102.4 0 0 0-102.4 102.4v102.4zM102.4 563.2h819.2v51.2H102.4z" fill="#000000" p-id="3936"></path><path d="M486.4 844.8v-614.4h51.2v614.4z" fill="#000000" p-id="3937"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/table_add.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895651482" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6839" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M153.6 256a51.2 51.2 0 0 0-51.2 51.2v460.8a51.2 51.2 0 0 0 51.2 51.2h716.8a51.2 51.2 0 0 0 51.2-51.2V307.2a51.2 51.2 0 0 0-51.2-51.2H153.6z m0-51.2h716.8a102.4 102.4 0 0 1 102.4 102.4v460.8a102.4 102.4 0 0 1-102.4 102.4H153.6a102.4 102.4 0 0 1-102.4-102.4V307.2a102.4 102.4 0 0 1 102.4-102.4z" fill="#000000" p-id="6840"></path><path d="M51.2 358.4h921.6V256a102.4 102.4 0 0 0-102.4-102.4H153.6a102.4 102.4 0 0 0-102.4 102.4v102.4zM102.4 563.2h819.2v51.2H102.4z" fill="#000000" p-id="6841"></path><path d="M486.4 844.8v-614.4h51.2v614.4z" fill="#000000" p-id="6842"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/superSubScript.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function superSubScript (h, cursor, block, token, outerClass) { 4 | const className = this.getClassName(outerClass, block, token, cursor) 5 | const { marker } = token 6 | const { start, end } = token.range 7 | 8 | const startMarker = this.highlight(h, block, start, start + marker.length, token) 9 | const endMarker = this.highlight(h, block, end - marker.length, end, token) 10 | const content = this.highlight(h, block, start + marker.length, end - marker.length, token) 11 | const tagName = marker === '^' ? 'sup' : 'sub' 12 | 13 | return [ 14 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, startMarker), 15 | h(`${tagName}.${CLASS_OR_ID.AG_INLINE_RULE}`, { 16 | attrs: { 17 | spellcheck: 'false' 18 | } 19 | }, content), 20 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, endMarker) 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /test/specs/help.js: -------------------------------------------------------------------------------- 1 | export const removeCustomClass = html => { 2 | const customClass = ['indented-code-block', 'fenced-code-block', 'task-list-item'] 3 | customClass.forEach(className => { 4 | if (html.indexOf(className) > -1) { 5 | const REG_EXP = new RegExp(`class="${className}"`, 'g') 6 | /* eslint-disable no-useless-escape */ 7 | const REG_EXP_SIMPLE = new RegExp(className + ' \*', 'g') 8 | /* eslint-enable no-useless-escape */ 9 | html = html.replace(REG_EXP, '') 10 | .replace(REG_EXP_SIMPLE, '') 11 | } 12 | }) 13 | return html 14 | } 15 | 16 | export const padding = (str, len, marker = ' ') => { 17 | const spaceLen = len - str.length 18 | let preLen = 0 19 | let postLen = 0 20 | if (spaceLen % 2 === 0) { 21 | preLen = postLen = spaceLen / 2 22 | } else { 23 | preLen = (spaceLen - 1) / 2 24 | postLen = (spaceLen + 1) / 2 25 | } 26 | return marker.repeat(preLen) + str + marker.repeat(postLen) 27 | } 28 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # User Documentation 2 | 3 | Welcome to the end-user documentation of MarkText. 4 | 5 | ![](assets/marktext-interface-2.png) 6 | 7 | **Quick start:** 8 | 9 | - [Basics](BASICS.md) 10 | - [Editing in depth](EDITING.md) 11 | - [Spelling](SPELLING.md) 12 | - [Markdown syntax](MARKDOWN_SYNTAX.md) 13 | 14 | **Further documents:** 15 | 16 | - [Frequently asked questions (FAQ)](FAQ.md) 17 | - [Application data directory](APPLICATION_DATA_DIRECTORY.md) 18 | - [Command line interface](CLI.md) 19 | - [Environment variables](ENVIRONMENT.md) 20 | - [Export a document](EXPORT.md) 21 | - [Image uploader configuration](IMAGE_UPLOADER_CONFIGRATION.md) 22 | - [Installation instructions](../README.md#download-and-installation) 23 | - [Key bindings](KEYBINDINGS.md) 24 | - [Portable mode](PORTABLE.md) 25 | - [Preferences](PREFERENCES.md) 26 | - [Themes](THEMES.md) 27 | - [Themes for exporting](EXPORT_THEMES.md) 28 | 29 | Interested in developer documentation? Please see [here](dev/README.md). 30 | -------------------------------------------------------------------------------- /src/renderer/store/notification.js: -------------------------------------------------------------------------------- 1 | import { ipcRenderer, shell } from 'electron' 2 | import notice from '../services/notification' 3 | 4 | const state = {} 5 | 6 | const getters = {} 7 | 8 | const mutations = {} 9 | 10 | const actions = { 11 | LISTEN_FOR_NOTIFICATION ({ commit }) { 12 | const DEFAULT_OPTS = { 13 | title: 'Infomation', 14 | type: 'primary', 15 | time: 10000, 16 | message: 'You should never see this message' 17 | } 18 | 19 | ipcRenderer.on('mt::show-notification', (e, opts) => { 20 | const options = Object.assign(DEFAULT_OPTS, opts) 21 | 22 | notice.notify(options) 23 | }) 24 | 25 | ipcRenderer.on('mt::pandoc-not-exists', async (e, opts) => { 26 | const options = Object.assign(DEFAULT_OPTS, opts) 27 | options.showConfirm = true 28 | await notice.notify(options) 29 | shell.openExternal('http://pandoc.org') 30 | }) 31 | } 32 | } 33 | 34 | export default { state, getters, mutations, actions } 35 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/footnoteIdentifier.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | 3 | export default function footnoteIdentifier (h, cursor, block, token, outerClass) { 4 | const className = this.getClassName(outerClass, block, token, cursor) 5 | const { marker } = token 6 | const { start, end } = token.range 7 | 8 | const startMarker = this.highlight(h, block, start, start + marker.length, token) 9 | const endMarker = this.highlight(h, block, end - 1, end, token) 10 | const content = this.highlight(h, block, start + marker.length, end - 1, token) 11 | 12 | return [ 13 | h(`sup#noteref-${token.content}.${CLASS_OR_ID.AG_INLINE_FOOTNOTE_IDENTIFIER}.${CLASS_OR_ID.AG_INLINE_RULE}`, [ 14 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, startMarker), 15 | h('a', { 16 | attrs: { 17 | spellcheck: 'false' 18 | } 19 | }, content), 20 | h(`span.${className}.${CLASS_OR_ID.AG_REMOVE}`, endMarker) 21 | ]) 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/copy.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554467898300" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2600" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M204.8 358.4a51.2 51.2 0 0 0-51.2 51.2v409.6a51.2 51.2 0 0 0 51.2 51.2h409.6a51.2 51.2 0 0 0 51.2-51.2V409.6a51.2 51.2 0 0 0-51.2-51.2H204.8z m0-51.2h409.6a102.4 102.4 0 0 1 102.4 102.4v409.6a102.4 102.4 0 0 1-102.4 102.4H204.8a102.4 102.4 0 0 1-102.4-102.4V409.6a102.4 102.4 0 0 1 102.4-102.4z" fill="#000000" p-id="2601"></path><path d="M766.1568 716.8H819.2a102.4 102.4 0 0 0 102.4-102.4V204.8a102.4 102.4 0 0 0-102.4-102.4H409.6a102.4 102.4 0 0 0-102.4 102.4v49.5104h51.2V204.8a51.2 51.2 0 0 1 51.2-51.2h409.6a51.2 51.2 0 0 1 51.2 51.2v409.6a51.2 51.2 0 0 1-51.2 51.2h-53.0432v51.2z" fill="#000000" p-id="2602"></path></svg> -------------------------------------------------------------------------------- /src/renderer/contextMenu/tabs/index.js: -------------------------------------------------------------------------------- 1 | import { getCurrentWindow, Menu as RemoteMenu, MenuItem as RemoteMenuItem } from '@electron/remote' 2 | import { 3 | CLOSE_THIS, 4 | CLOSE_OTHERS, 5 | CLOSE_SAVED, 6 | CLOSE_ALL, 7 | SEPARATOR, 8 | RENAME, 9 | COPY_PATH, 10 | SHOW_IN_FOLDER 11 | } from './menuItems' 12 | 13 | export const showContextMenu = (event, tab) => { 14 | const menu = new RemoteMenu() 15 | const win = getCurrentWindow() 16 | const { pathname } = tab 17 | const CONTEXT_ITEMS = [CLOSE_THIS, CLOSE_OTHERS, CLOSE_SAVED, CLOSE_ALL, SEPARATOR, RENAME, COPY_PATH, SHOW_IN_FOLDER] 18 | const FILE_CONTEXT_ITEMS = [RENAME, COPY_PATH, SHOW_IN_FOLDER] 19 | 20 | FILE_CONTEXT_ITEMS.forEach(item => { 21 | item.enabled = !!pathname 22 | }) 23 | 24 | CONTEXT_ITEMS.forEach(item => { 25 | const menuItem = new RemoteMenuItem(item) 26 | menuItem._tabId = tab.id 27 | menu.append(menuItem) 28 | }) 29 | menu.popup([{ window: win, x: event.clientX, y: event.clientY }]) 30 | } 31 | -------------------------------------------------------------------------------- /src/main/cli/parser.js: -------------------------------------------------------------------------------- 1 | import arg from 'arg' 2 | 3 | /** 4 | * Parse the given arguments or the default program arguments. 5 | * 6 | * @param {string[]} argv Arguments if null the default program arguments are used. 7 | * @param {boolean} permissive If set to false an exception is throw about unknown flags. 8 | * @returns {arg.Result} Parsed arguments 9 | */ 10 | const parseArgs = (argv = null, permissive = true) => { 11 | if (argv === null) { 12 | argv = process.argv.slice(1) 13 | } 14 | const spec = { 15 | '--debug': Boolean, 16 | '--safe': Boolean, 17 | 18 | '--new-window': Boolean, 19 | '-n': '--new-window', 20 | 21 | '--disable-gpu': Boolean, 22 | '--disable-spellcheck': Boolean, 23 | '--user-data-dir': String, 24 | 25 | // Misc 26 | '--help': Boolean, 27 | '-h': '--help', 28 | '--verbose': arg.COUNT, 29 | '-v': '--verbose', 30 | '--version': Boolean 31 | } 32 | return arg(spec, { argv, permissive }) 33 | } 34 | 35 | export default parseArgs 36 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/align_center.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895656395" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6950" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M256 204.8m25.6 0l460.8 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-460.8 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6951"></path><path d="M256 614.4m25.6 0l460.8 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-460.8 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6952"></path><path d="M102.4 819.2m25.6 0l768 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-768 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6953"></path><path d="M153.6 409.6m25.6 0l665.6 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-665.6 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6954"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/align_left.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895639880" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6615" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M102.4 204.8m25.6 0l460.8 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-460.8 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6616"></path><path d="M102.4 614.4m25.6 0l460.8 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-460.8 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6617"></path><path d="M102.4 819.2m25.6 0l768 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-768 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6618"></path><path d="M102.4 409.6m25.6 0l665.6 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-665.6 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6619"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/align_right.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895644652" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6727" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M409.6 204.8m25.6 0l460.8 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-460.8 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6728"></path><path d="M409.6 614.4m25.6 0l460.8 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-460.8 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6729"></path><path d="M102.4 819.2m25.6 0l768 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-768 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6730"></path><path d="M204.8 409.6m25.6 0l665.6 0q25.6 0 25.6 25.6l0 0q0 25.6-25.6 25.6l-665.6 0q-25.6 0-25.6-25.6l0 0q0-25.6 25.6-25.6Z" fill="#000000" p-id="6731"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_clear.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895499290" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4757" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M358.4 849.92h563.2v51.2H358.4z" fill="#000000" p-id="4758"></path><path d="M137.5232 581.8368a51.2 51.2 0 0 0 0 72.3968l181.0432 180.992a51.2 51.2 0 0 0 72.3968 0l434.4832-434.432a51.2 51.2 0 0 0 0-72.3968l-181.0432-181.0432a51.2 51.2 0 0 0-72.3968 0l-434.4832 434.4832z m-36.1984-36.1984l434.4832-434.4832a102.4 102.4 0 0 1 144.7936 0l181.0432 181.0432a102.4 102.4 0 0 1 0 144.7936L427.1616 871.424a102.4 102.4 0 0 1-144.7936 0l-181.0432-180.992a102.4 102.4 0 0 1 0-144.7936z" fill="#000000" p-id="4759"></path><path d="M193.792 484.7104l36.1984-36.1984 300.6976 300.7488-36.2496 36.1984z" fill="#000000" p-id="4760"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_link.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895479773" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4425" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M487.936 570.2144l-33.8432 38.4-34.048-30.208a227.1744 227.1744 0 0 1 0-321.28l81.408-81.4592a227.1744 227.1744 0 1 1 321.3312 321.28l-81.408 81.4592-36.2496-36.1984L786.5856 460.8a176.0256 176.0256 0 0 0-248.8832-248.9344L456.192 293.2736c-68.7616 68.7616-68.7616 180.224-1.1776 247.8592l32.9216 29.0816z m21.3504-140.8l32.512-39.6288 36.608 30.208a227.1744 227.1744 0 0 1 0 321.3312l-81.408 81.4592A227.1744 227.1744 0 1 1 175.616 501.504l81.408-81.4592 36.2496 36.1984-81.4592 81.408a175.9744 175.9744 0 1 0 248.8832 248.9344l81.4592-81.408c68.7616-68.7616 68.7616-180.224 1.8944-247.296l-34.816-28.4672z" fill="#000000" p-id="4426"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/backlashInToken.js: -------------------------------------------------------------------------------- 1 | import { union, isEven } from '../../../utils' 2 | import { CLASS_OR_ID } from '../../../config' 3 | // TODO HIGHLIGHT 4 | export default function backlashInToken (h, backlashes, outerClass, start, token) { 5 | const { highlights = [] } = token 6 | const chunks = backlashes.split('') 7 | const len = chunks.length 8 | const result = [] 9 | let i 10 | 11 | for (i = 0; i < len; i++) { 12 | const chunk = chunks[i] 13 | const light = highlights.filter(light => union({ start: start + i, end: start + i + 1 }, light)) 14 | let selector = 'span' 15 | if (light.length) { 16 | const className = this.getHighlightClassName(light[0].active) 17 | selector += `.${className}` 18 | } 19 | if (isEven(i)) { 20 | result.push( 21 | h(`${selector}.${outerClass}`, chunk) 22 | ) 23 | } else { 24 | result.push( 25 | h(`${selector}.${CLASS_OR_ID.AG_BACKLASH}`, chunk) 26 | ) 27 | } 28 | } 29 | 30 | return result 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a bug report to help us improve 4 | --- 5 | 6 | <!-- 7 | - Please search for issues that matches the one you want to file and use the thumbs up emoji. 8 | - Please make sure your application version is up to date. 9 | --> 10 | 11 | ### Description 12 | 13 | <!-- Description of the bug --> 14 | 15 | - [ ] Can you reproduce the issue? <!-- no: `[ ]` or yes: `[x]` --> 16 | 17 | ### Steps to reproduce 18 | 19 | <!-- Steps how the issue occurred. --> 20 | 21 | 1. [First step] 22 | 2. [Second step] 23 | 3. [and so on...] 24 | 25 | **Expected behavior:** 26 | 27 | <!-- What you expected to happen --> 28 | 29 | **Actual behavior:** 30 | 31 | <!-- What actually happened --> 32 | 33 | **Link to an example: [optional]** 34 | 35 | <!-- If you're reporting a bug that's not reproducible, or it's hard to description, please paste a screenshot of reproducing this issue - gif format is appropriate --> 36 | 37 | ### Versions 38 | 39 | - MarkText version: 40 | - Operating system: 41 | -------------------------------------------------------------------------------- /src/common/keybinding/index.js: -------------------------------------------------------------------------------- 1 | const isOsx = process.platform === 'darwin' 2 | 3 | const _normalizeAccelerator = accelerator => { 4 | return accelerator.toLowerCase() 5 | .replace('commandorcontrol', isOsx ? 'cmd' : 'ctrl') 6 | .replace('cmdorctrl', isOsx ? 'cmd' : 'ctrl') 7 | .replace('control', 'ctrl') 8 | .replace('meta', 'cmd') // meta := cmd (macOS only) or super 9 | .replace('command', 'cmd') 10 | .replace('option', 'alt') 11 | } 12 | 13 | export const isEqualAccelerator = (a, b) => { 14 | a = _normalizeAccelerator(a) 15 | b = _normalizeAccelerator(b) 16 | const i1 = a.indexOf('+') 17 | const i2 = b.indexOf('+') 18 | if (i1 === -1 && i2 === -1) { 19 | return a === b 20 | } else if (i1 === -1 || i2 === -1) { 21 | return false 22 | } 23 | 24 | const partsA = a.split('+') 25 | const partsB = b.split('+') 26 | if (partsA.length !== partsB.length) { 27 | return false 28 | } 29 | 30 | const intersection = new Set([...partsA, ...partsB]) 31 | return intersection.size === partsB.length 32 | } 33 | -------------------------------------------------------------------------------- /src/renderer/util/dompurify.js: -------------------------------------------------------------------------------- 1 | import runSanitize from 'muya/lib/utils/dompurify' 2 | 3 | export const PREVIEW_DOMPURIFY_CONFIG = Object.freeze({ 4 | FORBID_ATTR: ['style', 'contenteditable'], 5 | ALLOW_DATA_ATTR: false, 6 | USE_PROFILES: { 7 | html: true, 8 | svg: true, 9 | svgFilters: true, 10 | mathMl: false 11 | }, 12 | RETURN_TRUSTED_TYPE: false 13 | }) 14 | 15 | export const EXPORT_DOMPURIFY_CONFIG = Object.freeze({ 16 | FORBID_ATTR: ['contenteditable'], 17 | ALLOW_DATA_ATTR: false, 18 | ADD_ATTR: ['data-align'], 19 | USE_PROFILES: { 20 | html: true, 21 | svg: true, 22 | svgFilters: true, 23 | mathMl: false 24 | }, 25 | RETURN_TRUSTED_TYPE: false, 26 | // Allow "file" protocol to export images on Windows (#1997). 27 | ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|file):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape 28 | }) 29 | 30 | export const sanitize = (html, purifyOptions) => { 31 | return runSanitize(html, purifyOptions) 32 | } 33 | -------------------------------------------------------------------------------- /src/muya/lib/parser/marked/slugger.js: -------------------------------------------------------------------------------- 1 | import { downcode } from './urlify' 2 | 3 | /** 4 | * Slugger generates header id 5 | */ 6 | 7 | function Slugger () { 8 | this.seen = {} 9 | this.downcodeUnicode = true 10 | } 11 | 12 | /** 13 | * Convert string to unique id 14 | */ 15 | 16 | Slugger.prototype.slug = function (value) { 17 | let slug = this.downcodeUnicode ? downcode(value) : value 18 | slug = slug 19 | .toLowerCase() 20 | .trim() 21 | // remove html tags 22 | .replace(/<[!\/a-z].*?>/ig, '') // eslint-disable-line no-useless-escape 23 | // remove unwanted chars 24 | .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '') 25 | .replace(/\s/g, '-') 26 | 27 | if (this.seen.hasOwnProperty(slug)) { 28 | const originalSlug = slug 29 | do { 30 | this.seen[originalSlug]++ 31 | slug = originalSlug + '-' + this.seen[originalSlug] 32 | } while (this.seen.hasOwnProperty(slug)) 33 | } 34 | this.seen[slug] = 0 35 | 36 | return slug 37 | } 38 | 39 | export default Slugger 40 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/delete.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895674031" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7062" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M837.0176 256H186.9824l-26.0608 102.4h702.1056l-26.0096-102.4zM324.2496 204.8l22.528-67.3792A51.2 51.2 0 0 1 395.264 102.4h233.3696a51.2 51.2 0 0 1 48.5888 35.0208L699.7504 204.8h157.184a25.6 25.6 0 0 1 24.7808 19.3024l39.0656 153.6A25.6 25.6 0 0 1 896 409.6h-30.6176l-45.7216 465.8176a51.2 51.2 0 0 1-50.9952 46.1824h-517.12a51.2 51.2 0 0 1-50.9952-46.592L158.2592 409.6H128a25.6 25.6 0 0 1-24.832-31.8976l39.0656-153.6A25.6 25.6 0 0 1 167.1168 204.8h157.184z m53.9648 0h267.5712l-17.1008-51.2H395.3152l-17.1008 51.2z m435.712 204.8H209.664l41.8816 460.8h517.12l45.2608-460.8zM409.6 460.8h51.2v358.4H409.6V460.8z m153.6 0h51.2v358.4h-51.2V460.8z" fill="#000000" p-id="7063"></path></svg> -------------------------------------------------------------------------------- /test/e2e/xss.spec.js: -------------------------------------------------------------------------------- 1 | const { expect, test } = require('@playwright/test') 2 | const { launchElectron } = require('./helpers') 3 | 4 | test.describe('Test XSS Vulnerabilities', async () => { 5 | let app = null 6 | let page = null 7 | 8 | test.beforeAll(async () => { 9 | const { app: electronApp, page: firstPage } = await launchElectron(['test/e2e/data/xss.md']) 10 | app = electronApp 11 | page = firstPage 12 | 13 | // Wait to parse and render the document. 14 | await new Promise((resolve) => setTimeout(resolve, 3000)) 15 | }) 16 | 17 | test.afterAll(async () => { 18 | await app.close() 19 | }) 20 | 21 | test('Load malicious document', async () => { 22 | const { isVisible, isCrashed } = await app.evaluate(async process => { 23 | const mainWindow = process.BrowserWindow.getAllWindows()[0] 24 | return { 25 | isVisible: mainWindow.isVisible(), 26 | isCrashed: mainWindow.webContents.isCrashed() 27 | } 28 | }) 29 | 30 | expect(isVisible).toBeTruthy() 31 | expect(isCrashed).toBeFalsy() 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /src/muya/lib/ui/imageToolbar/config.js: -------------------------------------------------------------------------------- 1 | import editIcon from '../../assets/pngicon/imageEdit/2.png' 2 | import inlineIcon from '../../assets/pngicon/inline_image/2.png' 3 | import leftIcon from '../../assets/pngicon/algin_left/2.png' 4 | import middleIcon from '../../assets/pngicon/algin_center/2.png' 5 | import rightIcon from '../../assets/pngicon/algin_right/2.png' 6 | import deleteIcon from '../../assets/pngicon/image_delete/2.png' 7 | 8 | const icons = [ 9 | { 10 | type: 'edit', 11 | tooltip: 'Edit Image', 12 | icon: editIcon 13 | }, 14 | { 15 | type: 'inline', 16 | tooltip: 'Inline Image', 17 | icon: inlineIcon 18 | }, 19 | { 20 | type: 'left', 21 | tooltip: 'Align Left', 22 | icon: leftIcon 23 | }, 24 | { 25 | type: 'center', 26 | tooltip: 'Align Middle', 27 | icon: middleIcon 28 | }, 29 | { 30 | type: 'right', 31 | tooltip: 'Align Right', 32 | icon: rightIcon 33 | }, 34 | { 35 | type: 'delete', 36 | tooltip: 'Remove Image', 37 | icon: deleteIcon 38 | } 39 | ] 40 | 41 | export default icons 42 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/highlight.js: -------------------------------------------------------------------------------- 1 | import { union } from '../../../utils' 2 | 3 | // change text to highlight vdom 4 | export default function highlight (h, block, rStart, rEnd, token) { 5 | const { text } = block 6 | const { highlights } = token 7 | let result = [] 8 | const unions = [] 9 | let pos = rStart 10 | 11 | if (highlights) { 12 | for (const light of highlights) { 13 | const un = union({ start: rStart, end: rEnd }, light) 14 | if (un) unions.push(un) 15 | } 16 | } 17 | 18 | if (unions.length) { 19 | for (const u of unions) { 20 | const { start, end, active } = u 21 | const className = this.getHighlightClassName(active) 22 | 23 | if (pos < start) { 24 | result.push(text.substring(pos, start)) 25 | } 26 | 27 | result.push(h(`span.${className}`, text.substring(start, end))) 28 | pos = end 29 | } 30 | if (pos < rEnd) { 31 | result.push(block.text.substring(pos, rEnd)) 32 | } 33 | } else { 34 | result = [text.substring(rStart, rEnd)] 35 | } 36 | 37 | return result 38 | } 39 | -------------------------------------------------------------------------------- /docs/IMAGE_UPLOADER_CONFIGRATION.md: -------------------------------------------------------------------------------- 1 | #### Image Uploader Configration 2 | 3 | ##### PicGo 4 | 5 | PicGo is a CLI tool to upload images to various cloud providers. Please see [here](https://picgo.github.io/PicGo-Doc/en/guide/) of more information. 6 | 7 | ##### GitHub 8 | 9 | > NOTE: This uploader is deprecated and will be replaced by PicGo in version 0.18. 10 | 11 | 1. Step 1, Create a GitHub [repo](https://github.com/new). 12 | 13 | ![5ce17b03726c384991](https://i.loli.net/2019/05/19/5ce17b03726c384991.png) 14 | 15 | 2. Step 2, Create a GitHub token in [Settings/Developer settings.](https://github.com/settings/tokens) 16 | 17 | ![5ce17bd849d5589341](https://i.loli.net/2019/05/19/5ce17bd849d5589341.png) 18 | 19 | 3. Config in MarkText Preferences window. click `CmdOrCtrl + ,` to open MarkText Preferences window. 20 | 21 | ![5ce17cb97b0f111638](https://i.loli.net/2019/05/19/5ce17cb97b0f111638.png) 22 | 23 | 4. Input you `token`, `owner name` and `repo name` whick you just created. Click `Save` and `Set As default Uploader`. 24 | 25 | 5. Paste an image into MarkText and open you created repo to see the uploaded image. 26 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/header_2.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895618032" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6397" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M822.272 446.464c33.792 0 61.44 9.728 83.456 29.184 21.504 19.456 32.768 45.568 32.768 77.312s-12.288 60.416-35.84 86.016c-12.8 13.312-37.888 33.28-75.776 58.88-46.592 31.232-73.216 59.392-79.872 83.968h192V819.2h-243.712c0-33.28 11.776-63.488 36.352-90.624 14.336-16.384 40.448-38.4 79.36-65.024 28.672-20.48 47.616-35.328 57.344-45.568 18.432-19.968 28.16-41.984 28.16-65.536 0-22.528-6.656-39.424-19.968-51.712s-32.256-18.432-55.808-18.432c-25.088 0-44.544 8.192-57.856 25.6-14.336 16.384-22.016 40.96-22.528 73.216h-41.984c0-40.96 11.776-73.728 34.304-97.792 22.528-24.576 52.736-36.864 89.6-36.864zM51.2 153.6h51.2v306.944h461.2608V153.6H614.4v665.6h-50.7392v-306.4832H102.4V819.2H51.2z" fill="#000000" p-id="6398"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/parser/marked/index.js: -------------------------------------------------------------------------------- 1 | import Renderer from './renderer' 2 | import Lexer from './lexer' 3 | import Parser from './parser' 4 | import options from './options' 5 | 6 | /** 7 | * Marked 8 | */ 9 | 10 | function marked (src, opt = {}) { 11 | // throw error in case of non string input 12 | if (typeof src === 'undefined' || src === null) { 13 | throw new Error('marked(): input parameter is undefined or null') 14 | } 15 | if (typeof src !== 'string') { 16 | throw new Error('marked(): input parameter is of type ' + 17 | Object.prototype.toString.call(src) + ', string expected') 18 | } 19 | 20 | try { 21 | opt = Object.assign({}, options, opt) 22 | return new Parser(opt).parse(new Lexer(opt).lex(src)) 23 | } catch (e) { 24 | e.message += '\nPlease report this to https://github.com/marktext/marktext/issues.' 25 | if (opt.silent) { 26 | return '<p>An error occurred:</p><pre>' + 27 | escape(e.message + '', true) + 28 | '</pre>' 29 | } 30 | throw e 31 | } 32 | } 33 | 34 | export { 35 | Renderer, Lexer, Parser 36 | } 37 | 38 | export default marked 39 | -------------------------------------------------------------------------------- /src/renderer/commands/utils.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { isFile } from 'common/filesystem' 3 | 4 | /// Check whether the package is updatable at runtime. 5 | export const isUpdatable = () => { 6 | // TODO: If not updatable, allow to check whether there is a new version available. 7 | 8 | const resFile = isFile(path.join(process.resourcesPath, 'app-update.yml')) 9 | if (!resFile) { 10 | // No update resource file available. 11 | return false 12 | } else if (process.env.APPIMAGE) { 13 | // We are running as AppImage. 14 | return true 15 | } else if (process.platform === 'win32' && isFile(path.join(process.resourcesPath, 'md.ico'))) { 16 | // Windows is a little but tricky. The update resource file is always available and 17 | // there is no way to check the target type at runtime (electron-builder#4119). 18 | // As workaround we check whether "md.ico" exists that is only included in the setup. 19 | return true 20 | } 21 | 22 | // Otherwise assume that we cannot perform an auto update (standalone binary, archives, 23 | // packed for package manager). 24 | return false 25 | } 26 | -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_image.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895535011" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5304" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M204.8 204.8a51.2 51.2 0 0 0-51.2 51.2v563.2a51.2 51.2 0 0 0 51.2 51.2h614.4a51.2 51.2 0 0 0 51.2-51.2V256a51.2 51.2 0 0 0-51.2-51.2H204.8z m0-51.2h614.4a102.4 102.4 0 0 1 102.4 102.4v563.2a102.4 102.4 0 0 1-102.4 102.4H204.8a102.4 102.4 0 0 1-102.4-102.4V256a102.4 102.4 0 0 1 102.4-102.4z" fill="#000000" p-id="5305"></path><path d="M142.6432 738.816l-36.352-36.0448 205.1584-206.8992 144.3328 146.2784-36.4544 35.9424-107.9808-109.4144zM358.4 435.2a76.8 76.8 0 1 1 0-153.6 76.8 76.8 0 0 1 0 153.6z m0-51.2a25.6 25.6 0 1 0 0-51.2 25.6 25.6 0 0 0 0 51.2z" fill="#000000" p-id="5306"></path><path d="M673.3312 466.7392l-433.664 453.9392-37.0688-35.3792 469.504-491.4176 236.544 231.5776-35.7888 36.608z" fill="#000000" p-id="5307"></path></svg> -------------------------------------------------------------------------------- /.electron-vue/thirdPartyChecker.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const checker = require('license-checker') 4 | 5 | const getLicenses = (rootDir, callback) => { 6 | checker.init({ 7 | start: rootDir, 8 | production: true, 9 | development: false, 10 | direct: true, 11 | excludePackages: 'file-icons@2.1.47', // file-icons is under MIT License, but license-checker shows no license. 12 | json: true, 13 | onlyAllow: 'Unlicense;WTFPL;ISC;MIT;BSD;ISC;Apache-2.0;MIT*;Apache;Apache*;BSD*;CC0-1.0;CC-BY-4.0;CC-BY-3.0', 14 | customPath: { 15 | licenses: '', 16 | licenseText: 'none' 17 | } 18 | }, function (err, packages) { 19 | callback(err, packages, checker) 20 | }) 21 | } 22 | 23 | // Check that all production dependencies are allowed. 24 | const validateLicenses = rootDir => { 25 | getLicenses(rootDir, (err, packages, checker) => { 26 | if (err) { 27 | console.log(`[ERROR] ${err}`) 28 | process.exit(1) 29 | } 30 | console.log(checker.asSummary(packages)) 31 | }) 32 | } 33 | 34 | module.exports = { 35 | getLicenses: getLicenses, 36 | validateLicenses: validateLicenses 37 | } 38 | -------------------------------------------------------------------------------- /docs/KEYBINDINGS.md: -------------------------------------------------------------------------------- 1 | # Key Bindings 2 | 3 | All key bindings can be overwritten with the `keybindings.json` file. The file is located in the [application data directory](APPLICATION_DATA_DIRECTORY.md). Each entry consists of a `id`/`accelerator` pair in JSON format. 4 | 5 | Here is an example: 6 | 7 | ```json 8 | { 9 | "file.save": "CmdOrCtrl+Shift+S", 10 | "file.save-as": "CmdOrCtrl+S" 11 | } 12 | ``` 13 | 14 | ## Available modifiers 15 | 16 | - `Cmd` on macOS 17 | - `Option` on macOS 18 | - `Ctrl` 19 | - `Shift` 20 | - `Alt` (equal to `Option` on macOS) 21 | 22 | Please don't bind `AltGr`, use `Cltr+Alt` instead. 23 | 24 | ## Available keys 25 | 26 | - `0-9`, `A-Z`, `F1-F24` and punctuations like `/` or `#` 27 | - `Plus`, `Space`, `Tab`, `Backspace`, `Delete`, `Insert`, `Return/Enter`, `Esc`, `Home`, `End` and `PrintScreen` 28 | - `Up`, `Down`, `Left` and `Right` 29 | - `PageUp` and `PageDown` 30 | - Empty string `""` to unset a accelerator 31 | 32 | ## Available key bindings 33 | 34 | - [Key bindings for macOS](KEYBINDINGS_OSX.md) 35 | - [Key bindings for Linux](KEYBINDINGS_LINUX.md) 36 | - [Key bindings for Windows](KEYBINDINGS_WINDOWS.md) 37 | -------------------------------------------------------------------------------- /src/main/app/paths.js: -------------------------------------------------------------------------------- 1 | import { app } from 'electron' 2 | import EnvPaths from 'common/envPaths' 3 | import { ensureDirSync } from 'common/filesystem' 4 | 5 | class AppPaths extends EnvPaths { 6 | /** 7 | * Configure and sets all application paths. 8 | * 9 | * @param {[string]} userDataPath The user data path or null. 10 | */ 11 | constructor (userDataPath = '') { 12 | if (!userDataPath) { 13 | // Use default user data path. 14 | userDataPath = app.getPath('userData') 15 | } 16 | 17 | // Initialize environment paths 18 | super(userDataPath) 19 | 20 | // Changing the user data directory is only allowed during application bootstrap. 21 | app.setPath('userData', this._electronUserDataPath) 22 | } 23 | } 24 | 25 | export const ensureAppDirectoriesSync = paths => { 26 | ensureDirSync(paths.userDataPath) 27 | ensureDirSync(paths.logPath) 28 | // TODO(sessions): enable this... 29 | // ensureDirSync(paths.electronUserDataPath) 30 | // ensureDirSync(paths.globalStorage) 31 | // ensureDirSync(paths.preferencesPath) 32 | // ensureDirSync(paths.sessionsPath) 33 | } 34 | 35 | export default AppPaths 36 | -------------------------------------------------------------------------------- /src/muya/lib/parser/marked/options.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseUrl: null, 3 | breaks: false, 4 | gfm: true, 5 | headerIds: true, 6 | headerPrefix: '', 7 | highlight: null, 8 | mathRenderer: null, 9 | emojiRenderer: null, 10 | tocRenderer: null, 11 | langPrefix: 'language-', 12 | mangle: true, 13 | pedantic: false, 14 | renderer: null, // new Renderer(), 15 | silent: false, 16 | smartLists: false, 17 | smartypants: false, 18 | xhtml: false, 19 | disableInline: false, 20 | 21 | // NOTE: sanitize and sanitizer are deprecated since version 0.7.0, should not be used and will be removed in the future. 22 | sanitize: false, 23 | sanitizer: null, 24 | 25 | // Markdown extensions: 26 | // TODO: We set whether to support `emoji`, `math`, `frontMatter` default value to `true` 27 | // After we add user setting, we maybe set math and frontMatter default value to false. 28 | // User need to enable them in the user setting. 29 | emoji: true, 30 | math: true, 31 | frontMatter: true, 32 | superSubScript: false, 33 | footnote: false, 34 | isGitlabCompatibilityEnabled: false, 35 | 36 | isHtmlEnabled: true 37 | } 38 | -------------------------------------------------------------------------------- /src/muya/lib/ui/baseFloat/index.css: -------------------------------------------------------------------------------- 1 | .ag-float-wrapper { 2 | position: absolute; 3 | font-size: 12px; 4 | opacity: 0; 5 | width: 110px; 6 | height: auto; 7 | top: -1000px; 8 | right: -1000px; 9 | border-radius: 2px; 10 | box-shadow: var(--floatShadow); 11 | background-color: var(--floatBgColor); 12 | transition: opacity .25s ease-in-out; 13 | transform-origin: top; 14 | box-sizing: border-box; 15 | z-index: 10000; 16 | overflow: hidden; 17 | } 18 | 19 | .ag-float-container::-webkit-scrollbar:vertical { 20 | width: 0px; 21 | } 22 | 23 | [x-placement] { 24 | opacity: 1; 25 | } 26 | 27 | .ag-popper-arrow { 28 | width: 16px; 29 | height: 16px; 30 | background: inherit; 31 | border: 1px solid #ebeef5; 32 | display: inline-block; 33 | position: absolute; 34 | transform: rotate(45deg); 35 | } 36 | 37 | [x-placement="bottom-start"] > .ag-popper-arrow { 38 | border-right: none; 39 | border-bottom: none; 40 | top: -9px; 41 | } 42 | 43 | [x-placement="top-start"] > .ag-popper-arrow { 44 | border-left: none; 45 | border-top: none; 46 | bottom: -9px; 47 | } 48 | 49 | [x-out-of-boundaries] { 50 | display: none; 51 | } 52 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/autoLink.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | import { sanitizeHyperlink } from '../../../utils/url' 3 | 4 | // render auto_link to vdom 5 | export default function autoLink (h, cursor, block, token, outerClass) { 6 | const className = this.getClassName(outerClass, block, token, cursor) 7 | const { isLink, marker, href, email } = token 8 | const { start, end } = token.range 9 | 10 | const startMarker = this.highlight(h, block, start, start + marker.length, token) 11 | const endMarker = this.highlight(h, block, end - marker.length, end, token) 12 | const content = this.highlight(h, block, start + marker.length, end - marker.length, token) 13 | 14 | const hyperlink = isLink ? encodeURI(href) : `mailto:${email}` 15 | return [ 16 | h(`span.${className}`, startMarker), 17 | h(`a.${CLASS_OR_ID.AG_INLINE_RULE}.${CLASS_OR_ID.AG_AUTO_LINK}`, { 18 | attrs: { 19 | spellcheck: 'false' 20 | }, 21 | props: { 22 | href: sanitizeHyperlink(hyperlink), 23 | target: '_blank' 24 | } 25 | }, content), 26 | h(`span.${className}`, endMarker) 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/muya/lib/utils/getImageInfo.js: -------------------------------------------------------------------------------- 1 | import { isWin } from '../config' 2 | import { findNearestParagraph, getOffsetOfParagraph } from '../selection/dom' 3 | import { tokenizer } from '../parser' 4 | 5 | export const getImageInfo = image => { 6 | const paragraph = findNearestParagraph(image) 7 | const raw = image.getAttribute('data-raw') 8 | const offset = getOffsetOfParagraph(image, paragraph) 9 | const tokens = tokenizer(raw) 10 | const token = tokens[0] 11 | token.range = { 12 | start: offset, 13 | end: offset + raw.length 14 | } 15 | return { 16 | key: paragraph.id, 17 | token, 18 | imageId: image.id 19 | } 20 | } 21 | 22 | export const correctImageSrc = src => { 23 | if (src) { 24 | // Fix ASCII and UNC paths on Windows (#1997). 25 | if (isWin && /^(?:[a-zA-Z]:\\|[a-zA-Z]:\/).+/.test(src)) { 26 | src = 'file:///' + src.replace(/\\/g, '/') 27 | } else if (isWin && /^\\\\\?\\.+/.test(src)) { 28 | src = 'file:///' + src.substring(4).replace(/\\/g, '/') 29 | } else if (/^\/.+/.test(src)) { 30 | // Also adding file protocol on UNIX. 31 | src = 'file://' + src 32 | } 33 | } 34 | return src 35 | } 36 | -------------------------------------------------------------------------------- /docs/ENVIRONMENT.md: -------------------------------------------------------------------------------- 1 | # Environment 2 | 3 | | Name | Description | 4 | | ---------------------------- | ----------------------------------------------------------- | 5 | | `MARKTEXT_DEBUG` | Enable debug mode. | 6 | | `MARKTEXT_DEBUG_KEYBOARD` | Print more keyboard information when debug mode is enabled. | 7 | | `MARKTEXT_ERROR_INTERACTION` | Never show the error dialog to report bugs. | 8 | | `MARKTEXT_PANDOC` | Overwrite the pandoc path. | 9 | 10 | ## Development 11 | 12 | | Name | Description | 13 | | ------------------------------------ | ------------------------------------------------------------ | 14 | | `MARKTEXT_EXIT_ON_ERROR` | Exit on the first error or exception that occurs. | 15 | | `MARKTEXT_DEV_HIDE_BROWSER_ANALYZER` | Don't show the dependency analyzer. | 16 | | `MARKTEXT_IS_STABLE` | **Please don't use this!** Used to identify stable releases. | 17 | -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/htmlRuby.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | import { htmlToVNode } from '../snabbdom' 3 | 4 | export default function htmlRuby (h, cursor, block, token, outerClass) { 5 | const className = this.getClassName(outerClass, block, token, cursor) 6 | const { children } = token 7 | const { start, end } = token.range 8 | const content = this.highlight(h, block, start, end, token) 9 | const vNode = htmlToVNode(token.raw) 10 | 11 | const previewSelector = `span.${CLASS_OR_ID.AG_RUBY_RENDER}` 12 | 13 | return children 14 | ? [ 15 | h(`span.${className}.${CLASS_OR_ID.AG_RUBY}`, [ 16 | h(`span.${CLASS_OR_ID.AG_INLINE_RULE}.${CLASS_OR_ID.AG_RUBY_TEXT}`, content), 17 | h(previewSelector, { 18 | attrs: { 19 | contenteditable: 'false', 20 | spellcheck: 'false' 21 | } 22 | }, vNode) 23 | ]) 24 | // if children is empty string, no need to render ruby charactors... 25 | ] 26 | : [ 27 | h(`span.${className}.${CLASS_OR_ID.AG_RUBY}`, [ 28 | h(`span.${CLASS_OR_ID.AG_INLINE_RULE}.${CLASS_OR_ID.AG_RUBY_TEXT}`, content) 29 | ]) 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present Luo Ran 4 | Copyright (c) 2018-present MarkText Contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/renderer/node/paths.js: -------------------------------------------------------------------------------- 1 | import { rgPath } from 'vscode-ripgrep' 2 | import EnvPaths from 'common/envPaths' 3 | 4 | // // "vscode-ripgrep" is unpacked out of asar because of the binary. 5 | const rgDiskPath = rgPath.replace(/\bapp\.asar\b/, 'app.asar.unpacked') 6 | 7 | class RendererPaths extends EnvPaths { 8 | /** 9 | * Configure and sets all application paths. 10 | * 11 | * @param {string} userDataPath The user data path. 12 | */ 13 | constructor (userDataPath) { 14 | if (!userDataPath) { 15 | throw new Error('No user data path is given.') 16 | } 17 | 18 | // Initialize environment paths 19 | super(userDataPath) 20 | 21 | // Allow to use a local ripgrep binary (e.g. an optimized version). 22 | if (process.env.MARKTEXT_RIPGREP_PATH) { 23 | // NOTE: Binary must be a compatible version, otherwise the searcher may fail. 24 | this._ripgrepBinaryPath = process.env.MARKTEXT_RIPGREP_PATH 25 | } else { 26 | this._ripgrepBinaryPath = rgDiskPath 27 | } 28 | } 29 | 30 | // Returns the path to ripgrep on disk. 31 | get ripgrepBinaryPath () { 32 | return this._ripgrepBinaryPath 33 | } 34 | } 35 | 36 | export default RendererPaths 37 | -------------------------------------------------------------------------------- /src/main/menu/actions/window.js: -------------------------------------------------------------------------------- 1 | import { ipcMain, Menu } from 'electron' 2 | import { isOsx } from '../../config' 3 | import { COMMANDS } from '../../commands' 4 | import { zoomIn, zoomOut } from '../../windows/utils' 5 | 6 | export const minimizeWindow = win => { 7 | if (win) { 8 | if (isOsx) { 9 | Menu.sendActionToFirstResponder('performMiniaturize:') 10 | } else { 11 | win.minimize() 12 | } 13 | } 14 | } 15 | 16 | export const toggleAlwaysOnTop = win => { 17 | if (win) { 18 | ipcMain.emit('window-toggle-always-on-top', win) 19 | } 20 | } 21 | 22 | export const toggleFullScreen = win => { 23 | if (win) { 24 | win.setFullScreen(!win.isFullScreen()) 25 | } 26 | } 27 | 28 | // --- Commands ------------------------------------------------------------- 29 | 30 | export const loadWindowCommands = commandManager => { 31 | commandManager.add(COMMANDS.WINDOW_MINIMIZE, minimizeWindow) 32 | commandManager.add(COMMANDS.WINDOW_TOGGLE_ALWAYS_ON_TOP, toggleAlwaysOnTop) 33 | commandManager.add(COMMANDS.WINDOW_TOGGLE_FULL_SCREEN, toggleFullScreen) 34 | commandManager.add(COMMANDS.WINDOW_ZOOM_IN, zoomIn) 35 | commandManager.add(COMMANDS.WINDOW_ZOOM_OUT, zoomOut) 36 | } 37 | -------------------------------------------------------------------------------- /src/muya/lib/parser/marked/LICENSE: -------------------------------------------------------------------------------- 1 | Marked 2 | 3 | Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/EXPORT.md: -------------------------------------------------------------------------------- 1 | # Export a Document 2 | 3 | MarkText allows you to export a markdown document as PDF and HTML file or to print the document. 4 | 5 | ## Options 6 | 7 | ### Page options 8 | 9 | You can set the page size, orientation and margin before exporting a document. 10 | 11 | ### Style 12 | 13 | Adjust the page style without modify the page theme: 14 | 15 | - Overwrite font family, size and line height. 16 | - Auto numbering headings. 17 | - Option to show the front matter on the exported document. 18 | 19 | ### Theme 20 | 21 | MarkText allows you to select a page theme before exporting. You can learn more about page themes [here](EXPORT_THEMES.md). 22 | 23 | ### Header and footer 24 | 25 | You can include a header and/or footer in the exported document if you choose PDF or printing and also adjust the header/footer style. You can select between no, a single or a three cell header in export options. The header and/or footer appear on each page when defined and the header can be multiline but the footer only single line. Unfortunately, page numbering is currently not supported. An example can be seen below. 26 | 27 | ![](assets/marktext-export-header.png) 28 | 29 | ![](assets/marktext-export-pdf.png) 30 | -------------------------------------------------------------------------------- /src/renderer/prefComponents/image/components/uploader/legalNoticesCheckbox.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div class="pref-cb-legal-notices"> 3 | <el-checkbox v-model="uploaderService.agreedToLegalNotices"></el-checkbox> 4 | <span> 5 | By using {{ uploaderService.name }}, you agree to {{ uploaderService.name }}'s 6 | <span class="link" @click="openUrl(uploaderService.privacyUrl)">Privacy Statement</span> 7 | and 8 | <span class="link" @click="openUrl(uploaderService.tosUrl)">Terms of Service</span>. 9 | <span v-if="!uploaderService.isGdprCompliant">This service cannot be used in Europe due to GDPR issues.</span> 10 | </span> 11 | </div> 12 | </template> 13 | 14 | <script> 15 | import { shell } from 'electron' 16 | 17 | export default { 18 | data () { 19 | return {} 20 | }, 21 | props: { 22 | uploaderService: Object 23 | }, 24 | methods: { 25 | openUrl (link) { 26 | if (link) { 27 | shell.openExternal(link) 28 | } 29 | } 30 | } 31 | } 32 | </script> 33 | 34 | <style> 35 | .pref-cb-legal-notices { 36 | border: 1px solid transparent; 37 | padding: 3px 5px; 38 | & .el-checkbox { 39 | margin-right: 0; 40 | } 41 | } 42 | </style> 43 | -------------------------------------------------------------------------------- /src/renderer/util/listToTree.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor (item) { 3 | const { parent, lvl, content, slug } = item 4 | this.parent = parent 5 | this.lvl = lvl 6 | this.label = content 7 | this.slug = slug 8 | this.children = [] 9 | } 10 | 11 | // Add child node. 12 | addChild (node) { 13 | this.children.push(node) 14 | } 15 | } 16 | 17 | const findParent = (item, lastNode, rootNode) => { 18 | if (!lastNode) { 19 | return rootNode 20 | } 21 | const { lvl: lastLvl } = lastNode 22 | const { lvl } = item 23 | 24 | if (lvl < lastLvl) { 25 | return findParent(item, lastNode.parent, rootNode) 26 | } else if (lvl === lastLvl) { 27 | return lastNode.parent 28 | } else { 29 | return lastNode 30 | } 31 | } 32 | 33 | const listToTree = list => { 34 | const rootNode = new Node({ parent: null, lvl: null, content: null, slug: null }) 35 | let lastNode = null 36 | 37 | for (const item of list) { 38 | const parent = findParent(item, lastNode, rootNode) 39 | 40 | const node = new Node({ parent, ...item }) 41 | parent.addChild(node) 42 | lastNode = node 43 | } 44 | 45 | return rootNode.children 46 | } 47 | 48 | export default listToTree 49 | -------------------------------------------------------------------------------- /src/muya/lib/renderers/index.js: -------------------------------------------------------------------------------- 1 | const rendererCache = new Map() 2 | /** 3 | * 4 | * @param {string} name the renderer name: katex, sequence, plantuml, flowchart, mermaid, vega-lite 5 | */ 6 | const loadRenderer = async (name) => { 7 | if (!rendererCache.has(name)) { 8 | let m 9 | switch (name) { 10 | case 'sequence': 11 | m = await import('../parser/render/sequence') 12 | rendererCache.set(name, m.default) 13 | break 14 | case 'plantuml': 15 | m = await import('../parser/render/plantuml') 16 | rendererCache.set(name, m.default) 17 | break 18 | case 'flowchart': 19 | m = await import('flowchart.js') 20 | rendererCache.set(name, m.default) 21 | break 22 | case 'mermaid': 23 | m = await import('mermaid/dist/mermaid.core.mjs') 24 | rendererCache.set(name, m.default) 25 | break 26 | case 'vega-lite': 27 | m = await import('vega-embed') 28 | rendererCache.set(name, m.default) 29 | break 30 | default: 31 | throw new Error(`Unknown diagram name ${name}`) 32 | } 33 | } 34 | 35 | return rendererCache.get(name) 36 | } 37 | 38 | export default loadRenderer 39 | -------------------------------------------------------------------------------- /src/renderer/prefComponents/general/config.js: -------------------------------------------------------------------------------- 1 | export const titleBarStyleOptions = [{ 2 | label: 'Custom', 3 | value: 'custom' 4 | }, { 5 | label: 'Native', 6 | value: 'native' 7 | }] 8 | 9 | export const zoomOptions = [{ 10 | label: '50.0%', 11 | value: 0.5 12 | }, { 13 | label: '62.5%', 14 | value: 0.625 15 | }, { 16 | label: '75.0%', 17 | value: 0.75 18 | }, { 19 | label: '87.5%', 20 | value: 0.875 21 | }, { 22 | label: '100.0%', 23 | value: 1.0 24 | }, { 25 | label: '112.5%', 26 | value: 1.125 27 | }, { 28 | label: '125.0%', 29 | value: 1.25 30 | }, { 31 | label: '137.5%', 32 | value: 1.375 33 | }, { 34 | label: '150.0%', 35 | value: 1.5 36 | }, { 37 | label: '162.5%', 38 | value: 1.625 39 | }, { 40 | label: '175.0%', 41 | value: 1.75 42 | }, { 43 | label: '187.5%', 44 | value: 1.875 45 | }, { 46 | label: '200.0%', 47 | value: 2.0 48 | }] 49 | 50 | export const fileSortByOptions = [{ 51 | label: 'Creation time', 52 | value: 'created' 53 | }, { 54 | label: 'Modification time', 55 | value: 'modified' 56 | }, { 57 | label: 'Title', 58 | value: 'title' 59 | }] 60 | 61 | export const languageOptions = [{ 62 | label: 'English', 63 | value: 'en' 64 | }] 65 | -------------------------------------------------------------------------------- /src/muya/lib/ui/footnoteTool/index.css: -------------------------------------------------------------------------------- 1 | .ag-footnote-tool-container { 2 | width: 300px; 3 | border-radius: 5px; 4 | } 5 | 6 | .ag-footnote-tool-container .ag-footnote-tool > div { 7 | display: flex; 8 | height: 35px; 9 | align-items: center; 10 | color: var(--editorColor); 11 | font-size: 12px; 12 | padding: 0 10px; 13 | } 14 | 15 | .ag-footnote-tool .text { 16 | text-overflow: ellipsis; 17 | overflow: hidden; 18 | white-space: nowrap; 19 | flex: 1; 20 | } 21 | 22 | .ag-footnote-tool .btn { 23 | width: 40px; 24 | display: inline-block; 25 | cursor: pointer; 26 | } 27 | 28 | .ag-footnote-tool .icon-wrapper { 29 | width: 14px; 30 | height: 14px; 31 | margin-right: 5px; 32 | position: relative; 33 | } 34 | 35 | .ag-footnote-tool .icon-wrapper i.icon { 36 | display: inline-block; 37 | position: absolute; 38 | top: 0; 39 | height: 100%; 40 | width: 100%; 41 | overflow: hidden; 42 | color: var(--iconColor); 43 | transition: all .25s ease-in-out; 44 | } 45 | 46 | .ag-footnote-tool .icon-wrapper i.icon > i[class^=icon-] { 47 | display: inline-block; 48 | width: 100%; 49 | height: 100%; 50 | filter: drop-shadow(14px 0 currentColor); 51 | position: relative; 52 | left: -14px; 53 | } 54 | -------------------------------------------------------------------------------- /src/renderer/store/listenForMain.js: -------------------------------------------------------------------------------- 1 | import { ipcRenderer } from 'electron' 2 | import bus from '../bus' 3 | 4 | const state = {} 5 | 6 | const getters = {} 7 | 8 | const mutations = {} 9 | 10 | const actions = { 11 | LISTEN_FOR_EDIT ({ commit }) { 12 | ipcRenderer.on('mt::editor-edit-action', (e, type) => { 13 | if (type === 'findInFolder') { 14 | commit('SET_LAYOUT', { 15 | rightColumn: 'search', 16 | showSideBar: true 17 | }) 18 | } 19 | bus.$emit(type, type) 20 | }) 21 | }, 22 | 23 | LISTEN_FOR_SHOW_DIALOG ({ commit }) { 24 | ipcRenderer.on('mt::about-dialog', e => { 25 | bus.$emit('aboutDialog') 26 | }) 27 | ipcRenderer.on('mt::show-export-dialog', (e, type) => { 28 | bus.$emit('showExportDialog', type) 29 | }) 30 | }, 31 | 32 | LISTEN_FOR_PARAGRAPH_INLINE_STYLE () { 33 | ipcRenderer.on('mt::editor-paragraph-action', (e, { type }) => { 34 | bus.$emit('paragraph', type) 35 | }) 36 | ipcRenderer.on('mt::editor-format-action', (e, { type }) => { 37 | bus.$emit('format', type) 38 | }) 39 | } 40 | } 41 | 42 | const listenForMain = { state, getters, mutations, actions } 43 | 44 | export default listenForMain 45 | -------------------------------------------------------------------------------- /test/e2e/data/xss.md: -------------------------------------------------------------------------------- 1 | # XSS Tests 2 | 3 | ### HTML 4 | 5 | <script>process.crash()</script> 6 | 7 | <img src="#" onerror="process.crash()"> 8 | 9 | <svg/onload="process.crash()"> 10 | 11 | <svg width="100" height="100"> 12 | <script>process.crash()</script> 13 | <rect width="100" height="100" style="fill:rgb(0,0,0)" /> 14 | </svg> 15 | 16 | <iframe src="javascript:process.crash();"></iframe> 17 | 18 | <iframe src="#" onerror="process.crash()" onload="process.crash()"></iframe> 19 | 20 | <iframe src="not-a-real-file.extension" onerror="process.crash()" onload="process.crash()"></iframe> 21 | 22 | <iframe/src="data:text/html,<svg onload=\"process.crash()\""> 23 | 24 | <embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj48c2NyaXB0PnRocm93IG5ldyBFcnJvcignWFNTIDgnKTwvc2NyaXB0Pjwvc3ZnPgo=" type="image/svg+xml" AllowScriptAccess="always"></embed> 25 | 26 | <script foo>process.crash()</script> 27 | 28 | #### Markdown 29 | 30 | ```<style/onload=process.crash()> 31 | foo 32 | ``` 33 | 34 | ```"><script>process.crash()</script> 35 | foo 36 | ``` 37 | -------------------------------------------------------------------------------- /src/renderer/assets/icons/markdown.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1513057467027" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4935" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M622.077559 64.636113 838.133314 280.69289 622.077559 280.69289 622.077559 64.636113 622.077559 64.636113Z" p-id="4936" fill="#515151"></path><path d="M622.077559 64.636113" p-id="4937" fill="#515151"></path><path d="M588.762803 64.636113l0 244.373707 244.331751 0L833.094554 959.362864 183.387215 959.362864 183.387215 64.636113 588.762803 64.636113 588.762803 64.636113 588.762803 64.636113zM227.432361 426.853761l0 484.581534 561.615001 0L789.047362 426.849668 227.432361 426.853761 227.432361 426.853761 227.432361 426.853761zM327.00517 814.697043 327.00517 524.713556l72.495104 0 108.74061 108.748796L616.985588 524.713556l72.491011 0 0 289.983487-72.491011 0 0-187.398064L508.240885 736.039589 399.500275 627.298979l0 187.398064L327.00517 814.697043" p-id="4938" fill="#515151"></path><path d="M623.946117 582.828139" p-id="4939" fill="#515151"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_strong.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552895597479" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5961" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M230.4 179.2h301.3632c65.4336 0 117.0432 15.6672 153.9072 47.0016 34.0992 29.4912 51.6096 69.12 51.6096 118.8864 0 36.864-9.216 68.1984-26.7264 94.0032-17.5104 23.9616-42.3936 41.472-75.5712 54.3744 43.3152 8.2944 75.5712 25.8048 97.6896 52.5312 21.1968 25.8048 32.256 61.7472 32.256 105.984 0 66.3552-23.04 115.2-68.1984 146.5344-38.7072 25.8048-94.0032 38.7072-164.0448 38.7072H230.4V179.2z m102.4 88.4736V455.68h170.3936c46.08 0 78.336-8.2944 97.6896-23.04 18.432-15.6672 28.5696-40.5504 28.5696-74.6496 0-31.3344-10.1376-54.3744-28.5696-68.1984-20.2752-14.7456-51.6096-22.1184-95.8464-22.1184H332.8512z m0 276.48v204.5952h184.2176c40.5504 0 72.8064-6.4512 95.8464-19.3536 29.4912-16.5888 44.2368-42.3936 44.2368-79.2576 0-37.7856-11.0592-64.512-32.256-81.1008-22.1184-16.5888-57.1392-24.8832-105.0624-24.8832H332.8512z" fill="#000000" p-id="5962"></path></svg> -------------------------------------------------------------------------------- /src/muya/lib/assets/icons/format_code.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M427.472384 901.8112l255.6672-742.4c0.2048-0.5632 0.3328-1.2544 0.4608-1.8176L427.472384 901.8112zM683.241984 120.704h-77.4656a9.2928 9.2928 0 0 0-8.7296 6.2208L331.395584 898.2272a9.216 9.216 0 0 0 8.7296 12.16h77.8496c3.8912 0 7.4752-2.56 8.704-6.1952l0.7936-2.4064L683.600384 157.5424l8.4992-24.576a9.2928 9.2928 0 0 0-8.8576-12.2624z m336.8704 382.7456a22.3232 22.3232 0 0 0-3.0976-3.1232l-251.4176-196.6336a9.088 9.088 0 0 0-12.8256 1.6128 8.832 8.832 0 0 0-1.9712 5.632v93.3376c0 2.8672 1.28 5.5296 3.584 7.2448l131.9936 103.3216-131.9936 103.296a9.2672 9.2672 0 0 0-3.584 7.2448v93.3376a9.216 9.216 0 0 0 9.1648 9.1648 9.216 9.216 0 0 0 5.632-1.9456l251.4176-196.6848a18.432 18.432 0 0 0 3.0976-25.8048z m-761.728-199.7568l-251.392 196.6336a18.5088 18.5088 0 0 0 0 28.9536l251.392 196.6848a9.216 9.216 0 0 0 14.8224-7.2192V625.408a8.96 8.96 0 0 0-3.5584-7.2448L137.603584 514.816l132.0192-103.296a9.2416 9.2416 0 0 0 3.5584-7.2448v-93.3376a9.1392 9.1392 0 0 0-14.7968-7.2448z" /></svg> -------------------------------------------------------------------------------- /src/muya/lib/parser/render/renderInlines/delEmStringFactory.js: -------------------------------------------------------------------------------- 1 | import { CLASS_OR_ID } from '../../../config' 2 | import { snakeToCamel } from '../../../utils' 3 | 4 | // render factory of `del`,`em`,`strong` 5 | export default function delEmStrongFac (type, h, cursor, block, token, outerClass) { 6 | const className = this.getClassName(outerClass, block, token, cursor) 7 | const COMMON_MARKER = `span.${className}.${CLASS_OR_ID.AG_REMOVE}` 8 | const { marker } = token 9 | const { start, end } = token.range 10 | const backlashStart = end - marker.length - token.backlash.length 11 | const content = [ 12 | ...token.children.reduce((acc, to) => { 13 | const chunk = this[snakeToCamel(to.type)](h, cursor, block, to, className) 14 | return Array.isArray(chunk) ? [...acc, ...chunk] : [...acc, chunk] 15 | }, []), 16 | ...this.backlashInToken(h, token.backlash, className, backlashStart, token) 17 | ] 18 | const startMarker = this.highlight(h, block, start, start + marker.length, token) 19 | const endMarker = this.highlight(h, block, end - marker.length, end, token) 20 | 21 | return [ 22 | h(COMMON_MARKER, startMarker), 23 | h(`${type}.${CLASS_OR_ID.AG_INLINE_RULE}`, content), 24 | h(COMMON_MARKER, endMarker) 25 | ] 26 | } 27 | --------------------------------------------------------------------------------