I wonder why the media9 package, a new replacement for movie15, needs babel? And what will happen if I would want to load polyglossia instead of babel as it is required for XeLaTeX to compile Russian text (note that standard babel conflicts with XeLaTeX if Russian language is requested)?

NB: Fortunately, there is a custom russification for babel (http://ctan.org/pkg/russian) which does not conflict with XeLaTeX--I am just curious.

  • The package uses \defineshorthand; I believe it can easily dispense with it. – egreg Apr 4 '12 at 14:06
  • @egreg: Indeed, media9 uses \defineshorthand. Could we replace it with something home-made? – AlexG Apr 4 '12 at 14:28

In media9, the command \defineshorthand, defined in babel, is used in order to correctly treat possibly active characters that may occur in URLs and path specifications passed to \includemedia.

Some characters frequently encountered in URLs, such as : and ~ have a special meaning in a standard LaTeX environment or get the same, if a certain language package is loaded with babel. However, URLs and paths containing such characters must be inserted verbatim into certain PDF objects related to media inclusion.

As an example, one of the characters \usepackage[french]{babel} makes active is :. In file frenchb.ldf, : is redefined as


In order to prevent \includemedia from inserting rubbish into the PDF, it temporarily redefines it as a simple letter:


which is undone, as soon as command \includemedia has completed.

I am not happy with media9 depending on babel. I prefer a stand-alone solution. Maybe someone capable can help?

  • Formal answer to my question as it was formulated is given by Alexander Grahn, so I am going to accept his answer. But I also want the package media9 to be improved so I am postponing formal approval for not to disturb fruitful discussion. – Igor Kotelnikov Apr 5 '12 at 6:55
  • Next release (to appear after Easter) won't depend on babel any longer, thanks to @egreg! – AlexG Apr 5 '12 at 15:33

It seems that media9 requires babel just to have available \defineshorthand, which is used in the macro \mix@uribegin, which has several lines such as


which is meant to say: if " is active, redefine it to \detokenize{"}. The same effect may be obtained by using a helper macro:


and changing the line above into


If an active " is found, it will be changed into a detokenized ".

In LaTeX3 parlance this might be

\char_set_catcode_active:N \~
\cs_new:Npn \mix_neutralize_active_char:n #1
   \char_set_lccode:nn { `~ }{ `#1 }
   \tl_to_lowercase:n { \group_end: \cs_set:Npn ~ }{\token_to_str:N #1}
\cs_new:Npn \mix_uribegin:
   \mix_neutralize_active_char:n {"}
   \mix_neutralize_active_char:n {:}
   \mix_neutralize_active_char:n {/}
   \mix_neutralize_active_char:n {?}
   \mix_neutralize_active_char:n {[}
   \mix_neutralize_active_char:n {]}
   \mix_neutralize_active_char:n {@}
   \mix_neutralize_active_char:n {!}
   \mix_neutralize_active_char:n {$}
   \mix_neutralize_active_char:n {&}
   \mix_neutralize_active_char:n {'}
   \mix_neutralize_active_char:n {(}
   \mix_neutralize_active_char:n {)}
   \mix_neutralize_active_char:n {*}
   \mix_neutralize_active_char:n {+}
   \mix_neutralize_active_char:n {,}
   \mix_neutralize_active_char:n {;}
   \mix_neutralize_active_char:n {=}
   \mix_neutralize_active_char:n {-}
   \mix_neutralize_active_char:n {.}
   \mix_neutralize_active_char:n {_}
   \mix_neutralize_active_char:n {~}
   \cs_set:Npn \% {\token_to_str:N \%}
   \cs_set:Npn \# {\token_to_str:N \#}
\cs_set_eq:NN \mix_uriend: \group_end:

This should replace the definitions of \mix@uribegin and \mix@uriend; where these appear, they must be replaced by \mix_uribegin: and \mix_uriend:


Following Joseph Wright's suggestion, here's a shorter definition:

\char_set_catcode_active:N \~
\cs_new:Npn \mix_uribegin:
   \tl_map_inline:nn {":/?[]@!$&'()*+,=-._~}
      \char_set_lccode:nn { `\~ }{ `##1 }
      \tl_to_lowercase:n { \group_end: \cs_set:Npn ~ }{\token_to_str:N ##1}
   \cs_set:Npn \% {\token_to_str:N \%}
   \cs_set:Npn \# {\token_to_str:N \#}
\cs_set_eq:NN \mix_uriend: \group_end:

The principle is exactly the same, but the code is at least more elegant.

  • Unfortunately it doesn't seem to work. In case of [french]{babel}, : is translated into penalty @M : in the pdf string. I inserted your LaTeX3 code snippet into media9.sty. – AlexG Apr 4 '12 at 15:25
  • @AlexanderGrahn I was expecting that not everything would work immediately. I'll try doing some tests. – egreg Apr 4 '12 at 15:27
  • @AlexanderGrahn If I define \NewDocumentCommand{\try}{m}{\mix_uribegin:#1\mix_uriend:} and then in a French setup I do \try{?:"} I get the expected result. I'll complete the code: the ... stood for "similar lines". – egreg Apr 4 '12 at 15:42
  • Thanks a lot! Your code works almost perfectly. Only ~ still doesn't work. Is it due to its special meaning if ExplSyntaxOn? The error is: ! Missing \endcsname inserted. <to be read again> \unhbox l.30 ]{}{":/?[]@!$&'()*+,;=-._~} – AlexG Apr 4 '12 at 19:51
  • @AlexanderGrahn I've moved the \group_end:, so that in all the definition of \mix_uribegin: the ~ is active. – egreg Apr 4 '12 at 20:38

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.