mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-12-08 17:58:05 +00:00
Revamp markdown plugin (#6528)
* Rename markdown to markdown-legacy * Change how default renderWikiTextPragma value is displayed To prevent out-of-sync, dynamically display the default value of renderWikiTextPragma from the shadow tiddler instead of hard coding the text in the "usage.tid". * Repackage remarkable-based markdown plugin as markdown-legacy - Rename plugin title to $:/plugins/tiddlywiki/markdown-legacy - Add support for "text/markdown" MIME type and set that as the default when creating new markdown tiddlers * Create new markdown plugin * add support to text/markdown MIME type * remove linkify and linkNewWindow config options - linkify feature should be controlled by "extlink" TW parser rule; enabling markdown's linkify option will interfere with parsing - remove the possibility to open external links in the same tab/window to match TW's behavior * Ignore latex-parser wikirule in rednerWikiTextPragma * Prevent camel-case link text from generating a link * Update editions/markdowndemo * Produce better parse tree * Improve markdown/tiddlywiki integration - widget block should not interrupt paragraph - ignore tw-syntax links inside markdown-syntax links - remove repeated renderWikiTextPragma parsing - more efficient findNextMatch when examining tw rules * Update user docs * Replace includes() with indexOf() for legacy browsers
This commit is contained in:
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/bold.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/bold.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/bold
|
||||
list-after: $:/core/ui/EditorToolbar/bold
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/bold
|
||||
caption: {{$:/language/Buttons/Bold/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Bold/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((bold))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-selection"
|
||||
prefix="**"
|
||||
suffix="**"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-1.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-1.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-1
|
||||
list-after: $:/core/ui/EditorToolbar/heading-1
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/heading-1
|
||||
caption: {{$:/language/Buttons/Heading1/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Heading1/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((heading-1))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="#"
|
||||
count="1"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-2.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-2.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-2
|
||||
list-after: $:/core/ui/EditorToolbar/heading-2
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/heading-2
|
||||
caption: {{$:/language/Buttons/Heading2/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Heading2/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((heading-2))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="#"
|
||||
count="2"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-3.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-3.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-3
|
||||
list-after: $:/core/ui/EditorToolbar/heading-3
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/heading-3
|
||||
caption: {{$:/language/Buttons/Heading3/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Heading3/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((heading-3))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="#"
|
||||
count="3"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-4.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-4.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-4
|
||||
list-after: $:/core/ui/EditorToolbar/heading-4
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/heading-4
|
||||
caption: {{$:/language/Buttons/Heading4/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Heading4/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((heading-4))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="#"
|
||||
count="4"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-5.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-5.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-5
|
||||
list-after: $:/core/ui/EditorToolbar/heading-5
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/heading-5
|
||||
caption: {{$:/language/Buttons/Heading5/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Heading5/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((heading-5))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="#"
|
||||
count="5"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-6.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-6.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/heading-6
|
||||
list-after: $:/core/ui/EditorToolbar/heading-6
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/heading-6
|
||||
caption: {{$:/language/Buttons/Heading6/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Heading6/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((heading-6))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="#"
|
||||
count="6"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/italic.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/italic.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/italic
|
||||
list-after: $:/core/ui/EditorToolbar/italic
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/italic
|
||||
caption: {{$:/language/Buttons/Italic/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Italic/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((italic))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-selection"
|
||||
prefix="*"
|
||||
suffix="*"
|
||||
/>
|
||||
@@ -0,0 +1,73 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/link-dropdown
|
||||
|
||||
\define lingo-base() $:/language/Buttons/Link/
|
||||
|
||||
\define add-link-actions()
|
||||
\whitespace trim
|
||||
<$action-sendmessage $message="tm-edit-text-operation" $param="make-markdown-link" text={{$(linkTiddler)$}} />
|
||||
<$action-deletetiddler $filter="[<dropdown-state>] [<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]"/>
|
||||
\end
|
||||
|
||||
\define get-focus-selector() [data-tiddler-title="$(cssEscapedTitle)$"] .tc-create-wikitext-link input
|
||||
|
||||
\define cancel-search-actions-inner()
|
||||
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}><$list filter="[<searchTiddler>get[text]!match<userInput>]" emptyMessage="<$action-deletetiddler $filter='[<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]'/>"><$action-setfield $tiddler=<<searchTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text="yes"/></$list></$set>
|
||||
\end
|
||||
|
||||
\define cancel-search-actions() <$list filter="[<storeTitle>!has[text]] +[<searchTiddler>!has[text]]" emptyMessage="<<cancel-search-actions-inner>>"><$action-sendmessage $message="tm-edit-text-operation" $param="focus-editor"/></$list>
|
||||
|
||||
\define external-link()
|
||||
\whitespace trim
|
||||
<$button class="tc-btn-invisible" style="width: auto; display: inline-block; background-colour: inherit;" actions=<<add-link-actions>>>
|
||||
{{$:/core/images/chevron-right}}
|
||||
</$button>
|
||||
\end
|
||||
|
||||
\define set-next-input-tab(beforeafter:"after") <$macrocall $name="change-input-tab" stateTitle="$:/state/tab/search-results/sidebar" tag="$:/tags/SearchResults" beforeafter="$beforeafter$" defaultState={{$:/config/SearchResults/Default}} actions="<$action-setfield $tiddler='$:/state/search/currentTab' text=<<nextTab>>/>"/>
|
||||
|
||||
\define body(config-title)
|
||||
\whitespace trim
|
||||
''<<lingo Hint>>''
|
||||
|
||||
<$vars searchTiddler="""$config-title$/search""" linkTiddler="""$config-title$/link""" linktext="" searchListState=<<qualify "$:/temp/link-search/selected-item">> refreshTitle=<<qualify "$:/temp/link-search/refresh">> storeTitle=<<qualify "$:/temp/link-search/input">>>
|
||||
|
||||
<$vars linkTiddler=<<searchTiddler>>>
|
||||
<$keyboard key="((input-tab-right))" actions=<<set-next-input-tab>>>
|
||||
<$keyboard key="((input-tab-left))" actions=<<set-next-input-tab "before">> class="tc-create-wikitext-link">
|
||||
<$macrocall $name="keyboard-driven-input" tiddler=<<searchTiddler>> storeTitle=<<storeTitle>>
|
||||
selectionStateTitle=<<searchListState>> refreshTitle=<<refreshTitle>> type="search" filterMinLength="1"
|
||||
tag="input" focus="true" class="tc-popup-handle" inputCancelActions=<<cancel-search-actions>>
|
||||
inputAcceptActions=<<add-link-actions>> placeholder={{$:/language/Search/Search}} default=""
|
||||
configTiddlerFilter="[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]" />
|
||||
</$keyboard>
|
||||
</$keyboard>
|
||||
 
|
||||
<$reveal tag="span" state=<<storeTitle>> type="nomatch" text="">
|
||||
<<external-link>>
|
||||
 
|
||||
<$button class="tc-btn-invisible" style="width: auto; display: inline-block; background-colour: inherit;">
|
||||
<<cancel-search-actions>><$set name="cssEscapedTitle" value={{{ [<storyTiddler>escapecss[]] }}}><$action-sendmessage $message="tm-focus-selector" $param=<<get-focus-selector>>/></$set>
|
||||
{{$:/core/images/close-button}}
|
||||
</$button>
|
||||
</$reveal>
|
||||
</$vars>
|
||||
|
||||
<$reveal tag="div" state=<<storeTitle>> type="nomatch" text="">
|
||||
|
||||
<$linkcatcher actions=<<add-link-actions>> to=<<linkTiddler>>>
|
||||
|
||||
<$vars userInput={{{ [<storeTitle>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}}>
|
||||
|
||||
{{$:/core/ui/SearchResults}}
|
||||
|
||||
</$vars>
|
||||
|
||||
</$linkcatcher>
|
||||
|
||||
</$reveal>
|
||||
|
||||
</$vars>
|
||||
|
||||
\end
|
||||
|
||||
<$macrocall $name="body" config-title=<<qualify "$:/state/Link/">>/>
|
||||
11
plugins/tiddlywiki/markdown-legacy/EditorToolbar/link.tid
Executable file
11
plugins/tiddlywiki/markdown-legacy/EditorToolbar/link.tid
Executable file
@@ -0,0 +1,11 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/link
|
||||
list-after: $:/core/ui/EditorToolbar/link
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/link
|
||||
caption: {{$:/language/Buttons/Link/Caption}}
|
||||
description: {{$:/language/Buttons/Link/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
button-classes: tc-text-editor-toolbar-item-start-group
|
||||
shortcuts: ((link))
|
||||
dropdown: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/link-dropdown
|
||||
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/linkify.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/linkify.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
caption: {{$:/language/Buttons/Linkify/Caption}} (Markdown)
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
description: {{$:/language/Buttons/Linkify/Hint}}
|
||||
icon: $:/plugins/tiddlywiki/markdown-legacy/images/markdown-linkify
|
||||
list-after: $:/core/ui/EditorToolbar/linkify
|
||||
shortcuts: ((linkify))
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/linkify
|
||||
tags: $:/tags/EditorToolbar
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-selection"
|
||||
prefix="["
|
||||
suffix="]()"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/list-bullet.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/list-bullet.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/list-bullet
|
||||
list-after: $:/core/ui/EditorToolbar/list-bullet
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/list-bullet
|
||||
caption: {{$:/language/Buttons/ListBullet/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/ListBullet/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((list-bullet))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="*"
|
||||
count="1"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/list-number.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/list-number.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/list-number
|
||||
list-after: $:/core/ui/EditorToolbar/list-number
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/list-number
|
||||
caption: {{$:/language/Buttons/ListNumber/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/ListNumber/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((list-number))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character="1."
|
||||
count="1"
|
||||
/>
|
||||
17
plugins/tiddlywiki/markdown-legacy/EditorToolbar/mono-block.tid
Executable file
17
plugins/tiddlywiki/markdown-legacy/EditorToolbar/mono-block.tid
Executable file
@@ -0,0 +1,17 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/mono-block
|
||||
list-after: $:/core/ui/EditorToolbar/mono-block
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/mono-block
|
||||
caption: {{$:/language/Buttons/MonoBlock/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/MonoBlock/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
button-classes: tc-text-editor-toolbar-item-start-group
|
||||
shortcuts: ((mono-block))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-lines"
|
||||
prefix="
|
||||
```"
|
||||
suffix="```"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/mono-line.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/mono-line.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/mono-line
|
||||
list-after: $:/core/ui/EditorToolbar/mono-line
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/mono-line
|
||||
caption: {{$:/language/Buttons/MonoLine/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/MonoLine/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((mono-line))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="wrap-selection"
|
||||
prefix="`"
|
||||
suffix="`"
|
||||
/>
|
||||
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/quote.tid
Executable file
15
plugins/tiddlywiki/markdown-legacy/EditorToolbar/quote.tid
Executable file
@@ -0,0 +1,15 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/EditorToolbar/quote
|
||||
list-after: $:/core/ui/EditorToolbar/quote
|
||||
tags: $:/tags/EditorToolbar
|
||||
icon: $:/core/images/quote
|
||||
caption: {{$:/language/Buttons/Quote/Caption}} (Markdown)
|
||||
description: {{$:/language/Buttons/Quote/Hint}}
|
||||
condition: [<targetTiddler>type[text/x-markdown]] [<targetTiddler>type[text/markdown]]
|
||||
shortcuts: ((quote))
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-edit-text-operation"
|
||||
$param="prefix-lines"
|
||||
character=">"
|
||||
count="1"
|
||||
/>
|
||||
@@ -0,0 +1,8 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/KeyboardShortcuts/new-markdown-tiddler
|
||||
tags: $:/tags/KeyboardShortcut
|
||||
key: ((new-markdown-tiddler))
|
||||
|
||||
\whitespace trim
|
||||
<$navigator story="$:/StoryList" history="$:/HistoryList" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>
|
||||
<$action-sendmessage $message="tm-new-tiddler" type="text/markdown"/>
|
||||
</$navigator>
|
||||
5
plugins/tiddlywiki/markdown-legacy/config.multids
Normal file
5
plugins/tiddlywiki/markdown-legacy/config.multids
Normal file
@@ -0,0 +1,5 @@
|
||||
title: $:/config/
|
||||
|
||||
ShortcutInfo/new-markdown-tiddler: {{$:/language/Buttons/NewMarkdown/Hint}}
|
||||
shortcuts-mac/new-markdown-tiddler: ctrl-M
|
||||
shortcuts-not-mac/new-markdown-tiddler: alt-M
|
||||
3
plugins/tiddlywiki/markdown-legacy/config_breaks.tid
Normal file
3
plugins/tiddlywiki/markdown-legacy/config_breaks.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/breaks
|
||||
|
||||
false
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/linkNewWindow
|
||||
|
||||
true
|
||||
3
plugins/tiddlywiki/markdown-legacy/config_linkify.tid
Normal file
3
plugins/tiddlywiki/markdown-legacy/config_linkify.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/linkify
|
||||
|
||||
false
|
||||
3
plugins/tiddlywiki/markdown-legacy/config_quotes.tid
Normal file
3
plugins/tiddlywiki/markdown-legacy/config_quotes.tid
Normal file
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/quotes
|
||||
|
||||
“”‘’
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/renderWikiText
|
||||
|
||||
true
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/renderWikiTextPragma
|
||||
|
||||
\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock latex-parser
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/config/markdown/typographer
|
||||
|
||||
false
|
||||
4
plugins/tiddlywiki/markdown-legacy/docs_type_markdown.tid
Executable file
4
plugins/tiddlywiki/markdown-legacy/docs_type_markdown.tid
Executable file
@@ -0,0 +1,4 @@
|
||||
title: $:/language/Docs/Types/text/markdown
|
||||
description: Markdown
|
||||
name: text/markdown
|
||||
group: Text
|
||||
@@ -0,0 +1,37 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/editor-operations/make-markdown-link.js
|
||||
type: application/javascript
|
||||
module-type: texteditoroperation
|
||||
|
||||
Text editor operation to make a markdown link
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports["make-markdown-link"] = function(event,operation) {
|
||||
if(operation.selection) {
|
||||
if(event.paramObject.text.indexOf("://") !== -1) {
|
||||
operation.replacement = "[" + operation.selection + "](" + event.paramObject.text + ")";
|
||||
} else {
|
||||
operation.replacement = "[" + operation.selection + "](#" + event.paramObject.text.replaceAll(" ", "%20") + ")";
|
||||
}
|
||||
operation.cutStart = operation.selStart;
|
||||
operation.cutEnd = operation.selEnd;
|
||||
} else {
|
||||
if(event.paramObject.text.indexOf("://") !== -1) {
|
||||
operation.replacement = "<" + event.paramObject.text + ">";
|
||||
} else {
|
||||
operation.replacement = "[](#" + event.paramObject.text.replaceAll(" ", "%20") + ")";
|
||||
}
|
||||
operation.cutStart = operation.selStart;
|
||||
operation.cutEnd = operation.selEnd;
|
||||
}
|
||||
operation.newSelStart = operation.selStart + operation.replacement.length;
|
||||
operation.newSelEnd = operation.newSelStart;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Brad Howes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
137
plugins/tiddlywiki/markdown-legacy/files/remarkable-katex.js
Normal file
137
plugins/tiddlywiki/markdown-legacy/files/remarkable-katex.js
Normal file
@@ -0,0 +1,137 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Plugin for Remarkable Markdown processor which transforms $..$ and $$..$$ sequences into math HTML using the
|
||||
* Katex package.
|
||||
*/
|
||||
const rkatex = (md, options) => {
|
||||
const backslash = '\\';
|
||||
const dollar = '$';
|
||||
const opts = options || {};
|
||||
const delimiter = opts.delimiter || dollar;
|
||||
if (delimiter.length !== 1) { throw new Error('invalid delimiter'); }
|
||||
|
||||
const katex = require("katex");
|
||||
|
||||
/**
|
||||
* Render the contents as KaTeX
|
||||
*/
|
||||
const renderKatex = (source, displayMode) => katex.renderToString(source,
|
||||
{displayMode: displayMode,
|
||||
throwOnError: false});
|
||||
|
||||
/**
|
||||
* Parse '$$' as a block. Based off of similar method in remarkable.
|
||||
*/
|
||||
const parseBlockKatex = (state, startLine, endLine) => {
|
||||
let haveEndMarker = false;
|
||||
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
||||
let max = state.eMarks[startLine];
|
||||
|
||||
if (pos + 1 > max) { return false; }
|
||||
|
||||
const marker = state.src.charAt(pos);
|
||||
if (marker !== delimiter) { return false; }
|
||||
|
||||
// scan marker length
|
||||
let mem = pos;
|
||||
pos = state.skipChars(pos, marker);
|
||||
let len = pos - mem;
|
||||
|
||||
if (len !== 2) { return false; }
|
||||
|
||||
// search end of block
|
||||
let nextLine = startLine;
|
||||
|
||||
for (;;) {
|
||||
++nextLine;
|
||||
if (nextLine >= endLine) { break; }
|
||||
|
||||
pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];
|
||||
max = state.eMarks[nextLine];
|
||||
|
||||
if (pos < max && state.tShift[nextLine] < state.blkIndent) { break; }
|
||||
if (state.src.charAt(pos) !== delimiter) { continue; }
|
||||
if (state.tShift[nextLine] - state.blkIndent >= 4) { continue; }
|
||||
|
||||
pos = state.skipChars(pos, marker);
|
||||
if (pos - mem < len) { continue; }
|
||||
|
||||
pos = state.skipSpaces(pos);
|
||||
if (pos < max) { continue; }
|
||||
|
||||
haveEndMarker = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If a fence has heading spaces, they should be removed from its inner block
|
||||
len = state.tShift[startLine];
|
||||
state.line = nextLine + (haveEndMarker ? 1 : 0);
|
||||
const content = state.getLines(startLine + 1, nextLine, len, true)
|
||||
.replace(/[ \n]+/g, ' ')
|
||||
.trim();
|
||||
|
||||
state.tokens.push({type: 'katex', params: null, content: content, lines: [startLine, state.line],
|
||||
level: state.level, block: true});
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Look for '$' or '$$' spans in Markdown text. Based off of the 'fenced' parser in remarkable.
|
||||
*/
|
||||
const parseInlineKatex = (state, silent) => {
|
||||
const start = state.pos;
|
||||
const max = state.posMax;
|
||||
let pos = start;
|
||||
|
||||
// Unexpected starting character
|
||||
if (state.src.charAt(pos) !== delimiter) { return false; }
|
||||
|
||||
++pos;
|
||||
while (pos < max && state.src.charAt(pos) === delimiter) { ++pos; }
|
||||
|
||||
// Capture the length of the starting delimiter -- closing one must match in size
|
||||
const marker = state.src.slice(start, pos);
|
||||
if (marker.length > 2) { return false; }
|
||||
|
||||
const spanStart = pos;
|
||||
let escapedDepth = 0;
|
||||
while (pos < max) {
|
||||
const char = state.src.charAt(pos);
|
||||
if (char === '{' && (pos == 0 || state.src.charAt(pos - 1) != backslash)) {
|
||||
escapedDepth += 1;
|
||||
} else if (char === '}' && (pos == 0 || state.src.charAt(pos - 1) != backslash)) {
|
||||
escapedDepth -= 1;
|
||||
if (escapedDepth < 0) { return false; }
|
||||
} else if (char === delimiter && escapedDepth === 0) {
|
||||
const matchStart = pos;
|
||||
let matchEnd = pos + 1;
|
||||
while (matchEnd < max && state.src.charAt(matchEnd) === delimiter) { ++matchEnd; }
|
||||
|
||||
if (matchEnd - matchStart === marker.length) {
|
||||
if (!silent) {
|
||||
const content = state.src.slice(spanStart, matchStart)
|
||||
.replace(/[ \n]+/g, ' ')
|
||||
.trim();
|
||||
state.push({type: 'katex', content: content, block: marker.length > 1, level: state.level});
|
||||
}
|
||||
state.pos = matchEnd;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
if (!silent) { state.pending += marker; }
|
||||
state.pos += marker.length;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
md.inline.ruler.push('katex', parseInlineKatex, options);
|
||||
md.block.ruler.push('katex', parseBlockKatex, options);
|
||||
md.renderer.rules.katex = (tokens, idx) => renderKatex(tokens[idx].content, tokens[idx].block);
|
||||
md.renderer.rules.katex.delimiter = delimiter;
|
||||
};
|
||||
|
||||
module.exports = rkatex;
|
||||
20
plugins/tiddlywiki/markdown-legacy/files/remarkable-katex.min.js
vendored
Normal file
20
plugins/tiddlywiki/markdown-legacy/files/remarkable-katex.min.js
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";const rkatex=(md,options)=>{const backslash='\\';const dollar='$';const opts=options||{};const delimiter=opts.delimiter||dollar;if(delimiter.length!==1){throw new Error('invalid delimiter');}
|
||||
const katex=require("katex");const renderKatex=(source,displayMode)=>katex.renderToString(source,{displayMode:displayMode,throwOnError:false});const parseBlockKatex=(state,startLine,endLine)=>{let haveEndMarker=false;let pos=state.bMarks[startLine]+state.tShift[startLine];let max=state.eMarks[startLine];if(pos+1>max){return false;}
|
||||
const marker=state.src.charAt(pos);if(marker!==delimiter){return false;}
|
||||
let mem=pos;pos=state.skipChars(pos,marker);let len=pos-mem;if(len!==2){return false;}
|
||||
let nextLine=startLine;for(;;){++nextLine;if(nextLine>=endLine){break;}
|
||||
pos=mem=state.bMarks[nextLine]+state.tShift[nextLine];max=state.eMarks[nextLine];if(pos<max&&state.tShift[nextLine]<state.blkIndent){break;}
|
||||
if(state.src.charAt(pos)!==delimiter){continue;}
|
||||
if(state.tShift[nextLine]-state.blkIndent>=4){continue;}
|
||||
pos=state.skipChars(pos,marker);if(pos-mem<len){continue;}
|
||||
pos=state.skipSpaces(pos);if(pos<max){continue;}
|
||||
haveEndMarker=true;break;}
|
||||
len=state.tShift[startLine];state.line=nextLine+(haveEndMarker?1:0);const content=state.getLines(startLine+1,nextLine,len,true).replace(/[ \n]+/g,' ').trim();state.tokens.push({type:'katex',params:null,content:content,lines:[startLine,state.line],level:state.level,block:true});return true;};const parseInlineKatex=(state,silent)=>{const start=state.pos;const max=state.posMax;let pos=start;if(state.src.charAt(pos)!==delimiter){return false;}
|
||||
++pos;while(pos<max&&state.src.charAt(pos)===delimiter){++pos;}
|
||||
const marker=state.src.slice(start,pos);if(marker.length>2){return false;}
|
||||
const spanStart=pos;let escapedDepth=0;while(pos<max){const char=state.src.charAt(pos);if(char==='{'&&(pos==0||state.src.charAt(pos-1)!=backslash)){escapedDepth+=1;}else if(char==='}'&&(pos==0||state.src.charAt(pos-1)!=backslash)){escapedDepth-=1;if(escapedDepth<0){return false;}}else if(char===delimiter&&escapedDepth===0){const matchStart=pos;let matchEnd=pos+1;while(matchEnd<max&&state.src.charAt(matchEnd)===delimiter){++matchEnd;}
|
||||
if(matchEnd-matchStart===marker.length){if(!silent){const content=state.src.slice(spanStart,matchStart).replace(/[ \n]+/g,' ').trim();state.push({type:'katex',content:content,block:marker.length>1,level:state.level});}
|
||||
state.pos=matchEnd;return true;}}
|
||||
pos+=1;}
|
||||
if(!silent){state.pending+=marker;}
|
||||
state.pos+=marker.length;return true;};md.inline.ruler.push('katex',parseInlineKatex,options);md.block.ruler.push('katex',parseBlockKatex,options);md.renderer.rules.katex=(tokens,idx)=>renderKatex(tokens[idx].content,tokens[idx].block);md.renderer.rules.katex.delimiter=delimiter;};module.exports=rkatex;
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016, Jon Schlinkert
|
||||
Copyright (c) 2014 Jon Schlinkert, Vitaly Puzrin.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1
plugins/tiddlywiki/markdown-legacy/files/remarkable.js
Normal file
1
plugins/tiddlywiki/markdown-legacy/files/remarkable.js
Normal file
File diff suppressed because one or more lines are too long
36
plugins/tiddlywiki/markdown-legacy/files/tiddlywiki.files
Executable file
36
plugins/tiddlywiki/markdown-legacy/files/tiddlywiki.files
Executable file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"tiddlers": [
|
||||
{
|
||||
"file": "remarkable.js",
|
||||
"fields": {
|
||||
"type": "application/javascript",
|
||||
"title": "$:/plugins/tiddlywiki/markdown-legacy/remarkable.js",
|
||||
"module-type": "library"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "remarkable-license.txt",
|
||||
"fields": {
|
||||
"type": "text/plain",
|
||||
"title": "$:/plugins/tiddlywiki/markdown-legacy/remarkable-license"
|
||||
}
|
||||
},
|
||||
{
|
||||
"file": "remarkable-katex.min.js",
|
||||
"fields": {
|
||||
"type": "application/javascript",
|
||||
"title": "$:/plugins/tiddlywiki/markdown-legacy/remarkable-katex.js",
|
||||
"module-type": "library"
|
||||
},
|
||||
"prefix": "(function(realRequire) {var require = function(m) {if(m===\"katex\"){m = \"$:/plugins/tiddlywiki/katex/katex.min.js\"};return realRequire(m);};",
|
||||
"suffix": "})(require);\n"
|
||||
},
|
||||
{
|
||||
"file": "remarkable-katex-license.txt",
|
||||
"fields": {
|
||||
"type": "text/plain",
|
||||
"title": "$:/plugins/tiddlywiki/markdown-legacy/remarkable-katex-license"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/images/markdown-linkify
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg width="22pt" height="22pt" class="tc-markdown-linkify-button tc-image-button" viewBox="0 0 128 128">
|
||||
<path d="M17.031185,32.1989189 L9.04781705,32.1989189 L9.04781705,97.1303119 L17.031185,97.1303119 L17.031185,104.049231 L0,104.049231 L0,25.28 L17.031185,25.28 L17.031185,32.1989189 Z M93.6716009,24.75 C90.4007675,30.8326023 88.0193713,37.1590826 86.5274123,43.7294408 C85.0354532,50.299799 84.2894737,56.9705775 84.2894737,63.7417763 C84.2894737,70.6277412 85.0211075,77.3702485 86.484375,83.9692982 C87.9476425,90.568348 90.314693,96.9952485 93.5855263,103.25 L93.5855263,103.25 L83.4287281,103.25 C79.8135965,97.3395468 77.0161732,91.1134868 75.0364583,84.5718202 C73.0567434,78.0301535 72.066886,71.3737208 72.066886,64.6025219 C72.066886,61.3890716 72.3107639,58.017818 72.7985197,54.488761 C73.2862756,50.9597039 74.0035636,47.4449927 74.9503838,43.9446272 C75.8972039,40.4442617 77.0735563,37.0586623 78.4794408,33.7878289 C79.8853253,30.5169956 81.5350877,27.504386 83.4287281,24.75 L83.4287281,24.75 Z M116.638158,24.75 C120.253289,30.6604532 123.050713,36.9152047 125.030428,43.5142544 C127.010143,50.1133041 128,56.7984284 128,63.5696272 C128,66.7830775 127.770468,70.1543311 127.311404,73.6833882 C126.852339,77.2124452 126.149397,80.7128107 125.202577,84.1844846 C124.255757,87.6561586 123.065058,91.0274123 121.630482,94.2982456 C120.195906,97.5690789 118.531798,100.552997 116.638158,103.25 L116.638158,103.25 L106.48136,103.25 C109.637427,97.1673977 111.975786,90.8696089 113.496436,84.3566338 C115.017087,77.8436586 115.777412,71.2015716 115.777412,64.4303728 C115.777412,57.5444079 115.031433,50.7732091 113.539474,44.1167763 C112.047515,37.4603436 109.723501,31.0047515 106.567434,24.75 L106.567434,24.75 Z M37.1101871,44.1061384 L37.1101871,56.702119 L49.0852391,52.799139 L51.3915454,59.8954661 L39.3277893,63.798446 L46.956341,74.1768244 L40.8357588,78.6120289 L33.2072072,68.1449464 L25.7560638,78.3459166 L19.8128898,73.8220081 L27.4414414,63.798446 L15.2889813,59.6293539 L17.5952876,52.5330268 L29.6590437,56.702119 L29.6590437,44.1061384 L37.1101871,44.1061384 Z M49.6493416,97.1303119 L57.6327096,97.1303119 L57.6327096,32.1989189 L49.6493416,32.1989189 L49.6493416,25.28 L66.6805267,25.28 L66.6805267,104.049231 L49.6493416,104.049231 L49.6493416,97.1303119 Z"></path>
|
||||
</svg>
|
||||
10
plugins/tiddlywiki/markdown-legacy/images/new-markdown-button.tid
Executable file
10
plugins/tiddlywiki/markdown-legacy/images/new-markdown-button.tid
Executable file
@@ -0,0 +1,10 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/images/new-markdown-button
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-new-markdown-button tc-image-button" viewBox="0 0 128 128" width="22pt" height="22pt">
|
||||
<g fill-rule="evenodd">
|
||||
<rect x="80" y="96" width="48" height="16" rx="8"></rect>
|
||||
<rect x="96" y="80" width="16" height="48" rx="8"></rect>
|
||||
<path d="M3.23876972,39.5396716 C3.23876972,35.9653274 6.13586353,33.0691646 9.7141757,33.0691646 L98.1283744,33.0691646 C101.706101,33.0691646 104.60378,35.9646626 104.60378,39.5396716 L104.60378,84.8296213 C104.60378,88.4039654 101.706687,91.3001282 98.1283744,91.3001282 L9.7141757,91.3001282 C6.13644944,91.3001282 3.23876972,88.4046302 3.23876972,84.8296213 L3.23876972,39.5396716 L3.23876972,39.5396716 Z M-2.15298617,39.5396716 L-2.15298617,84.8296213 C-2.15298617,91.3833243 3.15957363,96.6918841 9.7141757,96.6918841 L98.1283744,96.6918841 C104.684083,96.6918841 109.995536,91.382138 109.995536,84.8296213 L109.995536,39.5396716 C109.995536,32.9859686 104.682977,27.6774087 98.1283744,27.6774087 L9.7141757,27.6774087 C3.15846686,27.6774087 -2.15298617,32.9871549 -2.15298617,39.5396716 Z M14.0222815,80.5166164 L14.0222815,43.8526764 L24.8057933,43.8526764 L35.589305,57.3320661 L46.3728168,43.8526764 L57.1563286,43.8526764 L57.1563286,80.5166164 L46.3728168,80.5166164 L46.3728168,59.4887685 L35.589305,72.9681582 L24.8057933,59.4887685 L24.8057933,80.5166164 L14.0222815,80.5166164 Z M81.4192301,80.5166164 L65.2439624,62.723822 L76.0274742,62.723822 L76.0274742,43.8526764 L86.810986,43.8526764 L86.810986,62.723822 L97.5944978,62.723822 L81.4192301,80.5166164 Z"transform="translate(53.921275, 62.184646) rotate(-60.000000) translate(-53.921275, -62.184646) "></path>
|
||||
</g>
|
||||
</svg>
|
||||
16
plugins/tiddlywiki/markdown-legacy/new-markdown.tid
Executable file
16
plugins/tiddlywiki/markdown-legacy/new-markdown.tid
Executable file
@@ -0,0 +1,16 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/new-markdown-button
|
||||
tags: $:/tags/PageControls
|
||||
caption: {{$:/plugins/tiddlywiki/markdown-legacy/images/new-markdown-button}} {{$:/language/Buttons/NewMarkdown/Caption}}
|
||||
description: {{$:/language/Buttons/NewMarkdown/Hint}}
|
||||
list-after: $:/core/ui/Buttons/new-tiddler
|
||||
|
||||
\whitespace trim
|
||||
<$button tooltip={{$:/language/Buttons/NewMarkdown/Hint}} aria-label={{$:/language/Buttons/NewMarkdown/Caption}} class=<<tv-config-toolbar-class>>>
|
||||
<$action-sendmessage $message="tm-new-tiddler" type="text/markdown"/>
|
||||
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
|
||||
{{$:/plugins/tiddlywiki/markdown-legacy/images/new-markdown-button}}
|
||||
</$list>
|
||||
<$list filter="[<tv-config-toolbar-text>match[yes]]">
|
||||
<span class="tc-btn-text"><$text text={{$:/language/Buttons/NewMarkdown/Caption}}/></span>
|
||||
</$list>
|
||||
</$button>
|
||||
6
plugins/tiddlywiki/markdown-legacy/plugin.info
Executable file
6
plugins/tiddlywiki/markdown-legacy/plugin.info
Executable file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"title": "$:/plugins/tiddlywiki/markdown-legacy",
|
||||
"name": "Markdown (Legacy)",
|
||||
"description": "Markdown parser based on remarkable by Jon Schlinkert and remarkable-katex by Brad Howes",
|
||||
"list": "readme usage remarkable-license remarkable-katex-license"
|
||||
}
|
||||
7
plugins/tiddlywiki/markdown-legacy/readme.tid
Executable file
7
plugins/tiddlywiki/markdown-legacy/readme.tid
Executable file
@@ -0,0 +1,7 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/readme
|
||||
|
||||
This is a TiddlyWiki plugin for parsing Markdown text, using the [[Remarkable|https://github.com/jonschlinkert/remarkable]] library. If the KaTeX TiddlyWiki plugin is installed, KaTeX support is enabled using the [[remarkable-katex|https://github.com/bradhowes/remarkable-katex]] Remarkable plugin.
|
||||
|
||||
It is completely self-contained, and doesn't need an Internet connection in order to work. It works both in the browser and under Node.js.
|
||||
|
||||
[[Source code|https://github.com/Jermolene/TiddlyWiki5/blob/master/plugins/tiddlywiki/markdown-legacy]]
|
||||
36
plugins/tiddlywiki/markdown-legacy/usage.tid
Executable file
36
plugins/tiddlywiki/markdown-legacy/usage.tid
Executable file
@@ -0,0 +1,36 @@
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/usage
|
||||
|
||||
! Plugin Configuration
|
||||
|
||||
|!Config |!Default |!Description |
|
||||
| <code>[[breaks|$:/config/markdown/breaks]]</code>| ``false``|Remarkable library config: Convert '\n' in paragraphs into ``<br>`` |
|
||||
| <code>[[linkify|$:/config/markdown/linkify]]</code>| ``false``|Remarkable library config: Autoconvert URL-like text to links |
|
||||
| <code>[[linkNewWindow|$:/config/markdown/linkNewWindow]]</code>| ``true``|For external links, should clicking on them open a new window/tab automatically? |
|
||||
| <code>[[quotes|$:/config/markdown/quotes]]</code>| ``“”‘’``|Remarkable library config: Double + single quotes replacement pairs, when ``typographer`` enabled |
|
||||
| <code>[[renderWikiText|$:/config/markdown/renderWikiText]]</code>| ``true``|After Markdown is parsed, should any text elements be handed off to the ~WikiText parser for further processing? |
|
||||
| <code>[[renderWikiTextPragma|$:/config/markdown/renderWikiTextPragma]]</code>|<code><$view tiddler="$:/plugins/tiddlywiki/markdown-legacy" subtiddler="$:/config/markdown/renderWikiTextPragma" mode="inline"/></code>|When handing off to the ~WikiText parser, what pragma rules should it follow? |
|
||||
| <code>[[typographer|$:/config/markdown/typographer]]</code>| ``false``|Remarkable library config: Enable some language-neutral replacement + quotes beautification |
|
||||
|
||||
! Creating ~WikiLinks
|
||||
|
||||
Create wiki links with the usual Markdown link syntax targeting `#` and the target tiddler title:
|
||||
|
||||
```
|
||||
[link text](#TiddlerTitle)
|
||||
```
|
||||
|
||||
If the target tiddler has a space in its name, that name must be URL-escaped to be detected as a URL:
|
||||
|
||||
```
|
||||
[link text](#Test%20Tiddler)
|
||||
```
|
||||
|
||||
! Images
|
||||
|
||||
Markdown image syntax can be used to reference images by tiddler title or an external URI. For example:
|
||||
|
||||
```
|
||||

|
||||
|
||||

|
||||
```
|
||||
341
plugins/tiddlywiki/markdown-legacy/wrapper.js
Executable file
341
plugins/tiddlywiki/markdown-legacy/wrapper.js
Executable file
@@ -0,0 +1,341 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/markdown-legacy/wrapper.js
|
||||
type: application/javascript
|
||||
module-type: parser
|
||||
|
||||
Wraps up the remarkable parser for use as a Parser in TiddlyWiki
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var r = require("$:/plugins/tiddlywiki/markdown-legacy/remarkable.js");
|
||||
|
||||
var Remarkable = r.Remarkable,
|
||||
linkify = r.linkify,
|
||||
utils = r.utils;
|
||||
|
||||
///// Set up configuration options /////
|
||||
function parseAsBoolean(tiddlerName) {
|
||||
return $tw.wiki.getTiddlerText(tiddlerName).toLowerCase() === "true";
|
||||
}
|
||||
var pluginOpts = {
|
||||
linkNewWindow: parseAsBoolean("$:/config/markdown/linkNewWindow"),
|
||||
renderWikiText: parseAsBoolean("$:/config/markdown/renderWikiText"),
|
||||
renderWikiTextPragma: $tw.wiki.getTiddlerText("$:/config/markdown/renderWikiTextPragma").trim()
|
||||
};
|
||||
var remarkableOpts = {
|
||||
breaks: parseAsBoolean("$:/config/markdown/breaks"),
|
||||
quotes: $tw.wiki.getTiddlerText("$:/config/markdown/quotes"),
|
||||
typographer: parseAsBoolean("$:/config/markdown/typographer")
|
||||
};
|
||||
var accumulatingTypes = {
|
||||
"text": true,
|
||||
"softbreak": true
|
||||
};
|
||||
// If rendering WikiText, we treat katex nodes as text.
|
||||
if(pluginOpts.renderWikiText) {
|
||||
accumulatingTypes["katex"] = true;
|
||||
}
|
||||
|
||||
var md = new Remarkable(remarkableOpts);
|
||||
|
||||
// If tiddlywiki/katex plugin is present, use remarkable-katex to enable katex support.
|
||||
if($tw.modules.titles["$:/plugins/tiddlywiki/katex/katex.min.js"]) {
|
||||
var rk = require("$:/plugins/tiddlywiki/markdown-legacy/remarkable-katex.js");
|
||||
md = md.use(rk);
|
||||
}
|
||||
|
||||
if(parseAsBoolean("$:/config/markdown/linkify")) {
|
||||
md = md.use(linkify);
|
||||
}
|
||||
|
||||
function findTagWithType(nodes, startPoint, type, level) {
|
||||
for (var i = startPoint; i < nodes.length; i++) {
|
||||
if(nodes[i].type === type && nodes[i].level === level) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remarkable creates nodes that look like:
|
||||
* [
|
||||
* { type: 'paragraph_open'},
|
||||
* { type: 'inline', content: 'Hello World', children:[{type: 'text', content: 'Hello World'}]},
|
||||
* { type: 'paragraph_close'}
|
||||
* ]
|
||||
*
|
||||
* But TiddlyWiki wants the Parser (https://tiddlywiki.com/dev/static/Parser.html) to emit nodes like:
|
||||
*
|
||||
* [
|
||||
* { type: 'element', tag: 'p', children: [{type: 'text', text: 'Hello World'}]}
|
||||
* ]
|
||||
*/
|
||||
function convertNodes(remarkableTree, isStartOfInline) {
|
||||
let out = [];
|
||||
var accumulatedText = '';
|
||||
function withChildren(currentIndex, currentLevel, closingType, nodes, callback) {
|
||||
var j = findTagWithType(nodes, currentIndex + 1, closingType, currentLevel);
|
||||
if(j === false) {
|
||||
console.error("Failed to find a " + closingType + " node after position " + currentIndex);
|
||||
console.log(nodes);
|
||||
return currentIndex + 1;
|
||||
}
|
||||
let children = convertNodes(nodes.slice(currentIndex + 1, j));
|
||||
callback(children);
|
||||
return j;
|
||||
}
|
||||
function wrappedElement(elementTag, currentIndex, currentLevel, closingType, nodes) {
|
||||
return withChildren(currentIndex, currentLevel, closingType, nodes, function(children) {
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: elementTag,
|
||||
children: children
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < remarkableTree.length; i++) {
|
||||
var currentNode = remarkableTree[i];
|
||||
switch (currentNode.type) {
|
||||
case "paragraph_open":
|
||||
// If the paragraph is a "tight" layout paragraph, don't wrap children in a <p> tag.
|
||||
if(currentNode.tight) {
|
||||
i = withChildren(i, currentNode.level, "paragraph_close", remarkableTree, function(children) {
|
||||
Array.prototype.push.apply(out, children);
|
||||
});
|
||||
} else {
|
||||
i = wrappedElement("p", i, currentNode.level, "paragraph_close", remarkableTree);
|
||||
}
|
||||
break;
|
||||
|
||||
case "heading_open":
|
||||
i = wrappedElement("h" + currentNode.hLevel, i, currentNode.level, "heading_close", remarkableTree);
|
||||
break;
|
||||
|
||||
case "bullet_list_open":
|
||||
i = wrappedElement("ul", i, currentNode.level, "bullet_list_close", remarkableTree);
|
||||
break;
|
||||
|
||||
case "ordered_list_open":
|
||||
i = wrappedElement('ol', i, currentNode.level,'ordered_list_close', remarkableTree);
|
||||
break;
|
||||
|
||||
case "list_item_open":
|
||||
i = wrappedElement("li", i, currentNode.level, "list_item_close", remarkableTree);
|
||||
break;
|
||||
|
||||
case "link_open":
|
||||
i = withChildren(i, currentNode.level, "link_close", remarkableTree, function(children) {
|
||||
if(currentNode.href[0] !== "#") {
|
||||
// External link
|
||||
var attributes = {
|
||||
class: { type: "string", value: "tc-tiddlylink-external" },
|
||||
href: { type: "string", value: currentNode.href },
|
||||
rel: { type: "string", value: "noopener noreferrer" }
|
||||
};
|
||||
if(pluginOpts.linkNewWindow) {
|
||||
attributes.target = { type: "string", value: "_blank" };
|
||||
}
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: "a",
|
||||
attributes: attributes,
|
||||
children: children
|
||||
});
|
||||
} else {
|
||||
// Internal link
|
||||
out.push({
|
||||
type: "link",
|
||||
attributes: {
|
||||
to: { type: "string", value: $tw.utils.decodeURISafe(currentNode.href.substr(1)) }
|
||||
},
|
||||
children: children
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case "code":
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: currentNode.block ? "pre" : "code",
|
||||
children: [{ type: "text", text: currentNode.content }]
|
||||
});
|
||||
break;
|
||||
|
||||
case "fence":
|
||||
out.push({
|
||||
type: "codeblock",
|
||||
attributes: {
|
||||
language: { type: "string", value: currentNode.params },
|
||||
code: { type: "string", value: currentNode.content }
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case "image":
|
||||
out.push({
|
||||
type: "image",
|
||||
attributes: {
|
||||
tooltip: { type: "string", value: currentNode.alt },
|
||||
source: { type: "string", value: $tw.utils.decodeURIComponentSafe(currentNode.src) }
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case "softbreak":
|
||||
if(remarkableOpts.breaks) {
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: "br",
|
||||
});
|
||||
} else {
|
||||
accumulatedText = accumulatedText + '\n';
|
||||
}
|
||||
break;
|
||||
|
||||
case "hardbreak":
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: "br",
|
||||
});
|
||||
break;
|
||||
|
||||
case "th_open":
|
||||
case "td_open":
|
||||
var elementTag = currentNode.type.slice(0, 2);
|
||||
i = withChildren(i, currentNode.level, elementTag + "_close", remarkableTree, function(children) {
|
||||
var attributes = {};
|
||||
if(currentNode.align) {
|
||||
attributes.style = { type: "string", value: "text-align:" + currentNode.align };
|
||||
}
|
||||
out.push({
|
||||
type: "element",
|
||||
tag: elementTag,
|
||||
attributes: attributes,
|
||||
children: children
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
case "hr":
|
||||
out.push({
|
||||
type: 'element',
|
||||
tag: 'hr',
|
||||
});
|
||||
break;
|
||||
|
||||
case "inline":
|
||||
out = out.concat(convertNodes(currentNode.children, true));
|
||||
break;
|
||||
|
||||
case "text":
|
||||
// We need to merge this text block with the upcoming text block and parse it all together.
|
||||
accumulatedText = accumulatedText + currentNode.content;
|
||||
break;
|
||||
|
||||
case "katex":
|
||||
// If rendering WikiText, convert the katex node back to text for parsing by the WikiText LaTeX parser.
|
||||
if(pluginOpts.renderWikiText) {
|
||||
// If this is a block, add a newline to trigger the KaTeX plugins block detection.
|
||||
var displayModeSuffix = currentNode.block ? "\n" : "";
|
||||
accumulatedText = accumulatedText + "$$" + currentNode.content + displayModeSuffix + "$$";
|
||||
} else {
|
||||
out.push({
|
||||
type: "latex",
|
||||
attributes: {
|
||||
text: { type: "text", value: currentNode.content },
|
||||
displayMode: { type: "text", value: currentNode.block ? "true" : "false" }
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if(currentNode.type.substr(currentNode.type.length - 5) === "_open") {
|
||||
var tagName = currentNode.type.substr(0, currentNode.type.length - 5);
|
||||
i = wrappedElement(tagName, i, currentNode.level, tagName + "_close", remarkableTree);
|
||||
} else {
|
||||
console.error("Unknown node type: " + currentNode.type, currentNode);
|
||||
out.push({
|
||||
type: "text",
|
||||
text: currentNode.content
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
// We test to see if we process the block now, or if there's
|
||||
// more to accumulate first.
|
||||
if(accumulatedText
|
||||
&& (
|
||||
remarkableOpts.breaks ||
|
||||
(i+1) >= remarkableTree.length ||
|
||||
!accumulatingTypes[remarkableTree[i+1].type]
|
||||
)
|
||||
) {
|
||||
// The Markdown compiler thinks this is just text.
|
||||
// Hand off to the WikiText parser to see if there's more to render
|
||||
// But only if it's configured to, and we have more than whitespace
|
||||
if(!pluginOpts.renderWikiText || accumulatedText.match(/^\s*$/)) {
|
||||
out.push({
|
||||
type: "text",
|
||||
text: accumulatedText
|
||||
});
|
||||
} else {
|
||||
// If we're inside a block element (div, p, td, h1), and this is the first child in the tree,
|
||||
// handle as a block-level parse. Otherwise not.
|
||||
var parseAsInline = !(isStartOfInline && i === 0);
|
||||
var textToParse = accumulatedText;
|
||||
if(pluginOpts.renderWikiTextPragma !== "") {
|
||||
textToParse = pluginOpts.renderWikiTextPragma + "\n" + textToParse;
|
||||
}
|
||||
var wikiParser = $tw.wiki.parseText("text/vnd.tiddlywiki", textToParse, {
|
||||
parseAsInline: parseAsInline
|
||||
});
|
||||
var rs = wikiParser.tree;
|
||||
|
||||
// If we parsed as a block, but the root element the WikiText parser gave is a paragraph,
|
||||
// we should discard the paragraph, since the way Remarkable nests its nodes, this "inline"
|
||||
// node is always inside something else that's a block-level element
|
||||
if(!parseAsInline
|
||||
&& rs.length === 1
|
||||
&& rs[0].type === "element"
|
||||
&& rs[0].tag === "p"
|
||||
) {
|
||||
rs = rs[0].children;
|
||||
}
|
||||
|
||||
// If the original text element started with a space, add it back in
|
||||
if(rs.length > 0
|
||||
&& rs[0].type === "text"
|
||||
&& (accumulatedText[0] === " " || accumulatedText[0] === "\n")
|
||||
) {
|
||||
rs[0].text = " " + rs[0].text;
|
||||
}
|
||||
out = out.concat(rs);
|
||||
}
|
||||
accumulatedText = '';
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
var MarkdownParser = function(type, text, options) {
|
||||
var tree = md.parse(text, {});
|
||||
//console.debug(tree);
|
||||
tree = convertNodes(tree);
|
||||
//console.debug(tree);
|
||||
|
||||
this.tree = tree;
|
||||
};
|
||||
|
||||
exports["text/x-markdown"] = MarkdownParser;
|
||||
exports["text/markdown"] = MarkdownParser;
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user