with the recent introduction of a central group of images (which is fantastic for assets management), I am on a hunt for a way to export one single markdown note with all the images associated with it (.e.g to be shared with co-workers etc) as a markdown file + folder with images.
I wonder if there is a better way for that as searching through all the associated image files in a central group manually … Maybe there is some script which could be provided in the future to make this process simpler?
Maybe an option could be added to “convert to” which would basically provide a text bundle format with a markdown file and all associated assets to it.
The existing context menu options of “Convert to PDF…” and Convert to Formatted Note" both work for me—and certainly include any image which is included and which is the subject of an item link.
You could probably create an archive containing the relevant files. I posted a script to create an archive from the selected DT documents here a while ago, you could start from there.
Converting to paginated/single page PDF or rich text documents is already an option. The next release will also improve the conversion to formatted notes & web archives (and embed images using relative links inside the database).
to formatted notes & web archives (and embed images using relative links inside the database).
Thanks - that sounds very interesting.
Ideally I am looking for way to export a markdown document with a separate folder with all images associated with that markdown. By having same name of that folder as the global setting in DT3, relative paths in the md can stay the same … what is needed is the ability to pull in the images associated with that particular file.
This approach would allow to share separate notes between multiple “second brain” setups e.g. private <> corporate or private <> another person.
-- Export Markdown with linked images
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
tell application id "DNtp"
try
set theRecords to selected records
if theRecords = {} then error "Please select some Markdown records"
set thePath to POSIX path of (choose folder)
set theImageDestinationName to my getImageDestinationFromPlist()
show progress indicator "Exporting... " steps ((count theRecords) + 1) with cancel button
repeat with thisRecord in theRecords
set thisRecord_Type to (type of thisRecord) as string
if thisRecord_Type is in {"markdown", "«constant ****mkdn»"} then
set thisRecord_Name to (name without extension of thisRecord) as string
step progress indicator "... " & thisRecord_Name
set thisTempGroup to create record with {name:thisRecord_Name, type:group, exclude from search:true} in root of database of thisRecord
set thisExportFolderPath to export record thisTempGroup to thePath
set thisExportSubfolderPath to thisExportFolderPath & "/" & theImageDestinationName
set thisRecord_Text to plain text of thisRecord
set thisRecord_Text_modified to thisRecord_Text
set thisRecord_Location to location of thisRecord
set theLinkURLsAndRanges to my regexFindStringAndRange(thisRecord_Text, "\\!\\[.*?\\]\\((.*?)\\)", 1)
set theLinkURLsAndRanges_reverse to reverse of theLinkURLsAndRanges
repeat with thisItem in theLinkURLsAndRanges_reverse
set replaceLink to missing value
set thisLinkURL to MatchString of thisItem
set thisLinkURL_Range to MatchRange of thisItem
if thisLinkURL starts with "x-devonthink" then
set thisImageRecord to get record with uuid thisLinkURL
if thisImageRecord ≠ missing value then
set replaceLink to true
end if
else
if thisLinkURL does not contain "%" then
set thisImageRecord to get record at thisRecord_Location & thisLinkURL
else
set thisImageRecord to get record at thisRecord_Location & my percentDecode(thisLinkURL)
end if
if thisImageRecord ≠ missing value then
if thisLinkURL starts with ((theImageDestinationName & "/") as string) then
if (item 2 of (my tid(thisLinkURL, "/"))) ≠ ((filename of thisImageRecord) as string) then
set replaceLink to true
end if
else
set replaceLink to true
end if
end if
end if
if replaceLink = true then
set thisLinkURL_modified to theImageDestinationName & "/" & my percentEncode((filename of thisImageRecord) as string)
set thisRecord_Text_modified to my replaceInRange(thisRecord_Text_modified, thisLinkURL, thisLinkURL_modified, thisLinkURL_Range)
end if
if thisImageRecord ≠ missing value then export record thisImageRecord to thisExportSubfolderPath
end repeat
if not indexed of thisRecord then
set thisDuplicatedRecord to duplicate record thisRecord to thisTempGroup
else
consolidate record thisRecord
set thisDuplicatedRecord to duplicate record thisRecord to thisTempGroup
deconsolidate record thisRecord
end if
set plain text of thisDuplicatedRecord to thisRecord_Text_modified
export record thisDuplicatedRecord to thisExportFolderPath
delete record thisTempGroup
end if
end repeat
step progress indicator
hide progress indicator
on error error_message number error_number
hide progress indicator
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
on getImageDestinationFromPlist()
try
if current application's id = "com.devon-technologies.think3" then
set theDefaults to current application's NSUserDefaults's standardUserDefaults()
else
set theDefaults to current application's NSUserDefaults's alloc()'s initWithSuiteName:"com.devon-technologies.think3"
end if
set theImageDestination to (theDefaults's dictionaryRepresentation())'s stringForKey:"ImageDestination"
return theImageDestination as string
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"getImageDestinationFromPlist\"" message error_message as warning
error number -128
end try
end getImageDestinationFromPlist
on regexFindStringAndRange(theText, thePattern, theCaptureGroup)
try
set theString to current application's NSString's stringWithString:theText
set {theRegex, theError} to current application's NSRegularExpression's regularExpressionWithPattern:(thePattern) options:0 |error|:(reference)
set theMatches to theRegex's matchesInString:theString options:0 range:{0, theString's |length|()}
set theResults to {}
repeat with thisMatch in theMatches
set thisMatchRange to (thisMatch's rangeAtIndex:theCaptureGroup)
set thisMatchString to (theString's substringWithRange:thisMatchRange) as string
set end of theResults to {MatchRange:thisMatchRange, MatchString:thisMatchString}
end repeat
return theResults
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"regexFindStringAndRange\"" message error_message as warning
error number -128
end try
end regexFindStringAndRange
on replaceInRange(theText, thePattern, theRepacement, theRange)
try
set theString to (current application's NSString's stringWithString:theText)
set newString to (theString's stringByReplacingOccurrencesOfString:(thePattern) withString:(theRepacement) options:0 range:theRange)
return newString as string
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"replaceInRange\"" message error_message as warning
error number -128
end try
end replaceInRange
on percentDecode(theText)
try
set theString to (current application's NSString's stringWithString:theText)
set theString_decoded to theString's stringByRemovingPercentEncoding()
return theString_decoded as string
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"percentDecode\"" message error_message as warning
error number -128
end try
end percentDecode
on percentEncode(theText)
try
set theString to (current application's NSString's stringWithString:theText)
set theCharacterSet to current application's NSCharacterSet's alphanumericCharacterSet()
set theString_encoded to (theString's stringByAddingPercentEncodingWithAllowedCharacters:theCharacterSet)
return theString_encoded as string
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"percentEncode\"" message error_message as warning
error number -128
end try
end percentEncode
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
@pete31 Pete! This is fabulous Your contribution on the forum is beyond all levels of recognition - thank you so much for this work. Works like magic, indeed and now would allow easy sharing of markdown notes between different setups!!! THANK YOU.
See page 135 of the user guide (also available through the in-app Help):
Internal metadata for the items is preserved in invisible .DEVONtech_storage files, used for reimporting into DEVONthink. If you will not be reimporting the exported files, you can safely delete .DEVONtech_storage files.