Redefinindo a cor do contorno (para sublinhar)

Redefinindo a cor do contorno (para sublinhar)

Estou usando o seguinte código (retirado deesse sitepor colocar belos sublinhados no meu texto.

\usepackage{ulem}
\usepackage{contour}

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

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

Porém, ao sublinhar dentro shadeddos ambientes (da framedembalagem), a brancura persiste ao redor das letras. Para corrigir isso, pensei em adicionar isto abaixo do código acima:

\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}}
}

Acontece que não funcionou – até fez com que o sublinhado normal fora dos shadedambientes parasse de funcionar completamente.

Como posso ter dois valores de cores diferentes \contoursem que eles entrem em conflito um com o outro?

MWE:

\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}

Estou ciente do que o comando está fazendo. No whitefundo, crio uma whiteborda ao redor das letras para que o sublinhado não corte as letras. Isso funciona bem. Mas no shadedcolorfundo eu quero mudar essa borda para combinar com isso shadedcolor. O objetivo é se livrar dos cortes feios nas letras que ficam abaixo do sublinhado.

Acontece que quando modifico esse comando para um ambiente específico usando \newenvcommand{shaded}{\ul}[1], tudo para de funcionar.


EDIT: Esqueci de incluir algum código

  1. Então, aparentemente, esqueci de mencionar até que ponto quero esse sublinhado:
\renewcommand{\ULdepth}{1.8pt}
\contourlength{0.8pt}
  1. E esqueci de mencionar que estou usando os pacotes framedand colortambém:
\usepackage{framed,color}

\definecolor{shadecolor}{rgb}{.827451,.827451,.827451}
  1. Talvez valha a pena mencionar isso também:
\makeatletter

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

\makeatother

Todas essas edições foram adicionadas ao código acima. Desculpe pela inconveniência.

Responder1

Não é uma resposta, é mais um comentário com uma foto:

O definido localmente \ulnão é mais \relaxeditado ao copiar e colar o código expl3 de @egreg deDefinindo comandos com escopo para um ambiente específicoexatamente, o que dá este resultado (fora do ambiente = vermelho; dentro do ambiente = azul):

testar sublinhado com contorno

MWE

\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}

Ainda não vejo por que isso contourseria necessário, ou como isso poderia ter efeito, já que o halo do contorno não chega nem perto o suficiente para afetar a linha. Mas isso não está relacionado.

o código do egreg é sempre interessante.


Editado para adicionar:

Ah, acho que descobri por que as circunstâncias de fundo da pergunta parecem tão bizarras para mim: é porque o ulempacote por padrão faz isso (o que é perfeitamente aceitável):

padrão do ulem

E há dois parâmetros controlando a linha – espessura, via \ULthickness:

espessura de ulem uline

e profundidade, via \ULdepth:

profundidade de ulem uline

A documentação diz que o valor padrão \ULdepthé \maxdimen, que muda com a fonte. Portanto, se algo estiver (re)definindo \maxdimenpara um valor pequeno ou zero (ou nenhum valor) e/ou a configuração \ULdepthnão for uma ação disponível para empurrar o sublinhado novamente para baixo (por exemplo, o comando está sendo \relaxeditado por algo mais importante ( e, ainda, não especificado)), então o sublinhado passará pelos descendentes, conforme descrito nos comentários. Então, por sua vez, se uma ulemsolução não alternativa estiver sendo procurada, chegaremos a como contourela pode entrar no quadro (na verdade, há perguntas/respostas antigas sobre o assunto).

Simples (se foi isso que aconteceu).

Achei que talvez pudesse ter uma versão diferente do ulem, mas, como a última atualização foi em 2011, isso parece improvável.

Como opção logística, minha inclinação seria começar ulemprimeiro, em vez de cooptar outro(s) pacote(s), simplesmente por causa das dependências implícitas incorporadas na manutenção da solução por esse segundo método. No entanto, essa é uma questão diferente e não relacionada.


Editar 2:

Contoure ulemfunciona perfeitamente bem com as diferentes cores:

sem os ambientes

Se você quiser usar o código do egreg para definir o escopo de comandos dentro de ambientes, há três coisas a fazer: (1) verificar se há erros de digitação que possam ter surgido ao copiar de 'over', onde quer que 'over' esteja - por exemplo, quantos ds existem nos nomes?; (2) usar egreg'scódigo, conforme a pergunta vinculada, é uma boa fonte; e (3) na verdadeusaro código - definir algo é apenas o primeiro passo.

A maneira como você codificou mostra que o que \ulvocê está usando no shadedambiente é:

não aquele

não aquele que você pretende.

Dica: identifique o ambiente que realmente está usando o \checkenvcommandscomando.

A maneira mais fácil é copiar o código do egreg da pergunta vinculada, definir seu ambiente que usa esse código e, em seguida, o \ulescopo será definido para esse ambiente. Depois de fazer todas essas alterações, o resultado é:

ambiente de código egreg

MWE:

\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}

Se você deseja redefinir o ambiente frameddo pacote shaded, essa deve ser uma questão separada.

=====

Editar

Para referência, etoolboxo pacote fornece uma maneira de corrigir ambientes existentes, portanto o código é simplificado para:

MWE

\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}

Não relacionado: se o tempo for levado em consideração, então o código compilável que ilustra o problema (um MWE) provavelmente gerará uma resposta mais cedo, no intervalo de 6 minutos a 6 horas (P> 0,90), em vez do intervalo de 6 dias a 6 semanas (P<0,10) - ou nunca - que um conjunto cheio de bugs de trechos de código aleatórios jamais faria.

No entanto, como eu havia descoberto anteriormente (lentamente) como corrigir contourpara executar no modo de estrutura de tópicos no xelatex (na verdade, passando literais PDF para a saída por meio do \specialcomando do xdvipdfmx), o interesse em como contourestava sendo aplicado aqui levou a uma grande quantidade de aprendizagem e conhecimento, precisamente por causa de "um conjunto cheio de bugs de trechos de código aleatórios".

informação relacionada