Redefinir el color del contorno (para subrayar)

Redefinir el color del contorno (para subrayar)

Estoy usando el siguiente código (tomado deeste sitiopor poner bonitos subrayados debajo de mi texto.

\usepackage{ulem}
\usepackage{contour}

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

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

Sin embargo, al subrayar dentro de shadedambientes (del framedpaquete), la blancura persiste alrededor de las letras. Para solucionar este problema, pensé en agregar esto debajo del código anterior:

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

Resulta que no funcionó; incluso hizo que el subrayado normal fuera de los shadedentornos dejara de funcionar por completo.

¿Cómo puedo tener dos valores de color diferentes \contoursin que entren en conflicto entre sí?

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}

Soy consciente de lo que está haciendo el comando. Sobre un whitefondo, creo un whiteborde alrededor de las letras para que el subrayado no las corte. Eso funciona bien. Pero en un shadedcolorcontexto quiero cambiar ese borde para que coincida con eso shadedcolor. Se trata de deshacerse de los feos cortes en las letras que van debajo del subrayado.

Es solo que cuando modifico ese comando para un entorno específico usando \newenvcommand{shaded}{\ul}[1], todo deja de funcionar.


EDITAR: Olvidé incluir algún código

  1. Aparentemente olvidé mencionar qué tan abajo/arriba quiero ese subrayado:
\renewcommand{\ULdepth}{1.8pt}
\contourlength{0.8pt}
  1. Y olvidé mencionar que también estoy usando los paquetes framedand :color
\usepackage{framed,color}

\definecolor{shadecolor}{rgb}{.827451,.827451,.827451}
  1. Quizás también valga la pena mencionar esto:
\makeatletter

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

\makeatother

Todas estas ediciones ahora se han agregado al código anterior. Lo siento por los inconvenientes ocasionados.

Respuesta1

No es una respuesta, más bien un comentario con una imagen:

Lo definido localmente \ulya no se \relaxmodifica al copiar y pegar el código expl3 de @egreg desdeDefinición de comandos cuyo ámbito es un entorno particularexactamente, lo que da este resultado (fuera del entorno = rojo; dentro del entorno = azul):

prueba de subrayado con 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}

Todavía no veo por qué contoursería necesario, o cómo podría tener un efecto, ya que el halo de contorno ni siquiera llega lo suficientemente lejos como para afectar la línea. Pero eso no tiene relación.

El código de egreg siempre es interesante.


Editado para agregar:

Ah, creo que he descubierto por qué las circunstancias de fondo de la pregunta me parecen tan extrañas: es porque el ulempaquete por defecto hace esto (lo cual está perfectamente bien):

defecto ulema

Y hay dos parámetros que controlan la línea: espesor, a través de \ULthickness:

espesor de la línea ulem

y profundidad, a través de \ULdepth:

ulem uline profundidad

La documentación dice que el valor predeterminado \ULdepthes \maxdimen, que cambia con la fuente. Entonces, si algo se (re)establece \maxdimenen un valor pequeño o cero (o ningún valor), y/o la configuración \ULdepthno es una acción disponible, vuelva a bajar el subrayado (por ejemplo, el comando está siendo \relaxmodificado por algo más importante ( y, hasta el momento, sin especificar)), entonces el subrayado pasará por los descendentes, como se describe en los comentarios. Luego, a su vez, si ulemse busca una solución alternativa, llegamos a cómo contourpodría entrar en escena (de hecho, hay viejas preguntas/respuestas al respecto).

Simple (si eso es lo que pasó).

Pensé que tal vez podría haber tenido una versión diferente de ulem, pero, dado que la última actualización fue en 2011, eso parece poco probable.

Como opción logística, mi inclinación sería comenzar con ulemel primero, en lugar de comenzar cooptando otro(s) paquete(s), simplemente debido a las dependencias implícitas que están integradas en el mantenimiento de la solución mediante ese segundo método. Sin embargo, esa es una pregunta diferente y no relacionada.


Editar 2:

Contoury ulemfunciona perfectamente bien con los diferentes colores:

sin los ambientes

Si desea utilizar el código de egreg para determinar el alcance de los comandos dentro de entornos, hay tres cosas que hacer: (1) verificar si hay errores tipográficos que puedan haberse introducido al copiar desde 'over', dondequiera que esté 'over', por ejemplo, cuántosd s hay en los nombres?; (2) utilizar egregcódigo, según la pregunta vinculada es una buena fuente; y (3) en realidadusarel código: definir algo es sólo el primer paso.

La forma en que ha codificado muestra que lo \ulque está utilizando en el shadedentorno es:

no es ese

no el que pretendes.

Sugerencia: identifique el entorno que realmente está utilizando el \checkenvcommandscomando.

La forma más sencilla es copiar el código de egreg de la pregunta vinculada, definir el entorno que utiliza ese código y luego \ullimitarlo a ese entorno. Una vez que hagas todos esos cambios, el resultado es:

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

Si desea redefinir el entorno frameddel paquete shaded, esa debería ser una pregunta aparte.

=====

Editar

Como referencia, etoolboxel paquete proporciona una manera de aplicar parches a los entornos existentes, por lo que el código se simplifica a:

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}

No relacionado: si se considera el tiempo, es más probable que el código compilable que ilustra el problema (un MWE) genere una respuesta antes, en el rango de 6 minutos a 6 horas (PAG> 0,90), en lugar del rango de 6 días a 6 semanas (PAG< 0.10) - o nunca - que un conjunto de fragmentos de código aleatorios con errores alguna vez lo haría.

Sin embargo, dado que antes (lentamente) había descubierto cómo parchear contourpara ejecutar en modo esquema bajo xelatex (de hecho, pasando literales de pdf a la salida mediante el comando de xdvipdfmx \special), el interés en cómo contourse estaba aplicando aquí me ha llevado a una gran cantidad de aprendizaje y conocimiento, precisamente debido a "un conjunto de fragmentos de código aleatorios con errores".

información relacionada