1

Background

A Markdown document uses certain strings that are to be typeset in a special way. In this case, we'd like to typeset a.m. and p.m. as small caps wherever that text appears in the source document. That is:

11 a.m. → 11 AM
11 p.m. → 11 PM

ConTeXt LMTX, latest version.

Problem

Hooking into ConTeXt's text processing algorithm.

Code

The following snippet shows two parts. The first part represents the input source document. The second part shows how the text is meant to be replaced.

\starttext
  {\bf Markdown Input}

  Our grandmother clock rang 11 p.m. and we fled.

  Our grandmother clock rang 11 p.m., so we fled.

  Our grandmother clock rang 11 p.m. We fled.

  \blank[big]

  {\bf \ConTeXt{} Output}

  Our grandmother clock rang 11 \cap{pm} and we fled.

  Our grandmother clock rang 11 \cap{pm}, so we fled.

  Our grandmother clock rang 11 \cap{pm}. We fled.
\stoptext

English makes this a little bit more challenging than a straight substitution. For example:

At 11 p.m. Captain Cook cooked a crooked cook's cuke.

Let's not worry about that case.

Question

How do you perform a string replacement in ConTeXt without modifying the source document? Is there something like:

\definereplacement[SubstPostmeridian][
  match={[Pp].[Mm].]}
  replace={\cap{pm}}
]

\definereplacement[SubstMac][
  match={Mc(\W)}
  replace={M\sup{c}\1}
]

The second example would change "McGenius" into "MᶜGenius".

3
  • How are you inputting the markdown? Are you using an external converter like Pandoc, or are you using something from within ConTeXt like the markdown module? Aug 1, 2022 at 3:12
  • I'm using my editor, KeenWrite, which integrates and tweaks flexmark-java. The Markdown is converted to XML prior to typesetting. I seem to recall that ConTeXt has the ability to perform text substitution, but I've completely forgotten how to set it up. Aug 1, 2022 at 6:21
  • 1
    You're probably thinking of \replaceword, which unfortunately doesn't seem to work with the periods. Aug 1, 2022 at 9:20

1 Answer 1

4

You can use the translate module:

\startbuffer
  Our grandmother clock rang 11 p.m. and we fled.

  Our grandmother clock rang 11 p.m., so we fled.

  Our grandmother clock rang 11 p.m. We fled.
\stopbuffer

\usemodule[translate]

\translateinput[ a.m.][ \cap{AM}]
\translateinput[ p.m.][ \cap{PM}]

\starttext
\getbuffer

\enableinputtranslation

\getbuffer

\disableinputtranslation

\getbuffer
\stoptext
4
  • Unfortunately, this produces the grammatically incorrect phrase of: "Our grandmother clock rang 11 PM We fled." The period after PM is missing. I think regexes and backreferences are needed. Aug 1, 2022 at 19:08
  • Your regrex will produce the same output, right?
    – Aditya
    Aug 1, 2022 at 20:46
  • That particular example, yes. With regex, we could apply two different match conditions match={[Pp].[Mm]. ([^:upper:])}, and match={[Pp].[Mm]. ([:upper:])}, along with slightly different replacement patterns to solve the problem. Aug 1, 2022 at 20:48
  • 2
    You can look into the code of m-translate.mkiv. It hooks into textlineactions to do the replacement one by one. It should be possible to write a standalone lpeg based expression to do the translation that you want.
    – Aditya
    Aug 1, 2022 at 21:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .