LaTeX 如何使用命令 \leq 替换标记

LaTeX 如何使用命令 \leq 替换标记

<=LaTeX 如何有效地用命令替换标记\leq

例 1:我有以下代码:

\[
   2x <= 4x - 2
\]

我希望在编译后得到以下内容:

在此处输入图片描述

示例 2:

\[
     q --> q 
\]

输出:

在此处输入图片描述

示例 3:

\[
    Q ==> Q 
\]

输出:

在此处输入图片描述

答案1

"8000我认为替换应该只在数学模式下进行。然后可以通过的特殊值激活起始字符\mathcode。这些字符在文本模式下的行为与往常一样,但在数学模式下却变得特殊。

以下示例文档提供了以下简写的解析器:

<< : \ll (latexsym/amsmath)
<> : \neq
<= : \leq
<== : \Leftarrow
<=> : \Leftrightarrow
<-- : \leftarrow
<-> : \leftrightarrow
>> : \gg (latexsym/amsmath)
>= : \geq
--> : \rightarrow
-+ : \pm
+- : \mp
... : \dots (amsmath)
== : \equiv
=. : \doteq
==> : \Rightarrow
=( : \subseteq (latexsym/amsmath)
=) : \supseteq (latexsym/amsmath)
=[ : \sqsubseteq (latexsym/amsmath)
=] : \sqsubseteq (latexsym/amsmath)

示例文件:

\documentclass{article}

%\usepackage{latexsym}
% * because of \gg, \ll, \subseteq, \supseteq, \sqsubseteq, \sqsupseteq
% * not needed if amsmath is loaded

\usepackage{amsmath}% because of \dots

