Copy/paste from scribble/acmart @sigplan into DrRacket?

This should be a short example document that produces the problem:

#lang scribble/acmart @sigplan @screen

@(require scriblib/figure
          (only-in scribble/manual racketmod0))

@title{Title}

@section{Section}

@figure["easy-counter.rkt"
        "A counter GUI using GUI Easy's functional widgets."
        @racketmod0[
        racket/gui/easy
        (define |@|count (|@| 0))
        (render
         (window
          #:title "Counter"
          (hpanel
           (button "-" (λ () (<~ |@|count sub1)))
           (text (~> |@|count number->string))
           (button "+" (λ () (<~ |@|count add1))))))]]

Make a PDF with

raco scribble --pdf example.scrbl

Assuming you have GUI Easy installed (raco pkg install gui-easy), you might want to copy-paste the codeblock into DrRacket and run the example.

Punchline: you can't. The font has somehow transformed the ~, among other characters (including the lambda). DrRacket is able to reacquire the lambda, but not the ~ characters. Here's a hex dump of what I get:

00000000: 236c 616e 6720 7261 636b 6574 2f67 7569  #lang racket/gui
00000010: 2f65 6173 790a 2864 6566 696e 6520 4063  /easy.(define @c
00000020: 6f75 6e74 2028 4020 3029 290a 2872 656e  ount (@ 0)).(ren
00000030: 6465 720a 2028 7769 6e64 6f77 0a20 2023  der. (window.  #
00000040: 3a74 6974 6c65 2022 436f 756e 7465 7222  :title "Counter"
00000050: 0a20 2028 6870 616e 656c 0a28 6275 7474  .  (hpanel.(butt
00000060: 6f6e 2022 2d22 2028 f09d 9c86 2028 2920  on "-" (.... () 
00000070: 283c e288 bc20 4063 6f75 6e74 2073 7562  (<... @count sub
00000080: 3129 2929 2028 7465 7874 2028 e288 bc3e  1))) (text (...>
00000090: 2040 636f 756e 7420 6e75 6d62 6572 2d3e   @count number->
000000a0: 7374 7269 6e67 2929 2028 6275 7474 6f6e  string)) (button
000000b0: 2022 2b22 2028 f09d 9c86 2028 2920 283c   "+" (.... () (<
000000c0: e288 bc20 4063 6f75 6e74 2061 6464 3129  ... @count add1)
000000d0: 2929 2929 29                             )))))

The lambda became the sequence f0 9d 9c 86 and the ~ became e2 88 bc.


Does anyone know how I can configure Scribble (either via font or some other "really I mean it" mechanism) to produce copy-and-runnable code?

I suspect using racketmod0 from scribble/manual may be part of my issue, but I've gone through several different mechanisms to try to get good Racket figures in the PDF and this is what I've settled on for #lang-based figures.

Maybe related?

https://www.reddit.com/r/LaTeX/comments/t8ly61/unable_to_copy_words_with_f_or_similar_letters/

Thanks, that encouraged me to look at the LaTeX source; I see

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

at the top.

I also see that <~ has been converted to \RktSym{{\Stttextless}$\sim$} in the LaTeX source; I'm certain that's part of the problem. I really want to just use a ~ character. (The conversion of < to {\Stttextless} doesn't seem to be a bother.)

Here is the special case for ~:

Another piece to the puzzle.

From: What is the best way to produce a tilde in LaTeX for a website? - Stack Overflow

1 Like

Some intreprid digging which included copying and modifying scribble/run.rkt to add my own mixin wrappers around render-content and render-other to display certain inputs reveals the following chain (even when using #,(make-element symbol-color "<~")):

  1. Eventually we get to the element that includes the <~; this is handed to the latex-renderer's render-content.
  2. After some pre-processing, it calls (super render-content …) with the same element. Assuming that's base-renderer, the method calls (render-content (element-content i) …), which is (render-content "<~" …).
  3. This repeats latex-renderer's pre-processing and (super render-content "<~" …).
  4. Now, base-renderer calls (render-other "<~" …) because it has a string.

As pointed out, render-other in the LaTeX renderer cooperates with display-protected to turn ~ into $\sim$.


So, I think what I need is a way to bypass this and insert some other LaTeX command to generate a real tilde.

So, I think what I need is a way to bypass this and insert some other LaTeX command to generate a real tilde.

Inserting a real tilde is just what the Stackoverflow thread was about:

Since tilde is a special character in LaTeX, they needed some trickery (using catcode) to produce a real tilde. They needed it in order to copy/paste urls containing tilde. But the same trick ought to work in your context.

But the same trick ought to work in your context.

Yes, though I need to figure out / remind myself how to insert
arbitrary LaTeX in the document at the right places, hopefully without
making it too hard to type the code examples.

Aha! The following allowed me to use #,<~ and #,~> to get what I want, thanks to \textasciitilde{} producing something reasonable that also works with copy/paste:

#lang scribble/acmart @sigplan @screen

@(require scriblib/figure
          scribble/core
          (only-in scribble/manual racketmod0)
          (only-in scribble/racket symbol-color))

@(define ~ (make-element "textasciitilde" ""))
@(define <~ (make-element symbol-color (list "<" ~)))
@(define ~> (make-element symbol-color (list ~ ">")))

@title{Title}

@section{Section}

@figure["easy-counter.rkt"
        "A counter GUI using GUI Easy's functional widgets."
        @racketmod0[
        racket/gui/easy
        (define |@|count (|@| 0))
        (render
         (window
          #:title "Counter"
          (hpanel
           (button "-" (λ () (#,<~ |@|count sub1)))
           (text (#,~> |@|count number->string))
           (button "+" (λ () (#,<~ |@|count add1))))))]]

How? The (make-element "textasciitilde" "") will be converted to \textasciitilde{} by the LaTeX renderer; then we just wrap it with < or > in the right position, and colored by the symbol-color style (which is what racketidfont uses, IIRC; I spent so much tme staring at scribble source I don't remember exactly how I found that style).

In Vim, the command :v/make-element/s/\v(#,)@<!(\<\~|\~\>)/#,&/ge will replace all non-unsyntaxed occurrences of the two arrows with unsyntaxed versions (at least, the ones not on lines containing make-element, which suffices in my case).

2 Likes

You cracked it!

But does \textasciitilde produce the right tilde?

Reading the last answer too, I see that \textasciitilde ought to work.
Except for computer modern - which of course was used by the OP.

\textasciitilde

it's painful but you can wrap text to keep it exactly:

I think changing \sym to \textasciitilde is probably a good idea. We might also want to do something so that computer modern isn't the default tt font too? I thought that acmart doesn't use computer modern, tho?

The StackOverflow post was from 2010 - so perhaps the bug has been fixed in the mean time?

See Why is `~` converted to `$\sim$` by the LaTeX renderer? · Issue #370 · racket/scribble · GitHub which I filed as a result.

According to https://github.com/racket/scribble/blob/97d5b34742b12346da2e48c979cf1979232f0712/scribble-lib/scribble/acmart/acmart.cls#L818-L850 the acmart class tries very hard to use Libertine for text and math fonts and to use Incosolata for typewriter fonts.

1 Like