2

I'm currently writting a book in xelatex, and in the progress of creating a couple of highlight boxes, I've encountered a problem.

Some boxes have titles and some doesn't have, because of that, the icon of the box get misplaced.

I've tried using \ifx, but that didn't work.

Here is the MWE:

% !TEX encoding = UTF-8
% !TEX spellcheck = es_ES
\PassOptionsToPackage{x11names,table,usenames}{xcolor}
\documentclass[a4]{article}

\usepackage{lipsum}
\usepackage{tikz} % Para poder dibujar
\usetikzlibrary{calc,matrix,shapes,arrows,automata,positioning,graphs,arrows.meta,decorations.pathreplacing,svg.path,shapes.symbols,shadows,backgrounds}
\usepackage{fontawesome}
\usepackage[most]{tcolorbox}
\usepackage{fontspec}
\setmonofont{Iosevka}[Scale=0.9]
\usepackage{calc}
\usepackage{xcolor}

%----------------------------------------------------------------------------------------
% Highlight Boxes
%----------------------------------------------------------------------------------------
\newfontfamily\titleboxfont{Fira Sans} % Font
\newfontfamily\boxfont{Fira Sans Light} % Font

\tcbset{mybox/.style={
        enlarge top initially by=5mm,
        enlarge bottom finally by=5mm,
        fonttitle=\titleboxfont\bfseries,
        drop fuzzy shadow,
        height=3cm,
        height plus=10cm,
        enhanced,
        %    center,
        left=0pt,
        right=0pt,
        top=8pt,
        bottom=8pt,
        enlarge left by=0mm,
        boxsep=5pt,
        fontupper=\small\boxfont,
        arc=4pt,
        outer arc=4pt,
        leftupper=1.5cm,
        width=0.9\linewidth,
        title={#1}
    }
}

\colorlet{boxinfocolor}{blue}
\newtcolorbox{pinfobox}[1]{
    mybox=#1,
    colback=boxinfocolor!5!white,
    colframe=boxinfocolor!75!black,
    overlay={
%        \ifx #1\empty
%        \node[anchor=north west] at ([xshift=10pt,yshift=-0.65\baselineskip]frame.north west)
%        \else
        \node[anchor=north west] at ([xshift=10pt,yshift=-2.65\baselineskip]frame.north west)
%        \fi
        {{\color{boxinfocolor!75!black}\fontsize{10mm}{10mm}\selectfont\faInfoCircle}};
    }
}


\newenvironment{infobox}[1]{%
    \begin{figure}[htp]
        \begin{pinfobox}{#1}
        }
        {
        \end{pinfobox}
    \end{figure}
}


\begin{document}

    \begin{infobox}{Lipsum}
    \lipsum[1]
    \end{infobox}

    \begin{infobox}{}
    \lipsum[2]
    \end{infobox}

\end{document}

In the following picture you can see what is happening.

Highlight boxes

Thanks for your help.

5

Welcome to TeX.SE! Your test doesn't work because when #1 is empty, it becomes:

\ifx \empty
  \node[anchor=north west] ...

For TeX, this is exactly the same as:

\ifx\empty\node[anchor=north west] ...

Thus, TeX compares \empty to \node and the result is always false. What you wanted to do was probably something like this:

\def\tmp{#1}%
\ifx\tmp\empty
  〈something〉
\else
  〈something else〉
\fi

This works, you can use it. With this piece of code, the \tmp macro is defined with an empty replacement text if, and only if #1 is empty. Thus, comparing the meaning of \tmp with that of \empty makes sense. Here is another way to test whether #1 is empty and execute code depending on the outcome:

\if\relax\detokenize{#1}\relax
  〈something〉
\else
  〈something else〉
\fi

Apart from that, I:

  • added braces around #1 in mybox={#1} in case someone uses a #1 value that contains commas;

  • converted your title argument to an optional one defaulting to empty, and

  • removed a lot of unused things from your code. Please post a minimal example next time.

Here is the complete example:

\documentclass{article}
\usepackage{fontawesome}
\usepackage{tikz}
\usepackage[skins]{tcolorbox}
\usepackage{lipsum}            % only for demo code

\tcbset{
  mybox/.style={
    enhanced,
    enlarge top initially by=5mm,
    enlarge bottom finally by=5mm,
    fonttitle=\bfseries,
    drop fuzzy shadow,
    height=3cm,
    height plus=10cm,
    left=0pt,
    right=0pt,
    top=8pt,
    bottom=8pt,
    enlarge left by=0mm,
    boxsep=5pt,
    fontupper=\small,
    arc=4pt,
    outer arc=4pt,
    leftupper=1.5cm,
    width=0.9\linewidth,
    title={#1},
  }
}

\colorlet{boxinfocolor}{blue}

\newtcolorbox{pinfobox}[1][]{
  mybox={#1},
  colback=boxinfocolor!5!white,
  colframe=boxinfocolor!75!black,
  overlay={
    \if\relax\detokenize{#1}\relax
      \def\myFactor{0.9}  % <--- space token which doesn't matter
    \else
      \def\myFactor{2.65} % <--- ditto
    \fi
    \node[anchor=north west] at
      ([xshift=10pt, yshift=-\myFactor\baselineskip]frame.north west)
      {%
        \color{boxinfocolor!75!black}\fontsize{10mm}{10mm}\selectfont
        \faInfoCircle
      };
  }
}

\newenvironment{infobox}[1][]
  {\begin{figure}[htp]\begin{pinfobox}[#1]}
  {\end{pinfobox}\end{figure}}

\begin{document}

  \begin{infobox}[Lipsum]
    \lipsum[1]
  \end{infobox}

  \begin{infobox}[]
    \lipsum[2]
  \end{infobox}

  \begin{infobox}
    \lipsum[3]
  \end{infobox}

\end{document}

The aforementioned space tokens don't matter because they occur between TikZ statements—but feel free to add end-of-line percent signs if this makes you feel more comfortable. :-)

screenshot

1
  • Thanks @frougon. Sorry about my MWE (it wasn't M enough). I promise it will be better in my next question. :o) Jan 23 '20 at 11:56
4

The argument should be optional, in my opinion. You can get away more easily with xparse: a missing optional argument makes \IfNoValueTF return the “true path”

\documentclass[a4paper]{article}
\usepackage[x11names,table,usenames]{xcolor}
\usepackage{tikz} % Para poder dibujar
\usetikzlibrary{
  calc,matrix,shapes,arrows,automata,positioning,
  graphs,arrows.meta,decorations.pathreplacing,
  svg.path,shapes.symbols,shadows,backgrounds
}
\usepackage{fontawesome}
\usepackage[most]{tcolorbox}
\tcbuselibrary{xparse}

\usepackage{fontspec}
\usepackage{lipsum}


\setmonofont{Iosevka}[Scale=0.9]
\newfontfamily\titleboxfont{Fira Sans} % Font
\newfontfamily\boxfont{Fira Sans Light} % Font

%----------------------------------------------------------------------------------------
% Highlight Boxes
%----------------------------------------------------------------------------------------

\tcbset{
  pablobox/.style={
    enlarge top initially by=5mm,
    enlarge bottom finally by=5mm,
    fonttitle=\titleboxfont\bfseries,
    drop fuzzy shadow,
    height=3cm,
    height plus=10cm,
    enhanced,
    %center,
    left=0pt,
    right=0pt,
    top=8pt,
    bottom=8pt,
    enlarge left by=0mm,
    boxsep=5pt,
    fontupper=\small\boxfont,
    arc=4pt,
    outer arc=4pt,
    leftupper=1.5cm,
    width=0.9\linewidth,
    title={#1}
  },
}

\colorlet{boxinfocolor}{blue}

\NewTColorBox{pinfobox}{o}{
  IfNoValueTF={#1}{pablobox={}}{pablobox={#1}},
  overlay={
    \node[anchor=north west] at 
      ([xshift=10pt,yshift=-\IfValueTF{#1}{2}{0}.65\baselineskip]frame.north west)
      {\textcolor{boxinfocolor!75!black}{\fontsize{10mm}{0pt}\selectfont\faInfoCircle}};
  },
  colback=boxinfocolor!5!white,
  colframe=boxinfocolor!75!black,
}

\NewDocumentEnvironment{infobox}{}
 {\begin{figure}[htp]\begin{pinfobox}}
 {\end{pinfobox}\end{figure}}


\begin{document}

\begin{infobox}[Lipsum]
\lipsum[1]
\end{infobox}

\begin{infobox}
\lipsum[2]
\end{infobox}

\end{document}

enter image description here

1
  • Thanks @egreg. Your solution taught new concepts. I have never got into xparse before. Perhaps with this, I will give it a look. Jan 23 '20 at 11:58
2

Use the interior node and forget the problem with conditionals.

Look at geometry nodes in tcolorbox documentation. It explains that a tcolorbox defines four nodes: frame (title+box contents), interior (box contents), title and segmentation. Using interior as placement reference is a valid solution for boxes with o without title.

% !TEX encoding = UTF-8
% !TEX spellcheck = es_ES
\PassOptionsToPackage{x11names,table,usenames}{xcolor}
\documentclass[a4]{article}

\usepackage{lipsum}
\usepackage{tikz} % Para poder dibujar
\usetikzlibrary{calc,matrix,shapes,arrows,automata,positioning,graphs,arrows.meta,decorations.pathreplacing,svg.path,shapes.symbols,shadows,backgrounds}
\usepackage{fontawesome}
\usepackage[most]{tcolorbox}
%\usepackage{fontspec}
%\setmonofont{Iosevka}[Scale=0.9]
\usepackage{calc}
\usepackage{xcolor}

%----------------------------------------------------------------------------------------
% Highlight Boxes
%----------------------------------------------------------------------------------------
%\newfontfamily\titleboxfont{Fira Sans} % Font
%\newfontfamily\boxfont{Fira Sans Light} % Font

\tcbset{mybox/.style={
        enlarge top initially by=5mm,
        enlarge bottom finally by=5mm,
%        fonttitle=\titleboxfont\bfseries,
        drop fuzzy shadow,
        height=3cm,
        height plus=10cm,
        enhanced,
        %    center,
        left=0pt,
        right=0pt,
        top=8pt,
        bottom=8pt,
        enlarge left by=0mm,
        boxsep=5pt,
 %       fontupper=\small\boxfont,
        arc=4pt,
        outer arc=4pt,
        leftupper=1.5cm,
        width=0.9\linewidth,
        title={#1}
    }
}

\colorlet{boxinfocolor}{blue}
\newtcolorbox{pinfobox}[1]{
    mybox=#1,
    colback=boxinfocolor!5!white,
    colframe=boxinfocolor!75!black,
    overlay={
        \node[anchor=north west] at ([shift={(10pt,-10pt)}]interior.north west)
        {{\color{boxinfocolor!75!black}\fontsize{10mm}{10mm}\selectfont\faInfoCircle}};
    }
}


\newenvironment{infobox}[1]{%
    \begin{figure}[htp]
        \begin{pinfobox}{#1}
        }
        {
        \end{pinfobox}
    \end{figure}
}


\begin{document}

    \begin{infobox}{Lipsum}
    \lipsum[1]
    \end{infobox}

    \begin{infobox}{}
    \lipsum[2]
    \end{infobox}

\end{document}

enter image description here

enter image description here

1
  • As @egreg, your solution gave me a different approach. Something new to learn. Thanks! Jan 23 '20 at 11:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.