\makeatletter
% LaTeX's \@ifnextchar gobbles spaces, therefore
% \msh@ifnextchar is defined that keeps spaces
\newcommand*{\msh@ifnextchar}[3]{%
  \def\msh@temp{\msh@@ifnextchar{#1}{#2}{#3}}%
  \futurelet\msh@token\msh@temp
}
\newcommand*{\msh@@ifnextchar}[1]{%
  \ifx\msh@token#1%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

% <<
% <>
% <=
% <==
% <=>
% <--
% <->
% >>
% >=
% -->
% -+
% +-
% ...
% ==
% =.
% ==>
% =(
% =)
% =[
% =]

% Commands that take the original meanings of the special characters
\mathchardef\msh@code@less=\mathcode`\<\relax
\mathchardef\msh@code@greater=\mathcode`\>\relax
\mathchardef\msh@code@minus=\mathcode`\-\relax
\mathchardef\msh@code@plus=\mathcode`\+\relax
\mathchardef\msh@code@equal=\mathcode`\=\relax
\mathchardef\msh@code@dot=\mathcode`\.\relax

% Macro \resetmathshorthands resets the original meaning of the
% special characters by resetting their \mathcode values
\@ifdefinable{\resetmathshorthands}{%
  \edef\resetmathshorthands{%
    \mathcode\number`\<=\msh@code@less
    \mathcode\number`\>=\msh@code@greater
    \mathcode\number`\-=\msh@code@minus
    \mathcode\number`\+=\msh@code@plus
    \mathcode\number`\.=\msh@code@dot
    \mathcode\number`\==\msh@code@equal
  }%
}

% Macro \setmathshorthands activates and defines the special
% characters
\begingroup
  \catcode`\<=\active
  \catcode`\>=\active
  \catcode`\-=\active
  \catcode`\+=\active
  \catcode`\.=\active
  \catcode`\==\active
  \edef={\string=}%
  \@ifdefinable{\setmathshorthands}{%
    \xdef\setmathshorthands{%
      \mathcode\number`\<="8000 %
      \mathcode\number`\>="8000 %
      \mathcode\number`\-="8000 %
      \mathcode\number`\+="8000 %
      \mathcode\number`\.="8000 %
      \mathcode\number`\=="8000 %
      \let\noexpand<\noexpand\msh@less
      \let\noexpand>\noexpand\msh@greater
      \let\noexpand-\noexpand\msh@minus
      \let\noexpand+\noexpand\msh@plus
      \let\noexpand.\noexpand\msh@dot
      \let\noexpand=\noexpand\msh@equal
    }%
  }%
\endgroup

% The parsers for the math shorthands follow:

% <<
% <>
% <=
% <==
% <=>
% <--
% <->
\newcommand*{\msh@less}{%
  \msh@ifnextchar<{%
    \ll\@gobble
  }{%
    \msh@ifnextchar>{%
      \neq\@gobble
    }{%
      \msh@ifnextchar={%
        \expandafter\msh@less@equal\@gobble
      }{%
        \msh@ifnextchar-{%
          \expandafter\msh@less@minus\@gobble
        }{%
          \msh@code@less
        }%
      }%
    }%
  }%
}
\newcommand*{\msh@less@equal}{%
  \msh@ifnextchar={%
    \Leftarrow\@gobble
  }{%
    \msh@ifnextchar>{%
      \Leftrightarrow\@gobble
    }{%
      \leq
    }%
  }%
}
\newcommand*{\msh@less@minus}{%
  \msh@ifnextchar-{%
    \leftarrow\@gobble
  }{%
    \msh@ifnextchar>{%
      \leftrightarrow\@gobble
    }{%
      \msh@code@less\msh@code@minus
    }%
  }%
}

% >>
% >=
\newcommand*{\msh@greater}{%
  \msh@ifnextchar>{%
    \gg\@gobble
  }{%
    \msh@ifnextchar={%
      \geq\@gobble
    }{%
      \msh@code@greater
    }%
  }%
}

% -->
% -+
\newcommand*{\msh@minus}{%
  \msh@ifnextchar-{%
    \expandafter\msh@minus@minus\@gobble
  }{%
    \msh@ifnextchar+{%
      \mp\@gobble
    }{%
      \msh@code@minus
    }%
  }%
}
\newcommand*{\msh@minus@minus}{%
  \msh@ifnextchar>{%
    \rightarrow\@gobble
  }{%
    \msh@code@minus\msh@code@minus
  }%
}

% +-
\newcommand*{\msh@plus}{%
  \msh@ifnextchar-{%
    \pm\@gobble
  }{%
    \msh@code@plus
  }%
}

% ...
\newcommand*{\msh@dot}{%
  \msh@ifnextchar.{%
    \expandafter\msh@dot@dot\@gobble
  }{%
    \msh@code@dot
  }%
}
\newcommand*{\msh@dot@dot}{%
  \msh@ifnextchar.{%
    \expandafter\msh@dot@dot@dot\@gobble
  }{%
    \msh@code@dot
    \msh@code@dot
  }%
}
\newcommand*{\msh@dot@dot@dot}{%
  % remove space after "...", because a space would
  % disturb \dots' auto-positioning feature.
  \expandafter\dots\romannumeral-`\x
}

% ==
% =.
% ==>
% =(
% =)
% =[
% =]
\newcommand*{\msh@equal}{%
  \msh@ifnextchar={%
    \expandafter\msh@equal@equal\@gobble
  }{%
    \msh@ifnextchar.{%
      \doteq\@gobble
    }{%
      \msh@ifnextchar({%
        \subseteq\@gobble
      }{%
        \msh@ifnextchar){%
          \supseteq\@gobble
        }{%
          \msh@ifnextchar[{%
            \sqsubseteq\@gobble
          }{%
            \msh@ifnextchar]{%
              \sqsupseteq\@gobble
            }{%
              \msh@code@equal
            }%
          }%
        }%
      }%
    }%
  }%
}
\newcommand*{\msh@equal@equal}{%
  \msh@ifnextchar>{%
    \Rightarrow\@gobble
  }{%
    \equiv
  }%
}
\makeatother

% Activate math shorthands in the math modes
\everymath{\setmathshorthands}
\everydisplay{\setmathshorthands}

\begin{document}
\centering
\newcommand*{\test}[1]{%
  $#1$%
  \[#1\]%
}
\test{a << b < c <= d >= e > f >> g}
\test{a <> b = c =. d == e}
\test{a <== b <-- c <-> d <=> e --> f ==> g}
\test{a +- b = -(-a -+ +b)}
\test{a, ..., z <> a + ...+ z}
\test{a =( b =) c =[ e =] f}
\end{document}

结果

评论:

  • \msh@ifnextchar查找下一个标记。与 LaTeX 相反,\@ifnextchar它不会吞噬空格。例如,这对于a + -ba - b) 不同于a +- b(一个±b)。

  • ...\dots被包替换amsmath,因为它具有自动检测功能。点的垂直位置取决于下一个标记。例如,在逗号分隔的列表中,\dots变为\ldots;如果下一个标记是+,则\cdots使用 。

    在命令标记(如 )之后,空格会被吞噬\dots,但在其他字符(如 )之后则不会...。因此,\msh@dot@dot@dot在调用 之前会删除后面的空格\dots。否则,即使空格后的标记是 ,\dots也会看到空格并变成。\ldots+

  • 建议的_C\subseteq我来说太模糊了,因为它看起来像一个普通的下标C。而且没有合适的 ASCII 字母可用于 的简写。因此,我为正方形形式\supseteq实现了 的简写=(=)对。=[=]

    如果等号后面有圆括号或方括号,则可以用空格来防止简写替换,例如a = (b + c)

答案2

这是一个有趣的问题,可以通过比接受的答案更紧凑的宏来解决:

\long\def\isnextchar#1#2#3{\begingroup\toks0={\endgroup#2}\toks1={\endgroup#3}%
   \let\tmp=#1\futurelet\next\isnextcharA
}
\def\isnextcharA{\the\toks\ifx\tmp\next0\else1\fi\space}

\def\skipnext#1#2{#1}    
\def\trynext#1{\trynextA#1\relax\relax}
\def\trynextA#1#2\relax#3\relax#4#5{%
   \ifx\relax#2\relax \def\next{\isnextchar#1{\skipnext{#4}}{#5#3}}\else
      \def\next{\isnextchar#1{\skipnext{\trynextA#2\relax#3#1\relax#4{#5}}}{#5#3}}\fi
   \next
}
\def\mspecdefA#1#2#3 : #4{\ifx#2\undefined
   \def#2{\trynext{#3}#4{#1}}\else
   \toks0={\trynext{#3}#4}\toks1=\expandafter{#2}%
   \edef#2{\the\toks0{\the\toks1}}\fi
}
\def\mspecdef#1{%
   \expandafter\ifx\csname m:#1\endcsname\relax
      \expandafter\mathchardef\csname m:#1\endcsname=\mathcode`#1
   \fi
   \mathcode`#1="8000 
   \begingroup \lccode`~=`#1 
   \lowercase{\endgroup\expandafter\mspecdefA\csname m:#1\endcsname~}%
}

\mspecdef << : \ll
\mspecdef <> : \neq
\mspecdef <= : \leq
\mspecdef <== : \Leftarrow
\mspecdef <=> : \Leftrightarrow
\mspecdef <-- : \leftarrow
\mspecdef <-> : \leftrightarrow
\mspecdef >> : \gg
\mspecdef >= : \geq
\mspecdef --> : \rightarrow
\mspecdef -+ : \pm
\mspecdef +- : \mp
\mspecdef ... : \dots
\mspecdef == : \equiv
\mspecdef =. : \doteq
\mspecdef ==> : \Rightarrow
\mspecdef =( : \subseteq
\mspecdef =) : \supseteq
\mspecdef =[ : \sqsubseteq
\mspecdef =] : \sqsubseteq

test:

$$ a << b < c <= d >= e > f >> g $$
$$ a <> b = c =. d == e $$
$$ a <== b <-- c <-> d <=> e --> f ==> g $$
$$ a +- b = -(-a -+ +b) $$
$$ a, ..., z <> a + ...+ z $$
$$ a =( b =) c =[ e =] f $$

\bye

结果与接受的答案相同。

编辑它是如何工作的?当我们

\mspecdef ax : \U    \mspecdef axy : \V    \mspecdef abcd : \W 

则该a字符被设置为数学活动(即\matcode"8000,并定义为

\def a{\trynext{bcd}\W{\trynext{xy}\V{\trynext{x}\U{normal a}}}}

此宏会测试以下字符串是否为bcd(使用重复调用\isnextchar)。如果为真,则跳过宏的下一部分并\W进行处理。否则,处理宏的下一部分。这意味着,xy测试了。如果失败,则x测试了,如果失败,则a打印正常。

我们只能使用原始级别的 TeX 宏来做到这一点,而无需任何非 TeX 工具(如 lua 代码),也无需任何晦涩难懂的解决方案(如 expl3)。

答案3

以下部分摘自定义一个命令,使其仅在环境中document有效

在此处输入图片描述

\documentclass{article}
\makeatletter
\AtBeginDocument{
  \begingroup\lccode`~=`<
  \lowercase{\endgroup\def~{\@ifnextchar={\leq\@gobble}{<}}}%
  \catcode`<=\active
}
\makeatother
\begin{document}
$2x <= 4x - 2 \leq y$
\end{document}

但使用编辑器的搜索和替换功能似乎同样合适。

答案4

虽然这个解决方案没有保持“数学化”的风格,但对于有抱负的文学程序员来说,它非常有用。好处是什么?没有 TeX hackery(您看到的),因此可以轻松自定义!

使用listings包:

\documentclass{article}
\usepackage{listings,latexsym}

% Disclaimer: I don't actually know Pascal.  It's on my todo-list.
\lstset{language=Pascal}

\begin{document}
\begin{lstlisting}[literate={<=}{{$\leq$}}1
                            {>=}{{$\geq$}}1
                            {!=}{{$\neq$}}1
                            {<==}{{$\Longleftarrow$}}2 % note this width was increased
                            {==>}{{$\Longrightarrow$}}2
                            {<<}{{$\ll$}}1 % the only need for `latexsym`
                            {+-}{{$\pm$}}1
                            {in}{{$\in$}}1] % and so on
  if x <= 5 do stuff();
  if x in {4 +- 2}
  stuff << st
\end{lstlisting}
\end{document}

在此处输入图片描述

相关内容