% -------------------------------------------------------------------------- % the EMBRAC package % % Upright Brackets in Emphasized Text % % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://bitbucket.org/cgnieder/embrac/ % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2012 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- % The embrac package consists of the files % - embrac.sty, embrac_en.tex, embrac_en.pdf, embrac_kerning_test.tex and % README % -------------------------------------------------------------------------- % > this package is strongly based on an article by Dominik Waßenhoven in % > “Die TeXnische Komödie” 2 (2012), pp. 51--53 % > which introduces code by Bruno Le Floch. Code parts and idea used with % > their kind permission. Many thanks! % -------------------------------------------------------------------------- \RequirePackage { expl3 , xparse , l3keys2e } \ProvidesExplPackage {embrac} {2012/11/04} {0.2} {Upright Brackets in Emphasized Text} \bool_new:N \l__embrac_treat_biblatex_bool \tl_new:N \l__embrac_tmpa_tl \tl_new:N \l__embrac_treat_biblatex_tl \keys_define:nn { embrac } { biblatex .choice: , biblatex / true .code:n = \bool_set_true:N \l__embrac_treat_biblatex_bool , biblatex / on .code:n = \bool_set_true:N \l__embrac_treat_biblatex_bool , biblatex / parens .code:n = \bool_set_true:N \l__embrac_treat_biblatex_bool , biblatex / false .code:n = \bool_set_false:N \l__embrac_treat_biblatex_bool , biblatex / off .code:n = \bool_set_false:N \l__embrac_treat_biblatex_bool , biblatex / none .code:n = \bool_set_false:N \l__embrac_treat_biblatex_bool , biblatex .default:n = true } % save original commands: \cs_new_eq:Nc \__embrac_orig_emph:n { emph~ } \cs_generate_variant:Nn \__embrac_orig_emph:n { V } \cs_new_eq:Nc \__embrac_orig_textit:n { textit~ } \cs_generate_variant:Nn \__embrac_orig_textit:n { V } % preparations: \cs_new_eq:NN \embrac_braces_format:n \textup \cs_new_eq:NN \__embrac_kern:n \skip_horizontal:n \cs_new:Npn \__embrac_empty_or_no_value:nTF #1#2#3 { \IfNoValueTF { #1 } { #2 } { \tl_if_blank:nTF { #1 } { #2 } { #3 } } } \cs_new:Npn \__embrac_empty_or_no_value:nF #1#2 { \IfNoValueF { #1 } { \tl_if_blank:nF { #1 } { #2 } } } % -------------------------------------------------------------------------- % THE MAIN PART: % storage of the tokens to be replaced: \prop_new:N \l__embrac_emph_obrackets_prop \prop_new:N \l__embrac_emph_obrackets_before_prop \prop_new:N \l__embrac_emph_cbrackets_prop \prop_new:N \l__embrac_emph_cbrackets_after_prop % do the replacing: \cs_new:Npn \__embrac_replace_brackets:N #1 { \prop_map_inline:Nn \l__embrac_emph_obrackets_prop { \tl_replace_all:Nnn #1 { ##1 } { \__embrac_kern:n { \prop_get:Nn \l__embrac_emph_obrackets_before_prop { ##1 } } \embrac_braces_format:n { ##1 \__embrac_kern:n { ##2 } } \nobreak } } \prop_map_inline:Nn \l__embrac_emph_cbrackets_prop { \tl_replace_all:Nnn #1 { ##1 } { \nobreak \embrac_braces_format:n { \__embrac_kern:n { ##2 } ##1 } \__embrac_kern:n { \prop_get:Nn \l__embrac_emph_cbrackets_after_prop { ##1 } } } } } % internal \emph command: \cs_new:Npn \__embrac_emph:n #1 { \tl_set:Nx \l__embrac_tmpa_tl { #1 } \__embrac_replace_brackets:N \l__embrac_tmpa_tl \__embrac_orig_emph:V \l__embrac_tmpa_tl } % internal \textit command: \cs_new:Npn \__embrac_textit:n #1 { \tl_set:Nn \l__embrac_tmpa_tl { #1 } \__embrac_replace_brackets:N \l__embrac_tmpa_tl \__embrac_orig_textit:V \l__embrac_tmpa_tl } % biblatex compatibility: \cs_new:Npn \__embrac_treat_bibparens: { \bool_if:NT \l__embrac_treat_biblatex_bool { \__embrac_replace_brackets:N \bibleftbracket \__embrac_replace_brackets:N \bibrightbracket \__embrac_replace_brackets:N \bibleftparen \__embrac_replace_brackets:N \bibrightparen } } \cs_new:Npn \__embrac_treat_bibemph: { \bool_if:NT \l__embrac_treat_biblatex_bool { \patchcmd[\protected\long]\blx@imc@mkbibemph {\emph}{\emph*} {}{} } } % internal \emph command, second layer: \cs_new_protected:Npn \__embrac_new_emph:w #1#2 { \group_begin: \__embrac_treat_bibparens: \IfBooleanTF { #1 } { \__embrac_orig_emph:n { #2 } } { \__embrac_emph:n { #2 } } \group_end: } % internal \textit command, second layer: \cs_new_protected:Npn \__embrac_new_textit:w #1#2 { \group_begin: \__embrac_treat_bibparens: \IfBooleanTF { #1 } { \__embrac_orig_textit:n { #2 } } { \__embrac_textit:n { #2 } } \group_end: } % user command \emph: \RenewDocumentCommand \emph { sm } { \__embrac_new_emph:w #1 { #2 } } % user command \textit: \RenewDocumentCommand \textit { sm } { \__embrac_new_textit:w #1 { #2 } } % -------------------------------------------------------------------------- % TURNING EMBRAC OFF AND ON: % turning embrac off: \NewDocumentCommand \EmbracOff {} { \RenewDocumentCommand \emph { sm } { \__embrac_orig_emph:n { ##2 } } \RenewDocumentCommand \textit { sm } { \__embrac_orig_textit:n { ##2 } } } % turning embrac on: \NewDocumentCommand \EmbracOn {} { \RenewDocumentCommand \emph { sm } { \__embrac_new_emph:w ##1 { ##2 } } \RenewDocumentCommand \textit { sm } { \__embrac_new_textit:w ##1 { ##2 } } } % -------------------------------------------------------------------------- % ADDING AND REMOVING BRACKETS: % internal add command: \cs_new:Npn \__embrac_add_to_emph:nnnnnn #1#2#3#4#5#6 { \__embrac_empty_or_no_value:nTF { #2 } { \prop_put_if_new:Nnn \l__embrac_emph_obrackets_prop { #1 } { 0pt } } { \prop_put_if_new:Nnn \l__embrac_emph_obrackets_prop { #1 } { #2 } } \__embrac_empty_or_no_value:nTF { #3 } { \prop_put_if_new:Nnn \l__embrac_emph_obrackets_before_prop { #1 } { 0pt } } { \prop_put_if_new:Nnn \l__embrac_emph_obrackets_before_prop { #1 } { #3 } } \__embrac_empty_or_no_value:nTF { #5 } { \prop_put_if_new:Nnn \l__embrac_emph_cbrackets_prop { #4 } { 0pt } } { \prop_put_if_new:Nnn \l__embrac_emph_cbrackets_prop { #4 } { #5 } } \__embrac_empty_or_no_value:nTF { #6 } { \prop_put_if_new:Nnn \l__embrac_emph_cbrackets_after_prop { #4 } { 0pt } } { \prop_put_if_new:Nnn \l__embrac_emph_cbrackets_after_prop { #4 } { #6 } } } % internal delete command: \cs_new:Npn \__embrac_remove_from_emph:nn #1#2 { \prop_del:Nn \l__embrac_emph_obrackets_prop { #1 } \prop_del:Nn \l__embrac_emph_obrackets_before_prop { #1 } \prop_del:Nn \l__embrac_emph_cbrackets_prop { #2 } \prop_del:Nn \l__embrac_emph_cbrackets_after_prop { #2 } } % internal renew command: \cs_new:Npn \__embrac_renew_emph:nnnnnn #1#2#3#4#5#6 { \__embrac_empty_or_no_value:nTF { #2 } { \prop_put:Nnn \l__embrac_emph_obrackets_prop { #1 } { 0pt } } { \prop_put:Nnn \l__embrac_emph_obrackets_prop { #1 } { #2 } } \__embrac_empty_or_no_value:nTF { #3 } { \prop_put:Nnn \l__embrac_emph_obrackets_before_prop { #1 } { 0pt } } { \prop_put:Nnn \l__embrac_emph_obrackets_before_prop { #1 } { #3 } } \__embrac_empty_or_no_value:nTF { #5 } { \prop_put:Nnn \l__embrac_emph_cbrackets_prop { #4 } { 0pt } } { \prop_put:Nnn \l__embrac_emph_cbrackets_prop { #4 } { #5 } } \__embrac_empty_or_no_value:nTF { #6 } { \prop_put:Nnn \l__embrac_emph_cbrackets_after_prop { #4 } { 0pt } } { \prop_put:Nnn \l__embrac_emph_cbrackets_after_prop { #4 } { #6 } } } % internal change command: \cs_new:Npn \__embrac_change_emph:nnnnnn #1#2#3#4#5#6 { \prop_if_in:NnT \l__embrac_emph_obrackets_prop { #1 } { \__embrac_empty_or_no_value:nF { #2 } { \prop_put:Nnn \l__embrac_emph_obrackets_prop { #1 } { #2 } } \__embrac_empty_or_no_value:nF { #3 } { \prop_put:Nnn \l__embrac_emph_obrackets_before_prop { #1 } { #3 } } } \prop_if_in:NnT \l__embrac_emph_cbrackets_prop { #4 } { \__embrac_empty_or_no_value:nF { #5 } { \prop_put:Nnn \l__embrac_emph_cbrackets_prop { #4 } { #5 } } \__embrac_empty_or_no_value:nF { #6 } { \prop_put:Nnn \l__embrac_emph_cbrackets_after_prop { #4 } { #6 } } } } % user commands: \NewDocumentCommand \AddEmph { m > { \SplitArgument { 1 } { , } } O{,} m > { \SplitArgument { 1 } { , } } O{,} } { \__embrac_add_to_emph:nnnnnn { #1 } #2 { #3 } #4 \ignorespaces } \NewDocumentCommand \DeleteEmph { mm } { \__embrac_remove_from_emph:nn { #1 } { #2 } \ignorespaces } \NewDocumentCommand \RenewEmph { m > { \SplitArgument { 1 } { , } } O{,} m > { \SplitArgument { 1 } { , } } O{,} } { \__embrac_renew_emph:nnnnnn { #1 } #2 { #3 } #4 \ignorespaces } \NewDocumentCommand \ChangeEmph { m > { \SplitArgument { 1 } { , } } O{,} m > { \SplitArgument { 1 } { , } } O{,} } { \__embrac_change_emph:nnnnnn { #1 } #2 { #3 } #4 \ignorespaces } % add some defaults: \AddEmph{[}{]}[.04em,-.12em] \AddEmph{(}[-.04em]{)}[,-.15em] \ProcessKeysOptions { embrac } \AtBeginDocument { \__embrac_treat_bibemph: } \tex_endinput:D % HISTORY 2012/06/29 - v0.1 - first public release 2012/06/29 - v0.1a - renamed \RenewEmph => \ChangeEmph and added new \RenewEmph 2012/07/24 - v0.1b - adapted to deprecated functions in l3kernel and l3packages 2012/11/04 - v0.2 - extended `biblatex' option: parens/full - changed buggy definition of \EmbracOff and \EmbracOn