3

Is it possible to create a squiggly underline? Like this, but wavy:

\setupwhitespace[big]

\starttext
\underbar{\samplefile{knuth}}
\stoptext
  • If ConTeXt can use the ulem package, it defines the \uwave{something} command. – Bernard Dec 22 '18 at 21:55
  • @TeXnician link? – user19087 Dec 22 '18 at 23:01
  • @TeXnician I don't think \definehighlight is the right mechanism. I would suggest undergraphic instead (see my answer). – Henri Menke Dec 22 '18 at 23:44
  • @HenriMenke Much better. I'm still learning about all these options as well ;) – TeXnician Dec 23 '18 at 8:27
4

You can easily define your own undergraphic with a sine wave in MetaFun.

\setupwhitespace[big]

\startuseMPgraphic{rules:under:wave}
    draw function(2, "x", "sin(2*(x mod (2*pi)))", 0, RuleWidth, 1pt)
        shifted (0,RuleFactor*RuleOffset+RuleDepth)
        withpen pencircle scaled RuleThickness
        withcolor RuleColor ;
    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
\stopuseMPgraphic

\definebar
  [underwave]
  [undergraphic]
  [mp=rules:under:wave]

\definebar
  [underwaves]
  [underwave]
  [continue=yes]

\starttext
\underwaves{\samplefile{knuth}}
\stoptext

enter image description here


A method to avoid overflow could be to use hand-drawn waves. It looks a bit awkward right now. There is definitely room for improvement.

\setupwhitespace[big]

\startuseMPgraphic{rules:under:wave}
  numeric n ; n := 2 ;
  path p ;
  p := (0,RuleDepth) for i=0 step n until RuleWidth:
      .. (i,RuleDepth) .. (i+1*n/4,RuleDepth+1pt) .. (i+2*n/4,RuleDepth) .. (i+3*n/4,RuleDepth-1pt)
  endfor ;
  draw p shifted (0,RuleFactor*RuleOffset)
        withpen pencircle scaled RuleThickness
        withcolor RuleColor ;
    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
\stopuseMPgraphic

\definebar
  [underwave]
  [undergraphic]
  [mp=rules:under:wave]

\definebar
  [underwaves]
  [underwave]
  [continue=yes]

\starttext
\underwaves{\samplefile{knuth}}
\stoptext

enter image description here


Another option to avoid overflow is to compute the sine in Lua.

\setupwhitespace[big]

\startuseMPgraphic{rules:under:wave}
    vardef lsin primary x =
        lua("mp.print(math.sin(" & decimal x & "))")
    enddef ;
    draw function(1, "x", "lsin(2*x)", 0, RuleWidth, .2pt)
        shifted (0,RuleFactor*RuleOffset+RuleDepth)
        withpen pencircle scaled RuleThickness
        withcolor RuleColor ;
    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
\stopuseMPgraphic

\definebar
  [underwave]
  [undergraphic]
  [mp=rules:under:wave]

\definebar
  [underwaves]
  [underwave]
  [continue=yes]

\starttext
\underwaves{\samplefile{knuth}}
\stoptext

enter image description here

  • I didn't think it'd be so easy. Appreciate for the link to undergraphic. There's also the Rules PDF (just found it), and of course MetaFun. Quick question: how do I squish the squiggles together? Scaling the first x (x/2) or using xyscaled (0.5,1) truncates the graphic to half the line length, and scaling the second x (sin(x*2)) causes an out-of-bounds metapost error. – user19087 Dec 23 '18 at 2:06
  • @user19087 You have to use some arithmetic tricks to avoid overflows. See updated answer. – Henri Menke Dec 23 '18 at 2:18
  • Heh you're right, if I use \setuppapersize[A2] the original sin(x) overflows. And here I assumed the overflow was a sin result so small the exponent overflowed & wrapped to produce a value beyond [-1,1]. You have to increase the step (0.25pt) to keep the curve from appearing drunk, as though it was drawn using method function(1, ...). – user19087 Dec 23 '18 at 2:48
  • @user19087 You could just use hand-drawn waves to avoid any overflow. MetaPost is not very good with numbers. See updated answer. – Henri Menke Dec 23 '18 at 3:09
  • @user19087 Or you could even escape to Lua and compute the sine there. – Henri Menke Dec 23 '18 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.