So I went and created the $CHAR wrapper utility function and got it to work; It wasn't *quite* as simple as I thought it would be (couldn't simply pass the whole string parameter through to $C, and need to remember to pass the param as a single quoted string) so I thought I would share in case someone else wanted to go this route :)

As before, review the instructions for Defining Custom Utility Functions and ensure the class extends Ens.Rule.FunctionSet

/// Wrapper to built-in objectscript function $CHAR.
/// Intended use = linebreaks ($C(13,10)) in routing rules (trace) where CRLF not easily accessible.
ClassMethod Char(pCharString As %String) As %String
{
    #dim outString,thisChar As %String = ""
    #dim numChars As %Integer
    s numChars = $L(pCharString, ",")
    //q:(numChars<2) $C(pCharString)
    if (numChars<2){ s outString = $C(pCharString) }
    // more than one char, iterate over them to call $C and build outString
    else{
        for n=1:1:numChars {
            s thisCharCode = $P(pCharString, ",", n)
            s outString = outString_$C(thisCharCode)
        }
    }
    q outString
}

I originally had the post-conditional quit for the single-char cases, but felt assigning and using outString was slightly better since it was more consistent coding. Though I wonder if the post-conditional is slightly more efficient... (very outside of my wheelhouse)

Then make sure to pass a single quoted string in the Routing Rule, but otherwise it's just like calling $C:

In my experience, most/all $ objectscript functions ($CHAR, $PIECE, etc) are not available for use in a Routing Rule.  Some of them ($PIECE for example) have "built-in" workarounds in the defined Utility Functions - so in the rule, you can just do "Piece(foo,bar,x,y)" just like you would normally use elsewhere, sans $.

My use case for wanting a linebreak available in a Routing Rule is slightly different from @Erin Dolson 's
(I wanted to output some slightly neater Trace messages) but I think what I did below would work for that + other use cases as well.

Just for fun / to prove it is possible, I created a workaround that will retrieve a $C(13,10), by using a custom utility function:

1. In a class that was already extending Ens.Rule.Functionset, I defined a new classmethod:

/// Get linebreak chars (Carriage Return, Line Feed; ASCII 13, 10). Intended for use in routing rules (trace) where CRLF is not easily accessible.
ClassMethod CRLF() As %String
{
 q $C(13,10)
}

2. In my Routing Rule, I call the function in a Trace (or Assign) action's Value node like any other:

and the trace itself looks like:

[You could easily modify the new utility function to pass back any other char - or really, the best solution IMHO (which I will probably end up implementing in my environment) would just be to create the full wrapper to $CHAR itself via a passed parameter and call it "CHAR"]

FYI / N.B.: I'm on HealthShare (Ensemble) Health Connect 2018.1 but I'm fairly sure this should work for at least as far back as 2016 if not earlier since custom utility functions have been supported for quite some time.

Has anyone ever converted an HL7-embedded Base64-encoded PDF TO (HL7-embedded) RTF?

This looks great, but i noticed the linked LibreOffice conversion table seems to indicate PDF can only be exported (conversion target), not imported (conversion source)

Honestly interested in PDF of any kind; "converting" B64 PDF to a flatfile *.pdf is trivial, but it looks like using *.pdf as a source is not supported for LibreOffice method?

FWIW: Ensemble v2016.2 on Windows

I find myself agreeing with Mike W on this one in being generally in favor of (some) abbreviations, though I can certainly understand the "fully written out = easier to read (and thus maintain) code" argument.

I should also add: I have found I apply abbreviations inconsistently (Much to my internal engineer's chagrin)

s/set is an easy one and as mentioned, quickly becomes comfortable. I also tend to use d/do.

However, for control-flow items (for/if/while) i find myself always writing these out.  After reading John's subcomment above, I wonder if indeed this could be related to the larger "semantic gap" that develops in (for example) parsing "f" vs "for" / "i" vs "if" -  it is harder for NLP english brain to quickly internalize the true meaning.

One additional point touched on: preserving spacing. Abbreviations won't usually save vertical space, but I would contend that sometimes horizontal space (which they do save)  is a premium as well. Lines running offscreen can be annoyance at best, but at worst can cause a programmer to misparse or even completely miss sections of code. For this reason, I will usually try to break long lines (ie, a long concatted string) over multiple lines with an indented "_". Abbreviating saves hspace as well - albeit moreso $ objs functions than commands.

Speaking of which... Wasn't asked by OP, but similarly for objs functions: I will almost always use $P over $Piece, $S over $Select (but not $C for $CASE wink ).  I can understand rationale for spelling these out but as these (especially some $S) expressions can get complex, I find abbreviating the func itself helps keep focus on the expression logic itself. Sometimes an extra space between parens can go a long way towards maximizing this clarity. Oh, and $ZDT >> $ZDATETIME any day :) Similarly, would anyone actually ever write $HOROLOG over $H ?

In a similar, related vein of "cautionary M tales" - found this lovely gem crawling some forums last year (from a much older post from the days where the Cache tech stack was perhaps a bit less mature) :

"The following is a valid line of MUMPS code:

A       B:C  D E F G=H:I:J K:L M N O,P Q:R  S T=UVW X YZ

It means "Line is labelled A.  Breakpoint if C is true.  Do the E subroutine.  For G=H to J, incrementing by I. If L is true, kill (unset) the M variable.  Create new variables O and P.  If R is true, quit.  Set the T variable = the UVW variable.  Execute the contents of the YZ variable as if it contains valid MUMPS code." I remember showing some code to a college friend when I'd been working with it for a few months, and he asked why my printer was spewing line noise."

From <https://what.thedailywtf.com/topic/508/intersystems-cach-233-gateway-to-hell/21>