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?

4
  • 1
    LaTeX3 is still not “complete” regarding document commands, so many things are still not done yet.
    – Manuel
    Nov 14, 2017 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, 2017 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, 2017 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. Nov 14, 2017 at 12:24

2 Answers 2

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

You must log in to answer this question.

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