Keyboard shortcuts for bold and italics both in Rich Text and Markdown

Subtitle: “Confession of a failure”

I’m not very experienced in Apple Script, but make up for it a little bit with stubbornness. At least that’s what I thought.

Thing is, I’m jumping between notes in RTF and in Markdown back and forth. RTF is simpler to write in, as long as the notes are simple. But because Apple forgot to implement footnotes I use Markdown for notes with footnotes. The whole situation is not very satisfying.

And it doesn’t get any better as DEVONthink actually has no Markdown Editor (I haven’t checked Prism yet I must add) but a plain text editor combined with a Markdown viewer.

What I’m sorely missing is keyboard shortcuts for basic formatting like italic and bold.

So I came up with an idea that turned out to be significantly less clever than I thought:

I set the keyboard shortcuts for italics to the unusual command-shift-i and for bold to command-shift-b. And then I set command-i to my emphasize script and command-b to my strong script. Like this:

-- Activate italics both in rich text and in markdown

tell application id "DNtp"
	try
		if not (exists think window 1) then error "No window is open."
		
		set theSelection to the selection
		
		repeat with theRecord in theSelection
			try
				set theType to type of theRecord
				
				if ((theType is not rtf) and (theType is not rtfd)) then
					
					tell application "System Events"
						keystroke "*"
						-- Replace if you prefer a pair of asteriks and the cursor in between:
						-- keystroke "**"
						-- keystroke (key code 123)
					end tell
					
				else
					
					tell application "System Events" to keystroke "i" using {command down, shift down}
					
				end if
			end try
			
		end repeat
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

And guess what—it’s lagging like mad. Sometimes so much it doesn’t even work. Shortcuts working not reliably are even worse than no shortcuts.

So where lies the mistake? Is it because I frankensteined my script together from parts of dead bodies like usual? Or is the whole approach mislead?

U may want to take a look at this Script: universal formatting shortcuts for markdown and rtf

Thank you, I will look into it.

It’s strange the search I actually did before I started fiddling around with the shortcuts didn’t bring up your thread.

My apology, the script is overly complicated. This is the simplest version:

tell application id "DNtp"
	set theWin to think window 1
	set theDoc to content record of think window 1
	if type of theDoc is in {rtf, rtfd} then
		italicize selected text of theWin
		-- for bold, use  
        --bold selected text of think window 1
	else if type of theDoc is markdown then
		set {bTag, eTag} to {"*", "*"}
		-- for bold, use 
        -- set {bTag, eTag} to {"**", "**"}
		set selected text of theWin to bTag & selected text of theWin & eTag
	end if
end tell

Thank you again for the new script. So this is the right way to go, no more keystrokes executing other keystrokes nonsense! And no more lagging, of course.

But the script is not yet providing everything impudent me would like to have.

  1. On the RTF side:
    a) The script works with selected text but only in one direction: It italicizes but does not de-italicize when the text is italicized already. And it only works with selected text. While writing executing the script does nothing. Is it possible to rebuild the exact same behaviour as cmd-i would normally have?
    b) It could be I want to insert characters. Does it work the same as with plain text/Markdown or would that break rich text?

  2. On the Markdown side:
    a) Same as with RTF. The script works with selected text but only with selected text. Is it possible to move the cursor in between bTag and eTag if no text is selected?
    b) And here comes the tricky part: I’d like to have a universal toggler. Cmd-i for example toggles (in rich text and in good Markdown editors; there aren’t that many in that respect). If I have to move out of the markup by hitting the right arrow that’s not toggling.
    That’s why I went for not adding both bTag and eTag (to keep your naming) but just a single asterisk. Because when bTag and eTag are the same that’s like toggling. (In the ongoing writing, selected text is another thing.)
    But what if bTag and eTag are not the same? Like in MMD inline footnotes: [^ and ]—a really, really bad idea, by the way, to use a single square bracket as the ending markup of a footnote. What is the right approach to that? And that is a question of the logic behind it first and only then the coding.
    In 1Writer I use a (java)script from Drafts I adapted for 1Writer. It is made for every kind of pairs, like brackets or quotation marks.

                     // Smart parentheses key
                     //
                     // If a selection is present, wrap the text in parentheses
                     //
                     // If no selection, scan text for last parenthesis and
                     // close it if last one was an open parenthesis, or
                     // insert open parenthesis if not.
                     var open = "[^";
                     var close = "]";
                     var range = editor.getSelectedRange();
                     var priorText = editor.getSelectedText();
                     var allText = editor.getTextInRange(0, range[1])
                     if (range[1] > range[0]) { 
                      //text selected, wrap it!
                     var newText = (open + priorText + close);
                     }
                     else {
                      // no selection, find last 
                      var lastOpen = allText.lastIndexOf(open);
                      var lastClose = allText.lastIndexOf(close);
                      if	(lastOpen == -1 || lastClose > lastOpen) { // no close, use open
                      var newText = open;
                      }
                      else { // close last open
                      var newText = close;
                      }
                     }
                     editor.replaceSelection(newText)
    

