2
\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{newunicodechar}
\newunicodechar{‖}{\ensuremath{\|}}
\begin{document}
$$ ‖x‖ $$
$$ \big‖x\big‖ $$  % Error: Missing delimiter
\end{document}

Can we somehow hack \big to make it work?

3

2 Answers 2

3

Using \ensuremath makes no sense.

You can make it work with pdflatex, but you have to use braces with \big or similar commands. Not with \left and \right.

\documentclass{article}
\usepackage{amsmath}
\usepackage{newunicodechar}
\newunicodechar{‖}{\|}

\begin{document}

\[
‖x‖ + \bigl{‖}x\bigr{‖} + \left‖\frac{x}{2}\right‖
\]

\end{document}

enter image description here

The problem is that is not a single byte and \bigl only absorbs the first one.

Usual caveats. $$ should not be used in LaTeX and \big is not the right command for that use case.

On the other hand, \lVert and \rVert are the right commands for that use case.

6
  • Thanks! Unfortunately, it doesn't seem to work with \left and \right. Why shouldn't \big be used? What's the difference to using \bigl and \bigr? Seems like \big is the "default" suggestion for delimiter sizes around the web (e.g. overleaf or wikibooks)
    – Hyperplane
    Jun 26 at 15:49
  • @Hyperplane try $\big|-1\big|$ vs $\bigl|-1\bigr|$, the l an r variants create proper opening and closing symbol codes and thus the spacing on the minus becomes that of a sign not a binary relation.
    – daleif
    Jun 26 at 15:54
  • Same problem exists with ‖-x‖ after \newunicodechar{‖}{\|}. Compare with this: \lVert -x \rVert. Jun 26 at 16:05
  • 1
    The description of overleaf and wikibooks on this topic is incorrect. Jun 26 at 16:14
  • @Hyperplane It does work with \left and \right, without braces. See edit.
    – egreg
    Jun 26 at 16:26
1

For "academical" purpose, this is a macro that automatically braces the next Unicode character.

It does requires patching \big however. Unavoidably.

How TeX input stream works is a bit complex, you still need TeX knowledge to use this macro i.e. it's not 100% automatic.

It only works in pdflatex -- nevertheless if you're using some Unicode engine you would not need this code at all.

Side note--if you use this in a package/extend the code etc., fix the naming convention of \__stored_content etc. yourself, see expl3 manual interface3.pdf.

(use \tl_analysis_map_inline:nn just to check if it's an active character instead of something like e.g. \str_count:n, to handle some unlikely case that there's a length-1 control sequence and \escapechar=-1...)

%! TEX program = pdflatex
\documentclass{article}
\usepackage{newunicodechar}
\errorcontextlines=100
\newunicodechar{‖}{\ensuremath{\|}}

\begin{document}


\ExplSyntaxOn

% command docs:
% if you execute `\__brace_next_unicode:nw {blob blob} ■` where ■ is any
% multi-byte UTF8 character, after some execution steps `blob blob {■}`
% will be executed. (spaces are only for demonstration.)

\cs_new_protected:Npn \__brace_next_unicode:nw #1 {
 \peek_N_type:TF {
  \tl_set:Nn \__stored_content {#1}  % actually this part can be done expandably
        % as well... but \peek_N_type:TF is already unexpandable
  \__brace_next_unicode_get_one_byte:N
 }
 {
  % do nothing, just put `blob blob` out
  #1
 }
}

\cs_new_protected:Npn \__brace_next_unicode_get_one_byte:N #1 {
 \tl_analysis_map_inline:nn {#1} {
  \bool_set:Nn \__is_active_character { \token_if_eq_charcode_p:NN ##3 D }
 }
 \bool_if:nTF \__is_active_character {
  \int_compare:nNnTF {`#1} < {"80} {
   % not a part of multibyte UTF8 character, put it back.
   \__stored_content #1
  } {
   % part of multibyte UTF8 character.
   \int_compare:nNnTF {`#1} < {"E0} {
    % 2 bytes
    \__brace_next_unicode_handle_two:nn #1
   } {
    \int_compare:nNnTF {`#1} < {"F0} {
     % 3 bytes
     \__brace_next_unicode_handle_three:nnn #1
    } {
     % 4 bytes
     \__brace_next_unicode_handle_four:nnnn #1
    }
   }
  }
 }
 {
  % else, it could be a control sequence or similar. Do nothing with it.
  \__stored_content #1
 }
}

\cs_new_protected:Npn \__brace_next_unicode_handle_two:nn #1 #2 {
 \__stored_content {#1 #2}
}

\cs_new_protected:Npn \__brace_next_unicode_handle_three:nnn #1 #2 #3 {
 \__stored_content {#1 #2 #3}
}

\cs_new_protected:Npn \__brace_next_unicode_handle_four:nnnn #1 #2 #3 #4 {
 \__stored_content {#1 #2 #3 #4}
}

%\__brace_next_unicode:nw {\pretty:nn {123}} ■

\NewCommandCopy \oldbig \big
\def \big {\__brace_next_unicode:nw {\oldbig}}

\ExplSyntaxOff




\[ ‖x‖ \]
\[ \big‖x\big‖ \]

% check that it still works in normal cases
\[ \big|x\big| \]
\[ \big|x\big| \]
\[ \big{|}x\big{|} \]
\[ \big{|}x\big{|} \]
\[ \big\lbrace x\big\rbrace \]


\end{document}
6
  • Consecutive \[ ... \] is actually not recommended.
    – user202729
    Jun 26 at 17:46
  • Please, use the recommended naming scheme: \__stored_content does not fit. And also \let\oldbig\big is not good, and should be \NewCommandCopy\oldbig\big because \big is defined with \DeclareRobustCommand.
    – egreg
    Jun 26 at 20:45
  • \[ \big \lbrace x\big\rbrace \] Jun 26 at 21:52
  • @DavidCarlisle That still work right? The peek_N_type returns a "false negative" i.e. returns false even if it's a N-type, but a \lbrace is not a partial UTF8 character and doesn't need bracing anyway. But yes, worth noting if someone else decide to modify the result and get strange result (generally-speaking \peek family of functions has a few special cases that they fails)
    – user202729
    Jun 27 at 0:07
  • Actually the \let won't be "very harmful" as the fix is idempotent i.e. applying multiple times doesn't hurt
    – user202729
    Jun 27 at 4:42

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.