Изменение цвета контура (для подчеркивания)

Изменение цвета контура (для подчеркивания)

Я использую следующий код (взятый изэтот сайтза красивое подчеркивание моего текста.

\usepackage{ulem}
\usepackage{contour}

\renewcommand{\ULdepth}{1.8pt}
\contourlength{0.8pt}

\newcommand{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{white}{#1}}
}

Однако при подчеркивании в shadedокружениях (из framedпакета) белизна сохраняется вокруг букв. Чтобы исправить это, я подумал, что добавлю это под кодом выше:

\makeatletter

\def\ifenv#1{
   \def\@tempa{#1}%
   \ifx\@tempa\@currenvir
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
   \fi
}

\makeatother

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\newenvcommand}{ m m } % #1 = env name, #2 = command name
{
    \tl_if_exist:cF { g_envc_#1_list_tl } { \tl_new:c { g_envc_#1_list_tl } }
    \tl_gput_right:cn { g_envc_#1_list_tl } { #2 }
    \exp_args:Nc \newcommand { w envc_#1_\cs_to_str:N #2 }
}
\NewDocumentCommand{\checkenvcommands}{ }
{
    \tl_if_exist:cT { g_envc_\use:c {@currenvir} _list_tl }
    {
        \tl_map_inline:cn { g_envc_\use:c {@currenvir} _list_tl }
        {
            \cs_set_eq:Nc ##1 { envc_\use:c {@currenvir} _\cs_to_str:N ##1 }
        }
    }
}
\ExplSyntaxOff

%--Taking the bit below out restores normal underlining
\newenvcommand{shaded}{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{shadedcolor}{#1}}
}

Оказалось, что это не сработало — даже обычное подчеркивание за пределами shadedокружения перестало работать.

Как можно использовать два разных цветовых значения, \contourне конфликтуя друг с другом?

МВЭ:

\documentclass[a4paper,12pt]{report}

%-- Underline:

\usepackage{ulem}
\usepackage{contour}

\renewcommand{\ULdepth}{1.8pt}
\contourlength{0.8pt}

\newcommand{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{white}{#1}}
}

%-- Shaded environment:

\usepackage{framed,color}

\definecolor{shadecolor}{rgb}{.827451,.827451,.827451}

%-- Local commands:

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\newenvcommand}{ m m } % #1 = env name, #2 = command name
{
    \tl_if_exist:cF { g_envc_#1_list_tl } { \tl_new:c { g_envc_#1_list_tl } }
    \tl_gput_right:cn { g_envc_#1_list_tl } { #2 }
    \exp_args:Nc \newcommand { w envc_#1_\cs_to_str:N #2 }
}
\NewDocumentCommand{\checkenvcommands}{ }
{
    \tl_if_exist:cT { g_envc_\use:c {@currenvir} _list_tl }
    {
        \tl_map_inline:cn { g_envc_\use:c {@currenvir} _list_tl }
        {
            \cs_set_eq:Nc ##1 { envc_\use:c {@currenvir} _\cs_to_str:N ##1 }
        }
    }
}
\ExplSyntaxOff

%--Taking the bit below out restores normal underlining
\newenvcommand{shaded}{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{shadedcolor}{#1}}
}

\begin{document}

\ul{Test outside shaded.} %--Works if I take out the \newenvcommand{shaded}{\ul}[1]{…} bit, fails when I put it back.

\begin{shaded}
    \ul{Test inside shaded.} %--Displays white edge if I take out the \newenvcommand{shaded}{\ul}[1]{…} bit, fails when I put it back.
\end{shaded}

\end{document}

Я знаю, что делает команда. На whiteфоне я создаю whiteкромку вокруг букв, чтобы подчеркивание не обрезало буквы. Это работает нормально. Но на shadedcolorфоне я хочу изменить эту кромку, чтобы она соответствовала этому shadedcolor. Все дело в том, чтобы избавиться от некрасивых обрезов букв, которые идут под подчеркиванием.

Просто когда я изменяю эту команду для определенной среды с помощью \newenvcommand{shaded}{\ul}[1], все перестает работать.


EDIT: Забыл включить код

  1. Видимо, я забыл упомянуть, насколько низко/высоко я хочу расположить подчеркивание:
\renewcommand{\ULdepth}{1.8pt}
\contourlength{0.8pt}
  1. И я забыл упомянуть, что я также использую пакеты framedи :color
\usepackage{framed,color}

\definecolor{shadecolor}{rgb}{.827451,.827451,.827451}
  1. Возможно, стоит упомянуть и следующее:
\makeatletter

\def\ifenv#1{
   \def\@tempa{#1}%
   \ifx\@tempa\@currenvir
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
   \fi
}

\makeatother

Все эти правки теперь добавлены в код выше. Извините за неудобства.

решение1

Не ответ, скорее комментарий с картинкой:

Локально определенное \ulбольше не \relaxредактируется при копировании и вставке кода expl3 @egreg изОпределение команд, которые относятся к определенной средеименно, что дает следующий результат (вне среды = красный; внутри среды = синий):

тестовое подчеркивание с контуром

МВЭ

\documentclass[a4paper,12pt]{report}
\newcommand\textdescenders{pqrgym}
\usepackage{ulem}
\usepackage{contour}

\newcommand{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{red}{#1}}
}

%%\usepackage{xparse}
%%
%%\ExplSyntaxOn
%%\NewDocumentCommand{\newenvcommand}{ m m } % #1 = env name, #2 = command name
%%{
%%    \tl_if_exist:cF { g_envc_#1_list_tl } { \tl_new:c { g_envc_#1_list_tl } }
%%    \tl_gput_right:cn { g_envc_#1_list_tl } { #2 }
%%    \exp_args:Nc \newcommand { w envc_#1_\cs_to_str:N #2 }
%%}
%%\NewDocumentCommand{\checkenvcommands}{ }
%%{
%%    \tl_if_exist:cT { g_envc_\use:c {@currenvir} _list_tl }
%%    {
%%        \tl_map_inline:cn { g_envc_\use:c {@currenvir} _list_tl }
%%        {
%%            \cs_set_eq:Nc ##1 { envc_\use:c {@currenvir} _\cs_to_str:N ##1 }
%%        }
%%    }
%%}
%%\ExplSyntaxOff

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newenvcommand}{ m m } % #1 = env name, #2 = command name
  {
   \cs_if_exist:cF { g_envc_#1_list_tl } { \tl_new:c { g_envc_#1_list_tl } }
   \tl_gput_right:cn { g_envc_#1_list_tl } { #2 }
   \exp_after:wN \newcommand \cs:w envc_#1_\cs_to_str:N #2 \cs_end:
  }
\NewDocumentCommand{\checkenvcommands}{ }
  {
   \cs_if_exist:cT { g_envc_\use:c {@currenvir} _list_tl }
     {
      \tl_map_inline:cn { g_envc_\use:c {@currenvir} _list_tl }
        { \cs_set_eq:Nc ##1 { envc_\use:c {@currenvir} _\cs_to_str:N ##1 } }
     }
  }
\ExplSyntaxOff

%--Taking the bit below out restores normal underlining
\newenvcommand{shaded}{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{blue}{#1}
%  \uline{#1}\\
%  \contour{blue}{#1}
  }
}

\newenvironment{shaded}{\checkenvcommands}{}

%\input{the-above-code.tex}
\contourlength{0.6pt}

\begin{document}
\Huge
{\normalsize  \textbackslash uline as is: }

\uline{Test outside shaded. \textdescenders}
\vspace{2ex}

{\normalsize  \textbackslash ul with \texttt{contour:}} 

\ul{Test outside shaded. \textdescenders}

{\normalsize  environment \texttt{shaded} with local \textbackslash ul:} 

\begin{shaded}
%\show\ul
    \ul{Test inside shaded. \textdescenders } %--Displays white edge if I take out the \newenvcommand{shaded}{\ul}[1]{…} bit, fails when I put it back.
\end{shaded}

\end{document}

Я все еще не понимаю, зачем contourэто нужно, или как это может иметь эффект, поскольку контурный ореол даже не простирается достаточно далеко, чтобы повлиять на линию. Но это не имеет отношения к делу.

Код egreg всегда интересен.


Отредактировано для добавления:

Ах, кажется, я понял, почему предпосылки вопроса кажутся мне такими странными: это потому, что пакет ulemпо умолчанию делает следующее (что совершенно нормально):

улем по умолчанию

И есть два параметра, управляющие толщиной линии \ULthickness:

толщина линии улема

и глубина, через \ULdepth:

глубина линии улем

В документации говорится, что значение по умолчанию для \ULdepthравно \maxdimen, которое меняется вместе со шрифтом. Так что если что-то (сбрасывается) устанавливается \maxdimenна маленькое или нулевое значение (или не имеет значения) и/или установка \ULdepthне является доступным действием, чтобы снова опустить подчеркивание (например, команда выполняется \relaxчем-то более важным (и пока не указанным)), то подчеркивание пройдет через нижние выносные элементы, как описано в комментариях. Затем, в свою очередь, если ulemищется необходной путь, мы приходим к тому, как contourможно было бы включиться в картину (действительно, есть старые вопросы/ответы по этому поводу).

Все просто (если это то, что произошло).

Я думал, что, возможно, у меня другая версия ulem, но поскольку последнее обновление было в 2011 году, это кажется маловероятным.

В качестве логистического выбора я бы склонился к тому, чтобы начать с ulemпервого, а не начинать с кооптирования другого пакета(ов), просто из-за подразумеваемых зависимостей, встроенных в поддержание решения этим вторым методом. Однако это другой вопрос, и он не имеет отношения к делу.


Редактировать 2:

Contourи ulemпрекрасно сочетаются с разными цветами:

без окружающей среды

Если вы хотите использовать код egreg для определения области действия команд внутри сред, нужно сделать три вещи: (1) проверить наличие опечаток, которые могли возникнуть при копировании из «over», где бы ни было «over» — например, сколько букв s dв именах?; (2) использовать код egregкод, согласно связанному вопросу, является хорошим источником; и (3) на самом делеиспользоватькод - определение чего-либо - это только первый шаг.

Из того, как вы закодировали, следует, что \ulв среде вы используете shaded:

не тот

не тот, который вы имеете в виду.

Подсказка: определите среду, которая фактически использует\checkenvcommands команда.

Самый простой способ — скопировать код egreg из связанного вопроса, определить свою среду, которая использует этот код, а затем ограничить \ulобласть действия этой средой. После того, как вы внесете все эти изменения, результат будет следующим:

среда кода egreg

МВЭ:

\documentclass[a4paper,12pt]{report}

\newcommand\testdescenders{pqgrym}

\usepackage{ulem}
\usepackage{contour}

\renewcommand{\ULdepth}{1.8pt}
\contourlength{0.8pt}

\newcommand{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{white}{#1}}
}

%-- Shaded environment:

\usepackage{framed,xcolor}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newenvcommand}{ m m } % #1 = env name, #2 = command name
  {
   \cs_if_exist:cF { g_envc_#1_list_tl } { \tl_new:c { g_envc_#1_list_tl } }
   \tl_gput_right:cn { g_envc_#1_list_tl } { #2 }
   \exp_after:wN \newcommand \cs:w envc_#1_\cs_to_str:N #2 \cs_end:
  }
\NewDocumentCommand{\checkenvcommands}{ }
  {
   \cs_if_exist:cT { g_envc_\use:c {@currenvir} _list_tl }
     {
      \tl_map_inline:cn { g_envc_\use:c {@currenvir} _list_tl }
        { \cs_set_eq:Nc ##1 { envc_\use:c {@currenvir} _\cs_to_str:N ##1 } }
     }
  }
\ExplSyntaxOff


\definecolor{shadecolor}{rgb}{.6,.8,.9}

\newenvcommand{xshaded}{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{shadecolor}{#1}}
}


\newenvironment{xshaded}{\checkenvcommands\begin{shaded}}{\end{shaded}}


\begin{document}

\ul{Test outside shaded \testdescenders .}
\begin{xshaded}
    \ul{Test inside shaded \testdescenders .} 
\end{xshaded}


\end{document}

Если вы хотите переопределить framedпакетshaded , это должен быть отдельный вопрос.

=====

Редактировать

Для справки,etoolbox пакет предоставляет способ исправления существующих сред, поэтому код упрощается до:

МВЭ

\documentclass[a4paper,12pt]{report}

\newcommand\testdescenders{pqgrym}

\usepackage{ulem}
\usepackage{contour}%default: copies mode; default # copies = 16

%bring the underline nearer to the baseline
\renewcommand{\ULdepth}{1.8pt}
%set a small width of the halo around the text
\contourlength{0.8pt}

%underline is drawn first, then the overlapping text
%white: assumes page colour is white
\newcommand{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{white}{#1}}
}

% framed provides shaded environment:
\usepackage{framed}
\usepackage{xcolor}
\definecolor{shadecolor}{rgb}{.85,.9,.95}


%define command to define local-scope command and repoint environment to local token-list
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newenvcommand}{ m m } % #1 = env name, #2 = command name
  {
   \cs_if_exist:cF { g_envc_#1_list_tl } { \tl_new:c { g_envc_#1_list_tl } }
   \tl_gput_right:cn { g_envc_#1_list_tl } { #2 }
   \exp_after:wN \newcommand \cs:w envc_#1_\cs_to_str:N #2 \cs_end:
  }
\NewDocumentCommand{\checkenvcommands}{ }
  {
   \cs_if_exist:cT { g_envc_\use:c {@currenvir} _list_tl }
     {
      \tl_map_inline:cn { g_envc_\use:c {@currenvir} _list_tl }
        { \cs_set_eq:Nc ##1 { envc_\use:c {@currenvir} _\cs_to_str:N ##1 } }
     }
  }
\ExplSyntaxOff


%define a local command \ul for framed's shaded environment
\newenvcommand{shaded}{\ul}[1]{%
  \uline{\phantom{#1}}%
  \llap{\contour{shadecolor}{#1}}
}


%patch framed's shaded environment to check for local commands
\usepackage{etoolbox}
\AtBeginEnvironment{shaded}{\checkenvcommands}




\begin{document}

\ul{Test outside shaded \testdescenders .}
\begin{shaded}
    \ul{Test inside shaded \testdescenders .} 
\end{shaded}


\end{document}

Не связано: Если время имеет значение, то компилируемый код, иллюстрирующий проблему (MWE), скорее всего, сгенерирует ответ раньше, в диапазоне от 6 минут до 6 часов (п> 0,90), а не в диапазоне от 6 дней до 6 недель (п< 0,10) - или никогда - чего не мог бы сделать набор случайных фрагментов кода с ошибками.

Однако, поскольку ранее я (медленно) разобрался, как внести исправления contourдля работы в режиме структуры в xelatex (фактически, передавая литералы PDF на выход через \specialкоманду xdvipdfmx), интерес к тому, как это contourприменяется здесь, привел к большому объему знаний и опыта, именно из-за «набора случайных фрагментов кода с ошибками».

Связанный контент