使用 Markdown 样式的格式进行粗体和斜体

使用 Markdown 样式的格式进行粗体和斜体

我很喜欢这里的系统,其中*...*是斜体,**...**是粗体,***...***是粗体斜体。在 (La)TeX 中可以做到这一点吗?

实现第一个的 MWE:

\documentclass{article}

\begin{document}

\begingroup

\catcode`*\active
\def*#1*{\emph{#1}}

*italic text*

\endgroup
\end{document}

但是另外两个呢?关于让两个字符活跃起来的问题还存在,但在命令的开头和结尾都使用两个字符听起来更难。而且不要让我开始人物。

附带一个问题:我一直在想:\catcode`*\active和之间有什么区别\catcode`\*\active? (请注意\第二个例子中的 。)

答案1

这里的好处是,您可以用 打开该功能,并用(默认条件)\starON将其关闭。\starOFF

这是 MWE。

\documentclass{article}
\makeatletter
\def\starparse{\@ifnextchar*{\bfstarx}{\itstar}}
\def\bfstarx#1{\@ifnextchar*{\bfitstar\@gobble}{\bfstar}}
\makeatother
\def\itstar#1*{\textit{#1}\starON}
\def\bfstar#1**{\textbf{#1}\starON}
\def\bfitstar#1***{\textbf{\textit{#1}}\starON}
\def\starON{\catcode`\*=\active}
\def\starOFF{\catcode`\*=12}
\starON
\def*{\starOFF \starparse}
\starOFF
\begin{document}
\starON Turn feature on:\par
This is a test of *italic*, and **bold**, as well as ***bold, italic*** text.

\starOFF Turn feature off:\par
This is a test of *italic*, and **bold**, as well as ***bold, italic*** text.
\end{document}

在此处输入图片描述

答案2

以下解决方案使用 LuaLaTeX 的功能来定义一个名为的函数allstars,它将将星号组 -- ***...*****...***...*-- 转换为“传统” LaTeX 代码:{\bfseries\itshape ...}{\bfseries ...}{\itshape ...}。代码假设基于星号的 markdown 确实不是跨越换行符。代码不会使*“活动” (在 TeX 意义上)。因此,*不会出现因活动而导致的各种并发症。

使用带星号的 LaTeX 宏(例如\section*)和带星号的 LaTeX 环境(例如equation*)是可以的 - 也就是说,它们将不是导致编译崩溃——如果相应的输入行上没有其他星号。为了更加通用,代码提供了两个宏——名为\markdownoff\markdownon——用于关闭和打开函数的操作allstars。该allstars函数是未激活默认情况下——必须通过执行来打开它\markdownon

markdown 指令可以嵌套,也就是说斜体字符串可以包含 加粗斜体 子字符串还有粗体字符串可以包含 加粗斜体 子字符串


allstars函数被分配给 LuaTeX 的process_input_buffer回调,使其在编译的早期阶段运行(在 TeX 的“眼睛”开始工作之前)。该函数allstars使用 Lua 的函数对每行输入执行三次“扫描”或“传递” string.gsub。在第一次传递期间,它会搜索在第一次扫描中,它会查找字符***;在第二次扫描中,它会查找**字符对;在第三次也是最后一次扫描中,它会查找字符对*

为了充分理解该allstars函数的工作原理,有必要检查一下如果输入行包含四个或更多连续星号的情况(尽管“常规”markdown 不应包含此类情况)。例如,如果输入行包含七个星号序列

a*******b 

并且输入行上没有其他星号,则输出将是“ab”:单个““a”和“b”之间有一个字符,但没有斜体或粗体字符。发生了什么?函数将中的前六个星号*******解释allstars一对字符串**********因此被转换为{\bfseries\itshape};因此它们最终什么都不做,至少就 TeX 而言。不过,第七个星号是不是由函数修改allstars,因此由 TeX 排版。

或者,考虑字符串

a*******b********c

(“a”和“b”之间有七个星号,“b”和“c”之间有八个星号)。在第一遍中string.gsub,输入行被转换为

a{\bfseries\itshape}*b{\bfseries\itshape}**c

就我们的目的而言,这相当于

a*b**c

该函数的第二遍没有做任何事,因为没有一对字符数**出现在输入行中。函数的第三遍查找一个一对字符*,因此将输入行转换为

a{\itshape b}*c

这就是 (Lua)TeX 引擎排版的内容。

最后考虑一下如果输入行包含以下内容会发生什么情况

\section*{A New* Hope}

(并且没有其他星号)。该函数的第三遍allstars在此输入行中找到一对单个星号,因此将其转换为

\section{\itshape {A New} Hope}

相当于

\section{\itshape A New Hope}

因此,我们得到一个编号节,节标题(但不是节号)以粗斜体排版。可能不是预期或预期的...如果您确实需要*直接排版,则应发出\markdownoff暂停allstars函数操作的命令。


在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{amsmath}   % for 'equation*' environment

\usepackage{luacode,luatexbase}
\begin{luacode}
   -- Use Lua captures to extract material affected by markdown
   function allstars (line) 
      line = string.gsub( line, "(%*%*%*)(.-)(%*%*%*)", "{\\bfseries\\itshape %2}")
      line = string.gsub( line, "(%*%*)(.-)(%*%*)", "{\\bfseries %2}" )
      line = string.gsub( line, "(%*)(.-)(%*)", "{\\itshape %2}" )
      return line
   end
\end{luacode}

\newcommand\markdownon{%
   \directlua{luatexbase.add_to_callback( "process_input_buffer", allstars, "allstars" )}}
\newcommand\markdownoff{%
   \directlua{luatexbase.remove_from_callback( "process_input_buffer", "allstars" )}}

\begin{document}

\markdownon
normal

*italic*, **bold**, normal, *more italic*

**bold**, *italic*, **more bold**

***bold italic***, normal, ***more bold italic text***,

**bold text containing a *bold italic* substring**

*italic text with **bold italic** substring*

normal again

\markdownoff % not actually required, as each of the following lines contains exactly one asterisk
\medskip
an \texttt{equation*} environment:
\begin{equation*}
a = b
\end{equation*}

\markdownon
more **bold text with a *bold italic* substring**
\end{document}

答案3

如果您不反对使用'而不是*,那么该wiki包就是简单的解决方案。

这样就不会与带星号的宏发生冲突。此外,它使用常见的 Wikipedia 语法,另一方面,粗体和斜体可以嵌套甚至重叠:

平均能量损失

\documentclass[border=1cm]{standalone}
\usepackage{wiki}
\begin{document}
\wikimarkup
normal, 
'''bold''', 
''italic'', 
'''''bold italic''''' 
and 
''over'''lap''ping''' 
style.
\end{document}

相关内容