
У меня есть текстовая информация, к которой мне нужно применить текстовый формат ко всем внешним скобкам, например, сделать их крупнее и/или жирнее.
В каком-то смысле я хочу обрабатывать текст как
^(...(...(...)...)...(..)..^)...^(..(....)..^)
Где ^( и ^) имеют специальные форматы (по сути, все, что я хочу сделать, это выделить внешние скобки некоторого математического текста (но это не математический текст), чтобы его было легче читать).
Это будет выглядеть так
(...(...(...)...)...(..)..)...(..(....)..)
Есть идеи, как это сделать проще? Я не хочу добавлять \mathbf в каждую скобку, так как это загромождает текст.
(на самом деле я хотел бы изменить текст непосредственно перед *( и применить к нему форматирование (только к слову перед ним).
Так
Какой-тоТекст(....)
будет применен формат к SomeText и внешнему элементу ( ), но все, что находится внутри, останется.
Я хочу максимально избежать загромождения текста, и полагаю, что необходимо какое-то окружение?
решение1
Я бы не стал связываться с catcodes, так как никогда не знаешь, как это повлияет на другие пакеты, особенно для математики, а вместо этого предоставил бы небольшой парсер. Автор вставляет ввод как:
\[\parser SomeWords (...(\alpha...(...)...)...(\beta)..)...(..(....)..);\]
Вы можете придать \parser
более семантическое значение, если хотите, все, что находится между ним и первой открывающей скобкой, будет набрано жирным шрифтом. Если строка не содержит математики, вы можете опустить \[..\]
.
Мы анализируем содержимое между первой открывающей скобкой и последней до точки с запятой, буква за буквой, используя цикл ядра LaTeX @tfor
. Мы сохраняем баланс между внешним и внутренним циклами и набираем соответственно. Вот результат:
MWE показан ниже:
\documentclass{article}
\begin{document}
\makeatletter
\def\L{(}
\def\R{)}
%left counter
\newcounter{cnt}
\setcounter{cnt}{1}
%right counter
\newcounter{cntr}
\setcounter{cntr}{1}
%new counter balancing
\newcounter{bal}
\setcounter{bal}{0}
%define the parser
\def\parser#1(#2);{%
\textbf{#1 (}
\@tfor\next:=#2\do{%
\ifx\next\L \stepcounter{cnt}
\stepcounter{bal}
\ifnum\thebal=0 \textbf{\next}\else\normalfont\next\fi%
%
\else
\ifx\next\R \stepcounter{cntr}
\addtocounter{bal}{-1}
\ifnum\thebal=-1 \textbf{\next}\else\next\fi%
\else
\next
\fi
\fi
}%end forloop
\textbf{)}
}
\[\parser SomeWords (...(\alpha...(...)...)...(\beta)..)...(..(....)..);\]
\end{document}
решение2
Может быть \lgroup
, / \rgroup
для внешних скобок?
$$\lgroup a(b(c)) (d)\rgroup \lgroup e(fg) h\rgroup$$
\bye
Для макроса можно использовать скобки в качестве разделителей макроса и пробел в качестве конечного разделителя (в этом примере смена строки считается пробелом, то есть конечным разделителем):
\def\someFormat#1{{\it #1\/}}
\def\thingamabob#1(#2) {{\someFormat{#1}\mathsurround0pt$\lgroup$#2$\rgroup$}}
\thingamabob SomeText(blah(foo)bar) \thingamabob (bar(baz)foo(blah))
\bye
Он \mathsurround0pt
нужен только для того, чтобы убедиться, что до/после изменений mathmode не добавлено никаких пробелов, если он установлен на >0, а окружающая группа нужна для того, чтобы содержать эту настройку внутри этой команды.
решение3
Ниже указано \important[<prefix>]{<stuff>}
, что наборыпрефикс(жирным шрифтом, текстовый режим) и окружает <stuff>
и \big(
как \big)
форму акцентирования. В качестве альтернативы также возможен подход в стиле окружения, предоставляемый grp
(сокращение от "group"):
\documentclass{article}
\newcommand{\important}[2][]{\textbf{#1}\big(#2\big)}%
\newenvironment{grp}{\big(}{\big)}
\begin{document}
\[
\important[SomeText]{\ldots(\ldots(\ldots)\ldots)\ldots(\ldots)\ldots}\ldots\important{\ldots(\ldots)\ldots}
\]
\[
\textbf{SomeText}\begin{grp}\ldots(\ldots(\ldots)\ldots)\ldots(\ldots)\ldots\end{grp}\ldots\begin{grp}\ldots(\ldots)\ldots\end{grp}
\]
\end{document}
решение4
Следуя предложению @wh1t3 выше, вот один из способов определения \outermost
команды, которая выделяет любой текст перед первой открывающей скобкой, а затем каждую пару внешних скобок после нее. Его нужно изолировать в блоке, если вы не хотите, чтобы скобки обрабатывались специально для остальной части кода.
Код выделения можно изменить на любой другой: в частности, я предположил, что это будет использоваться в текстовом режиме, поэтому здесь используется \textbf
, но \mathbf
(или, возможно, команда bad man bold для работы со скобками) подойдет, если вы захотите использовать это в математическом режиме.
Главное преимущество этого подхода заключается в том, что не требуется дополнительной разметки текста, содержащего скобки.
\documentclass{standalone} % for demonstration purposes
\makeatletter
\newcount\@nbegin % number of inner open parentheses in current block
\newcount\@nend % number of outer open parentheses in current block
\newcommand\@outermostopen{%
\@nbegin=0\@nend=0\relax%
\@beginisinner\@endisouter%
\@outermostem{(}}
\newcommand\@outermostclose{%
\@outermostem{)}%
\@beginisouter}
\newcommand\@inneropen{%
(%
\advance\@nbegin by 1\relax%
\@endisinner}
\newcommand\@innerclose{%
)%
\advance\@nend by 1
\ifnum\@nend=\@nbegin%
\@endisouter\fi%
}
\def\outermost#1({%
\catcode`(=\active
\catcode`)=\active
\@outermostem{#1}\@outermostopen%
}
{ % Commands that redefine parentheses themselves need to be defined
% in a context where () are active
\catcode`(=\active
\catcode`)=\active
\gdef\@beginisouter{%
\def({\@outermostopen}%
}
\gdef\@beginisinner{%
\def({\@inneropen}%
}
\gdef\@endisouter{%
\def){\@outermostclose}%
}
\gdef\@endisinner{%
\def){\@innerclose}%
}
}
\newcommand{\@outermostem}[1]{\textbf{\Large #1}}
% redefine for whatever emphasis method you want
\makeatother
\begin{document}
{\outermost Beginning(\dots(\dots)\dots)\dots(\dots)\dots(\dots(\dots(\dots)\dots(\dots)\dots)\dots)}
\end{document}
который дает