3

This is a follow-up question to my previous one on using special characters in user-defined commands. I have extended the command \Char{} to take an optional parameter for a fixed with. \Char{} is supposed to work in text mode and math mode.

The MWE

\documentclass{article}

\usepackage{lmodern}
\usepackage{xparse}
\usepackage{relsize}
\usepackage{amssymb}

\ExplSyntaxOn

\NewDocumentCommand \Char { o m } 
{
  \IfNoValueTF {#1}
  {
    \str_case_x:nnF { \tl_to_str:n {#2} }
    {
      {              } { \mbox{$\varepsilon$}           }
      { ##           } { \mbox{\texttt{\#}}             }
      { \c_tilde_str } { \mbox{\textscale{.87}{$\Box$}} }
    }
    { \mbox{\texttt{#2}} }
  }
  {
    \str_case_x:nnF { \tl_to_str:n {#2} }
    {
      {              } { \makebox[#1]{$\varepsilon$}           }
      { ##           } { \makebox[#1]{\texttt{\#}}             }
      { \c_tilde_str } { \makebox[#1]{\textscale{.87}{$\Box$}} }
    }
    { \makebox[#1]{\texttt{#2}} }
  }
}

\ExplSyntaxOff

\begin{document}

\Char{}\Char{~}\Char{#}\Char{x}
$\Char{}\Char{~}\Char{#}\Char{x}$
\Char[1em]{}\Char[1em]{~}\Char[1em]{#}\Char[1em]{x}
$\Char[1em]{}\Char[1em]{~}\Char[1em]{#}\Char[1em]{x}$

\end{document}

produces the desired result

desired result

However, is there a better way to implement this functionality based on expl3?

  • 1
    LaTeX3 is still not “complete” regarding document commands, so many things are still not done yet. – Manuel Nov 14 '17 at 11:51
  • @Manuel Does this mean I should leave the implementation as it is for now accepting the mixture of LaTeX3 and LaTeX2e? – Matthias Nov 14 '17 at 11:54
  • 2
    Yes. Only may be reduce duplication of code (e.g., only have one \str_case rather than having two of them, and may be moving \texttt out of the cases if possible, i.e., \makebox{\texttt{\str_case .. }}). – Manuel Nov 14 '17 at 11:57
  • 2
    it depends if you want to optimise run time or optimise your developer time, I'd consider using O{\width} instead of o and then you don't need the IfNoValue test you can just use the \makebox form always as \makebox[\width]{zzz} is the same as \mbox{\zzz} just marginally less efficient. but it would halve the size of your definition and save you checking the two halves were in sync as you add more cases. – David Carlisle Nov 14 '17 at 12:24
5

You can use this as a starter:

\documentclass{article}

\usepackage{lmodern}
\usepackage{xparse}
\usepackage{relsize}
\usepackage{amssymb}

\ExplSyntaxOn

\NewDocumentCommand \Char { o m } 
{
    \IfNoValueTF { #1 } { \makebox } { \makebox [#1] }
    {
    \str_case_x:nnF { \tl_to_str:n {#2} }
    {
      {              } { $\varepsilon$           }
      { ##           } { \texttt{\#}             }
      { \c_tilde_str } { \textscale{.87}{$\Box$} }
    }
    { \texttt{#2} }
  }
}

\ExplSyntaxOff

\begin{document}

\Char{}\Char{~}\Char{#}\Char{x}
$\Char{}\Char{~}\Char{#}\Char{x}$
\Char[1em]{}\Char[1em]{~}\Char[1em]{#}\Char[1em]{x}
$\Char[1em]{}\Char[1em]{~}\Char[1em]{#}\Char[1em]{x}$

\end{document}
5

Using the fact that \makebox[\width]{...} is a slightly slower version of \mbox{...}, we can trade a bit of efficiency with avoidance of code duplication.

\documentclass{article}

\usepackage{lmodern}
\usepackage{xparse}
\usepackage{relsize}
\usepackage{amssymb}

\ExplSyntaxOn

\NewDocumentCommand \Char { O{\width} m }
 {
  \str_case_x:nnF { \tl_to_str:n {#2} }
   {
    {              } { \makebox[#1]{$\varepsilon$}           }
    { ##           } { \makebox[#1]{\texttt{\#}}             }
    { \c_tilde_str } { \makebox[#1]{\textscale{.87}{$\Box$}} }
   }
   { \makebox[#1]{\texttt{#2}} }
 }

\ExplSyntaxOff

\begin{document}

\Char{}\Char{~}\Char{#}\Char{x}
$\Char{}\Char{~}\Char{#}\Char{x}$
\Char[1em]{}\Char[1em]{~}\Char[1em]{#}\Char[1em]{x}
$\Char[1em]{}\Char[1em]{~}\Char[1em]{#}\Char[1em]{x}$

\end{document}

enter image description here

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.