Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Just after there is one code which has been proposed to me in this site.

Instead of using \begin{MyFrame}[1.5cm][2pt][1.3cm][blue][2][8ex], I would like to use something more friendly like \begin{MyFrame}[lenght = 1.5cm , thickness = 2pt , distH = 1.3cm , color = blue, factor = 2 , distV = 8ex].

If it is possible, how can I do that ?

% Source : http://tex.stackexchange.com/questions/33078/frame-with-only-crosses-in-two-opposite-corners/33087#33087

\documentclass{article}
    \usepackage{xparse}
    \usepackage{xcolor}

% Meaning of the variables
%    #1 --> Length : this controls the length of the rules used (default = 1cm)
%    #2 --> Thickness of the rule (default = 0.4pt)
%    #3 --> Horizontal distance between the rules and the text (default = 0.8cm)
%    #4 --> Color of the rule using the xcolor package (default = black)
%    #5 --> Factor is a number controlling the point of intersection of each pair
%           of rules used for the cross (default = 3)
%    #6 --> Vertical distance between the rules and the text (default = 2ex)
    \DeclareDocumentEnvironment{MyFrame}{O{1cm}O{0.4pt}O{0.8cm}O{black}O{3}O{2ex}}
    {%
        \par\hfill\rlap{%
            \bgroup\color{#4}%
            \hskip-\dimexpr#1-#3\relax\rule{#1}{#2}%
            \hskip-\dimexpr#1/#5\relax\rule[-\dimexpr#1-\dimexpr#1/#5\relax]{#2}{#1}%
            \egroup
        }%
        \vskip-\dimexpr#1/#5+\dimexpr#1/#5-#6\relax%
    }
    {%
        \par\nobreak\offinterlineskip\vskip-\dimexpr#1/#5+\dimexpr#1/#5-#6\relax\noindent%
        \hskip-#3\bgroup\color{#4}%
        \rule{#1}{#2}\hskip-\dimexpr#1-\dimexpr#1/#5-#2\relax%
        \rule[-\dimexpr#1/#5-#2\relax]{#2}{#1}\egroup\par
    }

% Just to generate text for the example.
    \usepackage{lipsum}


\begin{document}

\begin{MyFrame}[1.5cm][2pt][1.3cm][blue][6][8ex]
    \lipsum[1]
\end{MyFrame}

\end{document}
share|improve this question
    
A package like xkeyval will do what you want, I imagine. –  Seamus Oct 30 '11 at 11:06
add comment

3 Answers

up vote 7 down vote accepted

A complete translation using keyval

\documentclass{article}
\usepackage{keyval}
\usepackage{xcolor}

\makeatletter
\define@key{myframe}{length}{\def\mf@length{#1}}
\define@key{myframe}{thickness}{\def\mf@thickness{#1}}
\define@key{myframe}{Hdist}{\def\mf@Hdist{#1}}
\define@key{myframe}{Vdist}{\def\mf@Vdist{#1}}
\define@key{myframe}{color}{\def\mf@color{#1}}
\define@key{myframe}{factor}{\def\mf@factor{#1}}
%% set defaults (not Vdist, which depends on current conditions)
\setkeys{myframe}{length=1cm,thickness=0.4pt,Hdist=.8cm,factor=3,color=black}

\newenvironment{MyFrame}[1][]
  {\setkeys{myframe}{Vdist=2ex,#1}%
   \par\hfill\rlap{%
     \bgroup\color{\mf@color}%
     \hskip-\dimexpr\mf@length-\mf@Hdist\relax
     \rule{\mf@length}{\mf@thickness}%
     \hskip-\dimexpr\mf@length/\mf@factor\relax
     \rule[-\dimexpr\mf@length-\dimexpr\mf@length/\mf@factor\relax]{\mf@thickness}{\mf@length}%
     \egroup
   }%
   \vskip-\dimexpr\mf@length/\mf@factor+\dimexpr\mf@length/\mf@factor-\mf@Vdist\relax
   }
   {%
    \par\nobreak\offinterlineskip
    \vskip-\dimexpr\mf@length/\mf@factor+\dimexpr\mf@length/\mf@factor-\mf@Vdist\relax
    \noindent
    \hskip-\mf@Hdist\bgroup\color{\mf@color}%
    \rule{\mf@length}{\mf@thickness}\hskip-\dimexpr\mf@length-
                                    \dimexpr\mf@length/\mf@factor-\mf@thickness\relax
    \rule[-\dimexpr\mf@length/\mf@factor-\mf@thickness\relax]{\mf@thickness}{\mf@length}
    \egroup\par
    }
\makeatother

% Just to generate text for the example.
    \usepackage{lipsum}


\begin{document}

\begin{MyFrame}[length=1.5cm,thickness=2pt,Hdist=1.3cm,color=blue,factor=6,Vdist=8ex]
    \lipsum[1]
\end{MyFrame}

\end{document}

Here is a document example:

\documentclass{article}
\usepackage{keyval}
\usepackage{xcolor}
\usepackage[margin=2cm]{geometry}
\pagestyle{empty}
\makeatletter
\define@key{myframe}{length}{\def\mf@length{#1}}
\define@key{myframe}{thickness}{\def\mf@thickness{#1}}
\define@key{myframe}{Hdist}{\def\mf@Hdist{#1}}
\define@key{myframe}{Vdist}{\def\mf@Vdist{#1}}
\define@key{myframe}{color}{\def\mf@color{#1}}
\define@key{myframe}{factor}{\def\mf@factor{#1}}
%% set defaults (not Vdist, which depends on current conditions)
\setkeys{myframe}{length=1cm,thickness=0.4pt,Hdist=.8cm,factor=3,color=black}

\newenvironment{MyFrame}[1][]
  {\setkeys{myframe}{Vdist=2ex,#1}%
   \par\hfill\rlap{%
     \bgroup\color{\mf@color}%
     \hskip-\dimexpr\mf@length-\mf@Hdist\relax
     \rule{\mf@length}{\mf@thickness}%
     \hskip-\dimexpr\mf@length/\mf@factor\relax
     \rule[-\dimexpr\mf@length-\dimexpr\mf@length/\mf@factor\relax]{\mf@thickness}{\mf@length}%
     \egroup
   }%
   \vskip-\dimexpr\mf@length/\mf@factor+\dimexpr\mf@length/\mf@factor-\mf@Vdist\relax
   }
   {%
    \par\nobreak\offinterlineskip
    \vskip-\dimexpr\mf@length/\mf@factor+\dimexpr\mf@length/\mf@factor-\mf@Vdist\relax
    \noindent
    \hskip-\mf@Hdist\bgroup\color{\mf@color}%
    \rule{\mf@length}{\mf@thickness}\hskip-\dimexpr\mf@length-
                                    \dimexpr\mf@length/\mf@factor-\mf@thickness\relax
    \rule[-\dimexpr\mf@length/\mf@factor-\mf@thickness\relax]{\mf@thickness}{\mf@length}
    \egroup\par
    }
\makeatother

% Just to generate text for the example.
    \usepackage{lipsum}


\begin{document}
\small

\begin{MyFrame}[length=1.5cm,thickness=2pt,Hdist=1.3cm,color=blue,factor=4,Vdist=8ex]
    \lipsum[2]
\end{MyFrame}

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

\begin{MyFrame}[length=3cm,thickness=4pt,Hdist=1.5cm,color=red!60]
\lipsum[2]
\end{MyFrame}

\begin{MyFrame}[length=1.5cm,thickness=2pt,Hdist=1.3cm,color=blue,factor=2,Vdist=8ex]
\lipsum[2]
\end{MyFrame}

\begin{MyFrame}[length=1cm,thickness=7pt,Hdist=0.6cm,color=olive!60,factor=4,Vdist=0ex]
\lipsum[2]
\end{MyFrame}

\end{document}

enter image description here

share|improve this answer
    
Thanks, I'm happy to have learned one new thing... –  projetmbc Oct 30 '11 at 12:26
    
Run your code, the blue cross is't at the right place,how to solve it? thx. –  Pig Cry Oct 30 '11 at 15:22
    
@PigCry What do you mean? –  egreg Oct 30 '11 at 15:31
    
@egreg the upper right blue cross is in the middle position of the page. –  Pig Cry Oct 30 '11 at 15:47
    
@PigCry See image –  egreg Oct 30 '11 at 16:14
show 2 more comments

Another solution based on pgfkeys (slightly more verbose).

\documentclass{article}
\usepackage{xcolor}
\usepackage{pgfkeys}

\pgfkeys{%
  /MyFrame/.is family,
  /MyFrame/length/.initial = {1cm},
  /MyFrame/thickness/.initial = {0.4pt},
  /MyFrame/Hdist/.initial = {0.8cm},
  /MyFrame/color/.initial = {black},
  /MyFrame/factor/.initial = {3},
  /MyFrame/Vdist/.initial = {2ex}}  

% To make sure the environment is definable
\newenvironment{MyFrame}{}{}

\makeatletter
\def\MyFrame{%
  \@ifnextchar[{\MyFrame@i}{\MyFrame@i[]}}%]
\def\MyFrame@i[#1]{%
  \bgroup
  \pgfkeys{MyFrame/.cd,Vdist=2ex,#1}%
  \par\hfill\rlap{%
    \bgroup\color{\pgfkeysvalueof{/MyFrame/color}}%
    \hskip-\dimexpr\pgfkeysvalueof{/MyFrame/length} - 
      \pgfkeysvalueof{/MyFrame/Hdist}\relax
    \rule{\pgfkeysvalueof{/MyFrame/length}}{%
      \pgfkeysvalueof{/MyFrame/thickness}}%
    \hskip-\dimexpr\pgfkeysvalueof{/MyFrame/length} / 
      \pgfkeysvalueof{/MyFrame/factor}\relax
    \rule[-\dimexpr\pgfkeysvalueof{/MyFrame/length} - 
      \dimexpr\pgfkeysvalueof{/MyFrame/length} / 
      \pgfkeysvalueof{/MyFrame/factor}\relax]{%
        \pgfkeysvalueof{/MyFrame/thickness}}{%
        \pgfkeysvalueof{/MyFrame/length}}%
    \egroup
  }%
  \vskip-\dimexpr\pgfkeysvalueof{/MyFrame/length} / 
    \pgfkeysvalueof{/MyFrame/factor} + 
    \dimexpr\pgfkeysvalueof{/MyFrame/length} / 
    \pgfkeysvalueof{/MyFrame/factor} - 
    \pgfkeysvalueof{/MyFrame/Vdist}\relax}

\def\endMyFrame{%
  \par\nobreak\offinterlineskip
  \vskip-\dimexpr\pgfkeysvalueof{/MyFrame/length} / 
  \pgfkeysvalueof{/MyFrame/factor} + 
  \dimexpr\pgfkeysvalueof{/MyFrame/length} / 
  \pgfkeysvalueof{/MyFrame/factor} - 
  \pgfkeysvalueof{/MyFrame/Vdist}\relax\noindent%
  \hskip-\pgfkeysvalueof{/MyFrame/Hdist}%
  \bgroup
    \color{\pgfkeysvalueof{/MyFrame/color}}%
    \rule{\pgfkeysvalueof{/MyFrame/length}}{%
      \pgfkeysvalueof{/MyFrame/thickness}}
    \hskip-\dimexpr\pgfkeysvalueof{/MyFrame/length} - 
    \dimexpr\pgfkeysvalueof{/MyFrame/length} / 
    \pgfkeysvalueof{/MyFrame/factor} - 
    \pgfkeysvalueof{/MyFrame/thickness}\relax%
    \rule[-\dimexpr\pgfkeysvalueof{/MyFrame/length} / 
    \pgfkeysvalueof{/MyFrame/factor} - 
    \pgfkeysvalueof{/MyFrame/thickness}\relax]{%
      \pgfkeysvalueof{/MyFrame/thickness}}{%
      \pgfkeysvalueof{/MyFrame/length}}
  \egroup
\egroup\par}

\makeatother

\usepackage{lipsum}

\begin{document}

\begin{MyFrame}
    \lipsum[1]
\end{MyFrame}

\begin{MyFrame}[length=1.5cm,thickness=2pt,Hdist=1.3cm,
  color=blue,factor=6,Vdist=8ex]
    \lipsum[1]
\end{MyFrame}

\end{document}
share|improve this answer
add comment

Use a key/value package like xkeyval, then define all your keys you want. They will get the value as #1:

\usepackage{xkeyval}
\makeatletter% not required in a package or class
\newlength\myframelength

\define@key{MyFrame}{length}{%
   \setlength{\myframelength}{#1}%
}
\define@key{MyFrame}{foobar}[default]{%
   \dosomething{#1}%
}
\makeatother

\newenvironment{MyFrame}[1][]{%
    \setkeys{MyFrame}{#1}% execute keys
    % ...
}{%
    % ...
}

% usage:
\begin{MyFrame}
  foo bar
\end{MyFrame}

\begin{MyFrame}[length=1pt]
  foo bar
\end{MyFrame}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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