Script (Updated): Markdown formatting + image capture + link copying utility (probably less useless)

Updated Version (V1b6) with three additional functions: copy item link, copy cited text link, copy bookmark link.
The source document can be pdf, rtf, plain text, or markdown file, the links are in markdown format, saved in clipboard for pasting to markdown file.
For my usage, I attached shift-ctrl-M to the script as a shortcut.

(1) If text is selected in a markdown file, this is the menu:
Formatting functions are available.

(2) If no text is selected in any types of current document, or text is selected in a non-markdown document, this is the menu:
The script assumes that the user is planning to use function 1-5 for the two scenarios mentioned above.
Screenshot 2020-03-11 at 16.12.33

Scenario: Some text is selected in a pdf, function 3-5 are used respectively.

Configuration 1: The three types of link display filename as link’s name.

Configuration 2: The three types of link display simple link’s name.
DT Item link will always show the full filename regardless of the configuration.

Configuration 3: two other settings
Example 7: the link’s name is placed before the cited text.
Example 8: the search string in the DT’s link is based on a string instead of based on position.

There are quite a few changes, so I post the new script here:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

--By Ngan 2020.03.02
--v1b6 2020.03.11
--add 3 functions. Item-link, cite link, bookmark link

-- settings for "3. Cite Link", "4. Bookmark Link", "5. Item Link"
property linkName : "DF" -- DS:[position only] DF:[document name], "DA" [aliases name]
property linkBeforeCitedText : true -- true: put link as the first line before cited text. false: link after the cited text
property searchMethod : "S" -- "S" search by string  "P" search by position (paragraph for rtf, page for pdf). For markdown always search by string
property queryWordLen : 10 -- number of words used in search string


--Note for "property useFilepathForImageLink"
-- if "useFilepathForImageLink: true", image link is based on file path. Image in md can only be viewed in one computer and external md editor.
--if "useFilepathForImageLink:false", image link is based on DT Link. Image in md can be viewed in DT3 and DTTG, BUT NOT in external md editor
property useFilepathForImageLink : false

-- Note for "property useOneImageAssetsGpForAllDBs"
--if useOneImageAssetsGpForAllDBs: true,  use one image assets group for ALL databases
--if useOneImageAssetsGpForAllDBs: false,  use one image assets group for EACH database
property useOneImageAssetsGpForAllDBs : true

--Note: only need to define "property imgAssetsUUID" if useOneImageAssetsGpForAllDBs : true
--if useFilepathForImageLink : true, this group must be an index group
property imgAssetsUUID : "9A72DEC0-A97E-XXXX-XXXXXXXXXXXX" -- uuid of  the index folder for the centralised image assets

--Note: only need to define "property imgAssetsLocation" if useOneImageAssetsGpForAllDBs : false
--if useFilepathForImageLink : true, this group must be an index group
property imgAssetsLocation : "/your group/subgroup" -- example only


-- ignore these settings, for my personal used only
property characterToTrim : "- "
property regexForCardUID : "[c/n][0-9][0-9][0-9][0-9]"
property theCmd : missing value -- just for flexibility, probaby won't be used
--

-- How the list is displayed
property theStyle : {"I. Italic", "B. Bold", "S. Bold&Italic", "U. Underline", "C. Chapter", "S. Section", "X. Clear All Text Format"}
property theOtherFunction : {"1. Build Table", "2. Capture Image Link", "3. Cite Link", "4. Bookmark Link", "5. Item Link"}


global theWin, theDoc, theImgAsset
global theDocType, withText
global theCitedText

