Printing Tags and Annotations

Apologies if this is covered somewhere. I’ve checked all of my reference material to the best of my ability.

I have a series of Markdown notes that I print to either 8.5x11 paper or 4x6 index cards.

Is there a way to print the tags for each note at the bottom of the page or card?

Thanks in advance for any suggestions.

Welcome @paulcraig

You print directly to 4x6?

I do! It’s a custom size paper in MacOS.

What printer are you using? Just curious.

PS: Here’s an approach that appends Tags: and the document’s tags as the last line in Markdown, plain text, and rich text documents.…

property validTypes : {"markdown", "txt", "RTF", "RTFD"}

tell application id "DNtp"
	repeat with theRecord in (selected records)
		set od to AppleScript's text item delimiters -- Cache delimiters for resetting
		
		tell theRecord
			set recordType to (type as string)
			if recordType is not in validTypes then -- Only process valid file types
				return
			else if recordType is not in {"RTF", "RTFD"} then -- Get the plain test if the file isn't a rich text format
				set isRichText to false
				set currentText to plain text
			else -- Deal with the text of rich text files 
				set currentText to (text of theRecord)
				set isRichText to true
			end if
			set recordTags to tags -- Get the record's tags
			
			if (paragraph -1 of currentText) does not start with "Tags:" then -- Is the last line a list of tags?
				set AppleScript's text item delimiters to ", " -- Separate them with commas
				set recordTags to (recordTags as string) -- And coerce them into a string 
				set AppleScript's text item delimiters to od -- Reset the delimiters to default
				
				if isRichText then -- Add paragraph to text of rich text directly
					tell text of it
						set tagLine to (make paragraph at end with properties {text:linefeed & "Tags: " & recordTags, font:font})
						
					end tell
				else -- Concatenate the text of plain text formats with new lines
					set plain text to (plain text & linefeed & linefeed & "Tags: " & recordTags)
				end if
			end if
		end tell
	end repeat
end tell

Thank you for this!

I have a Brother HL-L2370DW. It will print 4x6 index cards from the paper tray. There is a limitation on thickness. I use a brand I buy at Dollar Tree called Jot. Currently $1.25 per pack of 100.

Pardon me for my ignorance. What exactly do I do with the code you posted?

Interesting and thanks for the heads-up on the printer.

  1. Open /Applications/Utilities/Script Editor.app.
  2. Paste the code.
  3. Select Script > Compile to ensure it’s compiling properly.
  4. Select File > Save.
  5. In the Save dialog, press Command-Shift-G and paste ~/Library/Application Scripts/com.devon-technologies.think3/Menu. You can save into that directory or a subfolder of your choice.
  6. Give the script your desired name and save it. The script should now be available in the Scripts menu in DEVONthink.

Thank you so much for your expertise! I appreciate everything you do for us DEVONthink users.

I’ve followed the directions. It’s in the correct folder and appears in the scripts menu. When I run it in the Script Editor, it works. When selected in the script menu in DEVONthink, it doesn’t. If that’s the way it needs to work, that’s awesome. If not, additional guidance is deeply appreciated.

Again, thank you.

An alternative to @BLUEFROG’s approach might be a script that appends something like
<div class=!tag-line">...your tags ...</div>
to the MD file and then use CSS and a @media selector to position the tags:

