Help with a way (script?) to copy DT tags to first line of md file?

Hi all

im interested for the sake of compatibility and additional minor backup method to copy my devonthink tags for my many markdown files to the first line of the markdown file (based on the common syntax for tags) ie

tag: #tag1, #tag2

# note 1

anyone done something like this or has any idea how to achieve this?

thx a lot in advance!

Z

A simple script to insert the tags could look like this:

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		if type of theRecord is markdown then
			set theText to plain text of theRecord
			set theTags to ""
			set theTagList to tags of theRecord
			if (count of theTagList) is greater than 0 then
				repeat with theTag in theTagList
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & theTag
				end repeat
				set theText to "tag: " & theTags & return & return & theText
				set plain text of theRecord to theText
			end if
		end if
	end repeat
end tell

wow @cgrunenberg

This is fantastic! Cant thank you enough!

Small question (and please feel free to ignore this if its to much work), but can the script be adjusted to not execute if the tags: line exists?

the rationale is that i run this every week on files, and if the script has been run already on a .md file it adds another tags: line

thx again, ive only been using devonthink for a few months but you and @BLUEFROG have the best support any company i know of has…make using devonthink even more fun!

thx

Z

2 Likes

Replacing the line…

if (count of theTagList) is greater than 0 then

…with…

if (count of theTagList) is greater than 0 and theText does not begin with "tag:" then

…should be sufficient.

Thanks :slight_smile:

Perfect!!!

thx so much @cgrunenberg

Z

Hi again @cgrunenberg

hope all is well!

ive been using your script for a long time yet and its my #1 used script in Devonthink :slight_smile:

was wondering (as i have zero Applescript knowledge), if it would also be possible to add the current Devonthink rating as a tag while the script runs?

ie rating of ★★★ will be tag: #★★★ or tags:3 etc

thx a bunch again!

Z

This should work:

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		if type of theRecord is markdown then
			set theText to plain text of theRecord
			if theText does not start with "tag:" then
				set theTags to ""
				
				set theTagList to tags of theRecord
				repeat with theTag in theTagList
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & theTag
				end repeat
				
				set theRating to rating of theRecord
				if theRating is not 0 then
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & (theRating as string)
				end if
				
				if theTags is not "" then
					set theText to "tag: " & theTags & return & return & theText
					set plain text of theRecord to theText
				end if
			end if
		end if
	end repeat
end tell

hi again @cgrunenberg

hope all is well. the above script i have been using has seemed to stopped working for me…dunno why :slight_smile:

also i want to be able to “force” it to work on the files (ie delete the previous first tags: line and replace with new updated tags) and also add as tags the MD files label (in addition to the ratings and tags).

Any chance you can help me with adding this? i tried this:

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		if type of theRecord is markdown then
			set theText to plain text of theRecord
			if theText does not start with "tag:" then
				set theTags to ""
				
				set theTagList to tags of theRecord
				repeat with theTag in theTagList
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & theTag
				end repeat
				
				set theRating to rating of theRecord
				if theRating is not 0 then
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & (theRating as string) & "star"
				end if
				
				set theLabel to label of theRecord
				if theLabel is not 0 then
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & (theRating as string) & "star" & (theLabel as string)
				end if
				
				
				if theTags is not "" then
					set theText to "tag: " & theTags & return & return & theText
					set plain text of theRecord to theText
				end if
			end if
		end if
	end repeat
end tell

but it didn’t run at all (but as i said in general the script stopped working)

also not i tried changing the rating from #3 to #star since some applications like obsidian don’t like numeric tags :slight_smile:

any help would be great

thx so much as always!

Z

Is there anything in DT’s log?
And: Did you try running the script in the script editor? It is a lot more verbose than DT. In order to do so, copy & paste the script into a new script editor window, select a record in DT, open the message window (three lines at the bottom of script editor) and then click on the right pointing triangle in script editor. If an error occurs, it will be reported in the message window.

1 Like

thx @chrillek , should have though about the log!

I get this error when i launch the script on demand

17:26:40: foodQ-Add tags to topline 	on performSmartRule (Error -1708)

any clue?

The above script is not suitable for smart rules without some changes. How does your script look like?

Hi @cgrunenberg

i knew i messed up things badly :laughing:

well i based it on your script

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		if type of theRecord is markdown then
			set theText to plain text of theRecord
			if theText does not start with "tag:" then
				set theTags to ""
				
				set theTagList to tags of theRecord
				repeat with theTag in theTagList
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & theTag
				end repeat
				
				set theRating to rating of theRecord
				if theRating is not 0 then
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & (theRating as string)
				end if
				
				if theTags is not "" then
					set theText to "tag: " & theTags & return & return & theText
					set plain text of theRecord to theText
				end if
			end if
		end if
	end repeat
end tell

this is my modification

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		if type of theRecord is markdown then
			set theText to plain text of theRecord
			if theText does not start with "tag:" then
				set theTags to ""
				
				set theTagList to tags of theRecord
				repeat with theTag in theTagList
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & theTag
				end repeat
				
				set theRating to rating of theRecord
				if theRating is not 0 then
					if theTags is not "" then set theTags to theTags & ", "
					set theTags to theTags & "#" & (theRating as string) & "star"
				end if
				
				if theTags is not "" then
					set theText to "tag: " & theTags & return & return & theText
					set plain text of theRecord to theText
				end if
			end if
		end if
	end repeat
end tell

I wanted to change it so that:

  1. it always overrides the first tag line with the current state
  2. add more tags for `label
  3. add the text start after the #3 star tag

does that make any sense?

thx!

Z

That will not work. External scripts for smart rules need

on performSmartRule(records)

at the start. As is, btw, described in the documentation. You can’t run an ordinary script as external one from a smart rule!

thx @chrillek !

hmm im sure it did work at some stage :slight_smile: i followed he above script from @cgrunenberg and iirc it did run from the smart rule…but im pretty clueless with scripts so i wouldn’t bet my life on it :smiley: :smiley:

so how do you suggest to proceed, run this externally?

thx!

Z

Yes, you should run this from Script Editor with the Replies active so it will show what’s going on.

VIew > Show Log > Replies

It can never have worked like this from a smart rule. As a standalone script, why not.

You could just make a copy of a record for texting, select it and then run the script. Either from the menu after having it copied to a suitable location or from script editor.

Here’s a shortcut to delete the first line

set theText to do shell script "sed -e '1,1d' <<<" & quoted form of theText

Just a side note…

sed '1d'

should be sufficient to remove the first line.

1 Like

thx @DTLow and @BLUEFROG super useful!

yet on some files the first line dosent have the tags line but rather starts with the # HEADER line

is there a way to make sed not delete the first line but rather any line starting with tags: ?

thx so much

Z

I’m over extending my non-existent sed skills
You can try sed ‘/^tags:/d’

Here’s a sed resource
https://www.gnu.org/software/sed/manual/sed.html