tell application id "DNtp"
	
	set theWin to think window 1
	set theDoc to content record of think window 1
	set theCitedText to selected text of theWin as string
	
	
	set theDocLoc to location of theDoc
	if useOneImageAssetsGpForAllDBs then
		if imgAssetsUUID is not missing value then set theImgAsset to get record with uuid imgAssetsUUID
	else
		if imgAssetsLocation is not missing value then set theImgAsset to get record at imgAssetsLocation
	end if
	
	if (type of theDoc is markdown) and (exists (selected text of think window 1)) then
		set theList to theStyle & " " & theOtherFunction
	else
		set theList to theOtherFunction
	end if
	
	set theChoice to (choose from list theList with prompt "Items 1-5 are created in clipboard" with empty selection allowed) as string
	set theChoice to text 1 of theChoice
	
	
	if theChoice is "I" then
		set (selected text of think window 1) to "*" & (selected text of think window 1) & "*"
	else if theChoice is "B" then
		set (selected text of think window 1) to "**" & (selected text of think window 1) & "**"
	else if theChoice is "S" then
		set (selected text of think window 1) to "***" & (selected text of think window 1) & "***"
	else if theChoice is "U" then
		set (selected text of think window 1) to "<u>" & (selected text of think window 1) & "</u>"
	else if theChoice is "C" then
		set (selected text of think window 1) to "### " & (selected text of think window 1)
	else if theChoice is "S" then
		set (selected text of think window 1) to "#### " & (selected text of think window 1)
	else if theChoice is "X" then
		set (selected text of think window 1) to my TrimText(my TrimText(my TrimText(my TrimText(my TrimText(selected text of think window 1, "*"), "<u>"), "</u>"), "#"), "==")
		
	else if theChoice is "1" then
		activate
		my buildTable()
		return
	else if theChoice is "2" then
		my grapImgandGetMDLink()
		return
	else if theChoice is "3" then
		my getLink(theWin, theDoc, theCitedText, queryWordLen, "C")
	else if theChoice is "4" then
		my getLink(theWin, theDoc, theCitedText, queryWordLen, "B")
	else if theChoice is "5" then
		my getLink(theWin, theDoc, theCitedText, queryWordLen, "D")
	end if
	
	
end tell

on buildTable()
	local numRow, numCol, theHD1, theHD2
	tell application id "DNtp"
		
		set a to text returned of (display dialog "Row, Col" default answer "3,3")
		
		set numRow to (item 1 of my strToList(a, ",")) as integer
		set numCol to (item 2 of my strToList(a, ",")) as integer
		
		set {theHD1, theHD2, theCol, theRow} to {" ", " ", " ", " "}
		
		repeat numCol times
			set theHD1 to theHD1 & "   |"
			set theHD2 to theHD2 & "---|"
		end repeat
		
		repeat numCol times
			set theRow to theRow & "   |"
		end repeat
		
		set theCol to ""
		repeat numRow times
			set theCol to theCol & return & theRow
		end repeat
		
		set the clipboard to theHD1 & return & theHD2 & theCol & return & return
		display alert "paste the layout to the  file" giving up after 1
	end tell
end buildTable

on grapImgandGetMDLink()
	
	
	set dateSting to my getDateString()
	
	do shell script "screencapture -ci"
	
	tell application id "DNtp"
		set theImageFile to paste clipboard to theImgAsset
		set the name of theImageFile to dateSting
		
		if useFilepathForImageLink then
			set theLink to path of theImageFile
			set the clipboard to "<img src=\"" & theLink & "\" style=\"zoom:50%;\" >"
		else
			set theLink to reference URL of theImageFile
			set the clipboard to "![](" & theLink & ")"
		end if
		
		
		
	end tell
end grapImgandGetMDLink