.tag-line {
  bottom: 1em; /* or something like that, some experimenting might be in order
}

supposing that you’re not going to print the raw Markdown, of course. More on CSS here

2 Likes

I like the idea of a script, and the CSS for positioning
My suggestion is using a temporary file instead of updating the original,
and the addition of a Print command

Change the first property line to this…

property validTypes : {"markdown", "«constant ****mkdn»", "txt", "«constant ****txt »", "RTF", "«constant ****rtf »", "RTFD", "«constant ****rtfd»"}

I need to look at this code again but it should work fine for Markdown.

Done. We’re much closer. On recompile, receiving this error:

DT Script Error

Again… thank you!

All the constants shouldn’t be necessary anymore actually.

I didn’t think so either but the script isn’t picking up the human-readable version when run from the Script menu.

If I don’t include the constants, it fails this conditional and returns…

if recordType is not in validTypes then -- Only process valid file types
				return

It runs in Script Editor as expected, but fails in DEVONthink’s Script menu.

No problem.
I copied and pasted that line into an emoty script and it compiled without incident.

Please post a screen capture of the Script Editor showing the error.

For all document types? Which version of macOS?

Ah… the joys of AppleScript. Initially I got some constants too but only initially. Then running the test script again and again for all kinds of types worked as expected. Sigh.

Anyway, converting types to strings is rarely necessary and usually not recommended. This version works fine, at least for me :slight_smile:

tell application id "DNtp"
	set od to AppleScript's text item delimiters -- Cache delimiters for resetting
	set AppleScript's text item delimiters to ", " -- Separate them with commas
	repeat with theRecord in (selected records)
		tell theRecord
			set isRichText to false
			set isPlainText to false
			
			set recordType to type
			if recordType is markdown or recordType is txt then -- Get the plain test if the file isn't a rich text format
				set isPlainText to true
				set currentText to plain text
			else if recordType is rtf or recordType is rtfd then -- Deal with the text of rich text files 
				set currentText to (text of theRecord)
				set isRichText to true
			end if
			
			if isRichText or isPlainText then
				if (paragraph -1 of currentText) does not start with "Tags:" then -- Is the last line a list of tags?
					set recordTags to tags -- Get the record's tags
					set recordTags to (recordTags as string) -- And coerce them into a string 
					
					if isRichText then -- Add paragraph to text of rich text directly
						tell text of it
							try -- Might fail in case of empty rich text as the current font can't be retrieved
								set tagLine to (make paragraph at end with properties {text:linefeed & "Tags: " & recordTags, font:font})
							end try
						end tell
					else -- Concatenate the text of plain text formats with new lines
						set plain text to (plain text & linefeed & linefeed & "Tags: " & recordTags)
					end if
				end if
			end if
		end tell
	end repeat
	set AppleScript's text item delimiters to od -- Reset the delimiters to default
end tell

If this script is incidentally run twice it will add the tags twice.

My take on it (lazy, only working for MD documents).

(() => {
  const styleSheet = `<style media="print">
		body {
		  width: 4in;
		  height: 6in;
		  position: relative;
		}
		.tags-list {
		   border: 1px solid black;
           position: absolute;
           bottom: 0.2in;
           padding: 0.5em;
           left: 0;
           right: 0;
           margin: 0 auto;
           width: max-content;
		}
		</style>`;
		
  const app = Application("DEVONthink 3");
  app.selectedRecords().forEach(rec => {
    if (rec.type() === "markdown") {
	  const tags = rec.tags().join(', ');
	  txt = rec.plainText() 
	    + `<p class=tags-list>${tags}</p>\n`
		+ styleSheet;
	  const newRec = app.createRecordWith({name: `${rec.name()}-COPY`,type: "markdown"}, {in: rec.locationGroup()});
	  newRec.plainText = txt;
	}
  })
})()

The script (JavaScript!) loops over all selected records, considering only those that are MD documents. For them, it creates a copy (original name-COPY) appending the tags as a comma-separated list and a style sheet defined at the top of the script. It is only used for printing (media="print") and sets the size of the body element to 4 by 6 inch. It puts the comma-separated tag-list at the bottom of the body, centered and surrounded with a small black border. The style sheet can, of course, be modified in any way.

Note Setting the size on the body element does not set the paper size. Currently, Safari/Webkit does not permit this (well, it’s only a standard, why should Apple care).

Obvious amendments: Have the script convert the MD document with the tags to PDF and remove the former. One could even try to print the PDF directly, using the terminal command lpr, possibly specifying paper size. Also, as it stands, annotations are not considered.

Not so obvious amendment: Add a style for non-print media that hides the tags, forego the copy of the MD document and simply modify the original. In that case, one should check, if it already contains the tags, remove them (might be outdated) and add the current set of tags anew.

Actually it doesn’t due to this line:

if (paragraph -1 of currentText) does not start with "Tags:" then -- Is the last line a list of tags?
2 Likes

Sorry, I overlooked that