For brackets etc. it works fine. But with MMD inline footnotes not if the footnotes contain square brackets used as actual square brackets and not as markup (most MMD editors can’t handle them either).
The point is: When a script inserts either the bTag or the eTag, how does it know which one to take? This script looks to the left of the cursor position for a closing square bracket and if there is one it inserts the bTag. Wrong, if it is just a square bracket.
If one goes this route the script would have to look for the last bTag. If there wasn’t any, insert bTag. If there is one count the opening and closing square brackets between the last bTag and the cursor position. If they are even, insert eTag. If there is one closing square bracket more than opening ones insert bTag. Imagine being at the end of a long text with a footnote at the beginning. Counting might take a while.
So I wonder if your approach of inserting both bTag and eTag is the better way. If it worked without selection, the cursor must be put in between them. The script must at first look to the (length of eTag) characters to the right of the cursor position. If they exist and if they contain the eTag, the cursor must move (length of eTag) to the right. That would be toggling.

How is pressing a hotkey for a script faster than pressing Shift-8 ? :slight_smile:

Because the muscle memory stored italics under cmd-i and so forth. This is especially important when you jump between formats like me.

Most markdown editors offer keyboard shortcuts for emphasize and strong.

Development would have to assess this.

If this was built in of course that would be better than a script! But until then maybe a script will do.

In all seriousness, this would be a game changer for taking Markdown notes in DEVONthink. A MultiMarkdown version of Typora like editor would be even better. Or one like the flabbergastingly expensive Paper but with more functions.

A MultiMarkdown version of Typora like editor would be even better.

Typora is a hybrid editor, showing both the control characters and the rendered text. There are no current plans to develop a similar editor in DEVONthink.

Most Markdown editors are. They offer something they sometimes call “Inline Highlighting”. Like real italics in between asterisks. Greyed out markup. Or a colourful variant like in Ulysses.

They are actually rich text editors but saving plain text files. What I never understand is why then showing the markup in the first place? Saving in a format that any writing app can handle is great but why bother the writer with markup? In writing apps not made for Markdown that’s totally okay of course.

In regards of developing a Markdown editor for DEVONthink: How about licencing a Markdown “engine”?

A few months ago, before I learned about the very promising Typora, I almost had suggested to you to license Paper’s engine. I would have added while it offers the smoothest way of writing in Markdown without seeing Markdown I had ever encountered (and still have) it a) has very little functionality and b) costs about 25% of DEVONthink Pro.

That was then. Now the price is HALF of DEVONthink Pro’s. For a beautiful almost nothing. I don’t want to imagine what licencing would cost.

If you are still interesting in testing it, here’s a link—because Paper(s) is not a very distinctive name for an app.

Should you run the test version make sure to use the option key while browsing through the menus. The Paper programmer moved the distraction free fad to another level by hiding lots of menu items.

In regards of developing a Markdown editor for DEVONthink : How about licencing a Markdown “engine”?

That would be a decision far beyond my pay grade. :slight_smile:

Most Markdown editors are.

I have more than one that are not.
And speaking from my own experience, writing long-form Markdown daily in DEVONthink, I personally don’t like the hybrids (and yes, I’ve tried almost all of them). I am so used to typing markdown, I often find myself doing it in places it’s not supported.

PS: Holy $100!!! I was expecting $39 tops. Wow. :flushed:

Then we probably have a misunderstanding what “hybrid” means. I refer to all Markdown editors that display more than just plain text, like italics and bold, colors, etc. And that is something a lot offer.

But back to the topic: Is it possible to alter ngan’s script so the cursor is moved—without using System Events—and the text before and after the cursor positios gets retrieved?