on getLink(theWin, theDoc, theCitedText, queryWordLen, linkType)
	local rPos, cPos -- realPositionOfText, citedPositionOfText
	local dl, pl, sl, cl -- docBackLink, positionBackLink, searchStringBackLink,customBackLink
	local dldn, pldn, sldn, cldn -- name of dl,pl,sl,cl
	local ctl, tq -- citedTextAsList, textQuery 
	local theID, theYear, theAuthor, theType
	
	local dn, an, cn
	local theBLDisplay, theBL
	
	
	tell application id "DNtp"
		
		set {dn, dl, an, cn} to {name of theDoc, reference URL of theDoc, aliases of theDoc, get custom meta data for theCmd from theDoc default value theCmd}
		
		
		-- extract the search string of the selected text or page
		if theCitedText is not "" then
			set ctl to my strToList(theCitedText, " ")
			set tq to items 1 thru (my min(queryWordLen, length of ctl)) of ctl
			set tq to my listToStr(tq, "%20")
			set sl to dl & "?search=" & tq
			set sldn to "Goto"
		else
			set sl to ""
			set sldn to ""
		end if
		
		-- extract the position of the selected text or page
		if the kind of theDoc is in "PDF+Text" then
			set {rPos, cPos} to {(current page of theWin), (current page of theWin) + 1}
			set pl to dl & "?page=" & rPos
			set pldn to " Page " & (rPos + 1)
			
		else if kind of theDoc is "Markdown" then
			if theCitedText is not "" then
				set pl to dl & "?search=" & tq
				set pldn to ""
			else
				set pl to dl
				set pldn to ""
			end if
			
			
		else
			if kind of theDoc is not "Markdown Document" then
				set {rPos, cPos} to {(current line of theWin), my getNonBlankParagraphNum(theWin, current line of theWin)}
			else
				set {rPos, cPos} to {0, 0}
			end if
			set pl to dl & "?line=" & rPos
			set pldn to " Paragraph " & cPos
			
		end if
		
		if searchMethod is "S" then
			set theBL to sl
		else if searchMethod is "P" then
			set theBL to pl
		end if
		
		if linkName is "DF" then
			-- display full filename as name of link
			set theBLDisplay to dn & pldn
			
			
		else if linkName is "DA" then
			-- display aliases name as name of link
			set theBLDisplay to an & pldn
			
			
		else if linkName is "DC" then
			-- display content of a cmd as name of link
			set theBLDisplay to cn & pldn
			
			
		else if linkName is "DS" then
			-- display "Link" as  name of link
			set theBLDisplay to "" & pldn
			
			
			
		else if linkName is "DM" then
			set dldn to dn
			set {theID, theYear, theAuthor, theType} to my getCitationInfo(dldn)
			
			set theType to my firstN(1, theType)
			if theCitedText is not "" then
				set cl to sl -- use pl fot page/paragraph link, sl for search link
			else
				set cl to pl
			end if
			
			if theType is "O" then -- other source
				set cldn to dldn & ": " & pldn
			else if theType is "R" then -- source is literature 
				set cldn to " (" & theAuthor & ", " & theYear & ": " & (cPos) & " &nbsp;" & theID & ") "
			else if (theType is "A") or (theType is "C") then -- source is annotationNote or card
				set cldn to " (" & theAuthor & ", " & theYear & ": para " & (cPos) & " &nbsp;" & theID & "-" & theType & ")"
			end if
			
			set theBLDisplay to cldn
			set theBL to cl
			
			
		end if
		
		if linkType = "C" then
			if linkBeforeCitedText then
				set theFullLink to "> [" & theBLDisplay & "](" & theBL & ")" & return & return & ">" & theCitedText
				
			else
				set theFullLink to ">" & theCitedText & " [" & theBLDisplay & "](" & theBL & ")"
			end if
			
		else if linkType = "B" then
			set theFullLink to "*Bookmark:* [" & theBLDisplay & "](" & theBL & ")"
			
		else if linkType = "D" then
			set theFullLink to "[" & dn & "](" & dl & ")"
		end if
		
		set the clipboard to theFullLink
		
	end tell
	
end getLink

on strToList(thestr, d)
	local theList
	set {tid, text item delimiters} to {text item delimiters, d}
	set theList to every text item of thestr
	set text item delimiters to tid
	return theList
end strToList

on listToStr(theList, theDelimiter)
	set {tid, text item delimiters} to {text item delimiters, theDelimiter}
	set thestr to theList as text
	set text item delimiters to tid
	return thestr
end listToStr

on TrimText(theText, theTrim)
	set AppleScript's text item delimiters to the theTrim
	set the item_list to every text item of theText
	set AppleScript's text item delimiters to the ""
	set theText to the item_list as string
	set AppleScript's text item delimiters to ""
	return theText
