Plugin actions: KMPARAMs and UTF-8 international glyphs

Keyboard Maestro's documentation on Plug In Actions notes that parameters can be retrieved either as

  • bash variables: echo "$KMPARAM_Option_Name", or
  • osascript systemAttributes()

The latter simplifies dealing with multi-line option arguments, but, to quote the docs:

is not safe for international characters

I have, for the moment, used the .systemAttributes() approach for a set of simple percent-encoding and decoding actions, but as predicted, letters beyond the Anglo-Saxon ken get mangled in the encode ⇄ decode wash.

Experimenting now with handling multiline option arguments through bash variables, I am still failing to protect diacritics and non-Roman glyphs with attempts like:

#!/bin/bash
LANGSTATE="$(defaults read -g AppleLocale).UTF-8"
if [[ "$LC_CTYPE" != *"UTF-8"* ]]; then export LC_ALL="$LANGSTATE" ; fi

txtIN=$(printf "%q" "$KMPARAM_Text_to_encode")

osascript -l JavaScript <<JXA_END 2>/dev/null
(function (strQuoted) {
    var a = Application.currentApplication(),
	    sa = (a.includeStandardAdditions = true, a),
        strText = (strQuoted.substr(0, 2) === "$'") ?
        strQuoted.substr(2, strQuoted.length - 3) : strQuoted;
    
    return encodeURIComponent(
        strText || ''
    );
})("$txtIN");
JXA_END

( Where the first two lines are an attempt to ensure UTF8 processing, and the printf quoting is to allow for a string argument which may contain \n or \r line endings )

Any thoughts about how I might rework this to yield ßèτא handling of 汉子 and so forth in KMPARAMS ?

( Apologies there for the reckless misuse of German and Greek etc characters )

For refce, the .systemAttribute() version, which works fine within its Anglo-Saxon limits, is:

#!/bin/bash
osascript -l JavaScript <<JXA_END 2>/dev/null
(function () {
    var a = Application.currentApplication(),
	    sa = (a.includeStandardAdditions = true, a); 

    return encodeURIComponent(
        sa.systemAttribute('KMPARAM_Text_to_encode')
    );
})();
JXA_END

Link to plugin

FWIW, a purely JavaScript version, outside the Bash context, works fine:

var strHan = "汉子",
	strCode = encodeURIComponent(strHan),
	strDecode = decodeURIComponent(strCode);
	
[strCode, strDecode]
["%E6%B1%89%E5%AD%90", "汉子"]
1 Like