In fact Pete31, you could probably run your script as a smart rule, e.g. when save a markdown file, it automatically runs your script, which would be quite an elegant solution, ensuring the user always has their links functional on iOS if created on Mac.
Would you know how that smart rule might be configured?
First off, Iām not sure itās a good idea to convert WikiLinks automatically to Markdown links. The initial script wasnāt written to do that. Iāll show how it maybe could be possible to use it in a Smart Rule but I didnāt test whether problems could arise from such usage.
If you really want to do that then the linked script wonāt work as we canāt use AppleScriptObjC directly in Smart Rules.
So you need to create a Script Library that contains everything that uses AppleScriptObjC. To do so:
-
In Finder:
- press ā§āG
- paste
~/Library/Script Libraries
- if no window is opened
- paste
~/Library/
- create folder
Script Libraries
- paste
-
In Script Editor.app
- create new document
- paste this script:
-- Script Library - Convert WikiLinks to Markdown links (Smart Rule version)
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
on regexFind(theText, thePattern)
try
set aString to current application's NSString's stringWithString:theText
set {theExpr, theError} to current application's NSRegularExpression's regularExpressionWithPattern:(thePattern) options:0 |error|:(reference)
set theMatches to theExpr's matchesInString:aString options:0 range:{0, aString's |length|()}
set theResults to {}
repeat with aMatch in theMatches
set theRange to (aMatch's rangeAtIndex:0)
set theString to (aString's substringWithRange:theRange) as text
if theString is not in theResults then
set end of theResults to theString
end if
end repeat
return theResults
on error error_message number error_number
activate
display alert "Error: Handler \"regexFind\"" message error_message as warning
error number -128
end try
end regexFind
on regexReplace(theText, thePattern, theRepacement)
try
set theString to current application's NSString's stringWithString:theText
set newString to theString's stringByReplacingOccurrencesOfString:(thePattern) withString:(theRepacement) options:(current application's NSRegularExpressionSearch) range:{location:0, |length|:length of theText}
set newText to newString as string
on error error_message number error_number
activate
display alert "Error: Handler \"regexReplace\"" message error_message as warning
error number -128
end try
end regexReplace
on decodeHTML(theText)
try
-- https://macscripter.net/viewtopic.php?pid=190404#p190404
set ca to current application
set str to ca's class "NSMutableString"'s stringWithString:(theText)
set HTMLData to str's dataUsingEncoding:(ca's NSUTF8StringEncoding)
set attributedStr to ca's class "NSAttributedString"'s alloc()'s initWithHTML:(HTMLData) documentAttributes:(missing value)
set decodedString to attributedStr's |string|()
return decodedString as text
on error error_message number error_number
activate
display alert "Error: Handler \"decodeHTML\"" message error_message as warning
error number -128
end try
end decodeHTML
- press āS
- press ā§āG
- paste
~/Script Libraries/Script Library - Convert WikiLinks to Markdown links (Smart Rule version).scpt
- save
Then create a Smart Rule with this script:
-- Convert WikiLinks to Markdown links (Smart Rule version)
property useSuffix : true -- include suffix in markdown link name
on performSmartRule(theRecords)
tell application id "DNtp"
try
set theEscapePattern to "\\,|\\!|\\?|\\.|\\(|\\)|\\[|\\]|\\{|\\}|\\*|\\\\|\\^|\\+|\\<|\\>|\\||\\$|\\="
repeat with thisRecord in theRecords
set theType to (type of thisRecord) as string
if theType is in {"markdown", "Ā«constant ****mkdnĀ»"} then
set the_record to {}
set theWikiLinkRecords to outgoing Wiki references of thisRecord
if theWikiLinkRecords ā {} then
repeat with thisWikiRecord in theWikiLinkRecords
set thisWikiRecord_RefURL to reference URL of thisWikiRecord
set thisWikiRecord_Type to (type of thisWikiRecord) as string
set thisWikiRecord_Kind to kind of thisWikiRecord
set {thisWikiRecord_NameWithoutSuffix, thisWikiRecord_Suffix} to {item 1, item 2} of my recordName(name of thisWikiRecord, filename of thisWikiRecord)
set end of the_record to {namewithoutsuffix_:thisWikiRecord_NameWithoutSuffix, suffix_:thisWikiRecord_Suffix, rurl_:thisWikiRecord_RefURL, neglookbehind_:{"\\t", "\\["}, neglookahead_:{("(\\." & thisWikiRecord_Suffix & ")?" & "\\]\\(") as string}, pattern_:"", type_:thisWikiRecord_Type, kind_:thisWikiRecord_Kind}
end repeat
set theLinkTexts to {}
set theSource to source of thisRecord
set theSource_Body to item 2 of my tid(theSource, ("</head>" & linefeed & "<body>") as string)
set theURLs to get links of theSource_Body
if theURLs ā {} then
repeat with thisURL in theURLs
set thisURL to thisURL as string
set thisURL_escaped to script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s regexReplace(thisURL, theEscapePattern, "\\\\$0")
set thisURL_LinkTexts to script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s regexFind(theSource_Body, (("(?<=\\<a href=\"" & thisURL_escaped & "\">)(.*?)(?=\\</a\\>)") as string))
repeat with thisLinkText in thisURL_LinkTexts
set thisLinkText to thisLinkText as string
if thisLinkText starts with "[[" and thisLinkText ends with "]]" then set thisLinkText to (characters 3 thru -3 in thisLinkText) as string
if theLinkTexts does not contain thisLinkText then set end of theLinkTexts to thisLinkText
set thisLinkText_decoded to script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s decodeHTML(thisLinkText)
if thisLinkText_decoded ā thisLinkText then set end of theLinkTexts to thisLinkText_decoded
end repeat
end repeat
end if
repeat with this_record in the_record
set thisWikiRecord_NameWithoutSuffix to namewithoutsuffix_ of this_record
set thisWikiRecord_NameWithoutSuffix_Length to length of thisWikiRecord_NameWithoutSuffix
set thisSuffix to ("." & (suffix_ of this_record)) as string
considering case
repeat with thisLinkText in theLinkTexts
set thisLinkText to thisLinkText as string
if thisWikiRecord_NameWithoutSuffix is in thisLinkText then
if thisWikiRecord_NameWithoutSuffix ā thisLinkText then
set thisSubStringOffsets to my getSubStringOffsets(thisWikiRecord_NameWithoutSuffix, thisLinkText)
set thisLinkText_Length to length of thisLinkText
repeat with thisOffset in thisSubStringOffsets
if thisOffset > 1 then
set thisNegLookbehind to characters 1 thru (thisOffset - 1) in thisLinkText as string
set thisNegLookbehind_escaped to ("(\\[)?" & script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s regexReplace(thisNegLookbehind, theEscapePattern, "\\\\$0")) as string
if neglookbehind_ of this_record does not contain thisNegLookbehind_escaped then
set end of neglookbehind_ of this_record to thisNegLookbehind_escaped
end if
end if
if ((thisOffset + thisWikiRecord_NameWithoutSuffix_Length)) < thisLinkText_Length then
set thisNegLookahead to characters (thisOffset + thisWikiRecord_NameWithoutSuffix_Length) thru -1 in thisLinkText as string
if thisNegLookahead ā thisSuffix then
set thisNegLookahead_escaped to (script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s regexReplace(thisNegLookahead, theEscapePattern, "\\\\$0") & "(\\]\\()?") as string
if neglookahead_ of this_record does not contain thisNegLookahead_escaped then
set end of neglookahead_ of this_record to thisNegLookahead_escaped
end if
end if
end if
end repeat
end if
end if
end repeat
end considering
end repeat
set newText to plain text of thisRecord
repeat with this_record in the_record
set thisWikiRecord_NameWithoutSuffix to namewithoutsuffix_ of this_record
set thisWikiRecord_NameWithoutSuffix_escaped to script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s regexReplace(thisWikiRecord_NameWithoutSuffix, theEscapePattern, "\\\\$0")
set thisWikiRecord_RefURL to rurl_ of this_record
set thisWikiRecord_Suffix to suffix_ of this_record
if useSuffix = true then
set thisWikiRecord_Type to type_ of this_record
set thisWikiRecord_Kind to kind_ of this_record
if thisWikiRecord_Type is in {"group", "Ā«constant ****DTgrĀ»", "smart group", "Ā«constant ****DTsgĀ»"} or thisWikiRecord_Kind = "Tag" then
set thisMarkdownLink to ("[" & thisWikiRecord_NameWithoutSuffix_escaped & "](" & thisWikiRecord_RefURL & ")") as string
else
set thisMarkdownLink to ("[" & thisWikiRecord_NameWithoutSuffix_escaped & "." & thisWikiRecord_Suffix & "](" & thisWikiRecord_RefURL & ")") as string
end if
else
set thisMarkdownLink to ("[" & thisWikiRecord_NameWithoutSuffix_escaped & "](" & thisWikiRecord_RefURL & ")") as string
end if
set thisPattern to ("(?<!" & my tid((neglookbehind_ of this_record), "|") & ")" & "(\\[\\[)?" & thisWikiRecord_NameWithoutSuffix_escaped) as string
set thisPattern to (thisPattern & "(?!" & my tid((neglookahead_ of this_record), "|") & ")") as string
set thisPattern to (thisPattern & "(\\." & thisWikiRecord_Suffix & ")?" & "(\\]\\])?" & "(\\." & thisWikiRecord_Suffix & ")?") as string
set pattern_ of this_record to thisPattern
set newText to script "Script Library - Convert WikiLinks to Markdown links (Smart Rule version)"'s regexReplace(newText, thisPattern, thisMarkdownLink)
end repeat
set plain text of thisRecord to newText
end if
end if
end repeat
on error error_message number error_number
script "error"'s defaultError(error_message, error_number, path to me)
end try
end tell
end performSmartRule
on recordName(theName, theFilename)
set theSuffix to my getSuffix(theFilename)
if theName ends with theSuffix and theName ā theSuffix then set theName to characters 1 thru -((length of theSuffix) + 2) in theName as string
return {theName, theSuffix}
end recordName
on getSuffix(thePath)
set revPath to reverse of characters in thePath as string
set theSuffix to reverse of characters 1 thru ((offset of "." in revPath) - 1) in revPath as string
end getSuffix
on tid(theInput, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
if class of theInput = text then
set theOutput to text items of theInput
else if class of theInput = list then
set theOutput to theInput as text
end if
set AppleScript's text item delimiters to d
return theOutput
end tid
on getSubStringOffsets(theSubstring, theText)
try
set theSubstringOffsets to {}
set x to 1
repeat (count (characters in theText)) times
set thisOffset to (offset of theSubstring in (characters x thru -1 in theText) as string)
if thisOffset > 0 then
set end of theSubstringOffsets to (thisOffset + x - 1)
set x to x + thisOffset
else
exit repeat
end if
end repeat
return theSubstringOffsets
on error error_message number error_number
activate
display alert "Error: Handler \"getSubStringOffsets\"" message error_message as warning
error number -128
end try
end getSubStringOffsets
Again, itās not tested.
Thanks Pete31, you might be right, it may not be a good idea, I did try the original suggestion prior to posting, but of course it doesnāt work, I personally would love DT3 links to work like [[ wiki links but use item links, I hope that is possible in the future. In the. mean time will try the method you mention carefully.
+1 for native wiki link support in DTTG.
Yet another request for [[link]] style wiki link support in DTTG.
My use case is using DEVONThink to index an Obsidian vault. Wikilinks in Obsidian are easy to create and use and navigate. I want to be able to effectively āclickā on a wikilink in a note in DTTG and have it open up the linked note.
Adding my eagerness for a square bracket or other linking support in future DTTG. I read a ton of research material on my ipad and annotate as I go. I often notice unexpected connections between names, organizations and other subjects connected to the book Iām writing. As I annotate while reading Iād like to be able to quickly pull up these connections or otherwise related subjects on the fly. If such a feature existed I could see myself quickly referring to other mentions of these topics, my own discussions of them, their relevance to a different focus, or which chapter Iām referencing them (might also be useful when citing sources in my writing). Iām eager to try some of the workarounds via synching with DT3.
I appreciate the warnings that this is would be a complicated feature addition and that other improvements might be higher priority, but please include my interest in the tally of feature requests.
While we wait for wikilinks on DTTG (and Iād note that as Zettelkasten-based note management has surged in popularity, maybe reconsider bumping wikilinks up on the DTTG roadmap as itās practically useless without them for that sort of thing), I have a suggestion.
When you double tap on a word to select it, iOS brings up a pop up menu. You already customize that menu by adding a āCaptureā item. Might I request another customization and add āSearchā? That would allow us to at least quickly search the database for the wikilinked term and jump to the document that way. Right now I have to copy, then back all the way out to the application Home Screen and paste in the search box from there. The juice is rarely worth the squeeze.
Hard agree, here. The lack of wiki links is the most painful thing about DTTG right now. With Zettelkasten gaining so many adherents it feels like the right time to make wiki links a priority. Iām all for limiting it to double square brackets, and trashing the other types. Even limiting the link to the same database would be fine.
Link conversion is just ok. That means clicking the link in any other piece of software opens DEVONthink instead of staying inside the app youāre currently using.
The lack of even a response on this has led me to consider other options. Iām using Craft for my Zettelkasten, which is really fantastic for that use. Iām still keeping reference material in DEVONthink, but itās not my go to for everything anymore.
Just want to add my voice to the chorus. Support for wiki-style linking on mobile is a must for those of us that want to use DEVONthink as a wiki and productively use it on iOS and iPadOS.
Ditto! On wiki-style linking on mobile.
+1, thanks
+1 for native wikilink support in DTTG
+1, wiki links in DTTG (names and aliases in particular) would add a lot of value
To everyone singing in this choir nowā¦
WikiLinks of any kind will not be implemented until our next-gen text editor is available in DEVONthink To Go. Trying to Frankenpiece it together with the current rich text framework would be an exercise in frustration for you as well as us.
And note Iām not claiming WikiLinking is the next feature after the text editor. Iām just stating the new editor will increase the potential for supporting WikiLinks in DEVONthink To Go.
Cheers, and as always, thanks for your patience and understanding!
BTW I just found out that transclusion with wiki links does work on current DTTG!
Didnāt expect that at all
Just tried notebooks 11 and the formatted note on there is rather amazing, wiki links etc but the search is horribly slow unlike devonthink, the performance is night and day.
As much as the mobile editor is not a wonderfull experience in its current state, the rest of the mobile app is far ahead and this is going to be well worth the wait.
I have not seen transclusion with wiki links work in DevonThink to go. I have not even seen wiki links work. Am I missing something?
WikiLinks are currently not supported in DEVONthink To Go.
However, file transclusions do work, e.g., {{transcluded filename}}
.
Searching for proper syntax for DTTG Transclusion and I also found that ![[ works for transclude as does {{.