end TrimText

on getDateString()
	set y to get year of (current date) as string
	set m to month of (current date) as integer
	set m to my PadNum(m, 2) as string
	set d to get day of (current date)
	set d to my PadNum(d, 2) as string
	set t to get time string of (current date) as string
	set t to my findAndReplaceInText(t, ":", ".") as string
	
	return y & "." & m & "." & d & "." & t
	
	
end getDateString

on findAndReplaceInText(theText, theSearchString, theReplacementString)
	set AppleScript's text item delimiters to theSearchString
	set theTextItems to every text item of theText
	set AppleScript's text item delimiters to theReplacementString
	set theText to theTextItems as string
	set AppleScript's text item delimiters to ""
	return theText
end findAndReplaceInText

on getNonBlankParagraphNum(theWin, theCurrentLine)
	local ap, nep -- all-paragraphs, non-empty-paragraphs
	tell application id "DNtp"
		set ap to every paragraph of the text of theWin
		set nep to {}
		repeat with i from 1 to (theCurrentLine + 1)
			if (item i of ap) is not "
" then
				set end of nep to item i of ap
			end if
		end repeat
		return count nep
	end tell
	
end getNonBlankParagraphNum

on PadNum(lngNum, lngDigits)
	
	set strNum to lngNum as string
	set lngGap to (lngDigits - (length of strNum))
	repeat while lngGap > 0
		set strNum to "0" & strNum
		set lngGap to lngGap - 1
	end repeat
	strNum
end PadNum

on min(x, y)
	if x ≤ y then
		return x
	else
		return y
	end if
end min


-- ignore these handlers
on getCitationInfo(theDocNm)
	local theNmlist, firstWord, thePos, lastWord, theType, theID, theYear, theAuthor
	
	set theNmlist to my strToList(theDocNm, " ")
	
	set thePos to my getItemPosInList("-", theNmlist)
	set firstWord to item 1 of theNmlist
	set lastWord to item -1 of theNmlist
	
	set theType to my getDocType(theDocNm)
	
	if theType is "O" then
		return {"", "", "", theType} -- no citation info
	else
		set theID to item 1 of theNmlist
		set theYear to item 2 of theNmlist
		if thePos is 0 then
			set theAuthor to item 3 of theNmlist
		else
			set theAuthor to items 3 thru thePos of theNmlist
			if the length of theAuthor ≤ 4 then
				set theAuthor to my listToStr(items 3 thru (thePos - 1) of theNmlist, " ")
			else
				set theAuthor to my listToStr((my TrimText((item 3 of theNmlist), ",") & " et al."), " ")
			end if
			
		end if
		return {theID, theYear, theAuthor, theType}
	end if
	
end getCitationInfo
on getDocType(theDocNm)
	local lnm
	set lnm to my strToList(theDocNm, " ")
	if my regexMatch(lnm's item -1, regexForCardUID) then
		return "C" --card
	else if lnm's item -1 contains "(annotation)" then
		return "A" -- annotation
	else if lnm's item 1 contains "." then
		return "R" --ref literature 
	else
		return "O" -- other ref
	end if
end getDocType
on getItemPosInList(theItem, theList)
	repeat with a from 1 to count of theList
		if item a of theList is theItem then return a
	end repeat
	return 0
end getItemPosInList
on regexMatch(s, regex)
	-- ignore case
	local ignoreCase, extraCommand
	set ignoreCase to true
	if ignoreCase then
		set extraCommand to "shopt -s nocasematch; "
	else
		set extraCommand to ""
	end if
	
	do shell script "export LANG='" & user locale of (system info) & ".UTF-8'; shopt -s compat31; " & extraCommand & "[[ " & quoted form of s & " =~ " & quoted form of regex & " ]] && printf '%s\\n' \"${BASH_REMATCH[@]}\" || printf ''"
	
	if result is not "" then
		return true
	else
		return false
	end if
	
end regexMatch
on firstN(n, s)
	return text from character 1 to character n of s
end firstN


1 Like