7

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.

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

2 Answers 2

5

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

\initiate@active@char{:}%
\declare@shorthand{french}{:}{%
      \ifhmode
        \ifdim\lastskip>\z@
          \unskip\penalty\@M\Fcolonspace
        \else
          \FDP@colonspace
        \fi
      \fi
      \string:}

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

\defineshorthand{:}{\detokenize{:}}

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?

2
  • 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. Apr 5, 2012 at 6:55
  • Next release (to appear after Easter) won't depend on babel any longer, thanks to @egreg!
    – AlexG
    Apr 5, 2012 at 15:33
7

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

\defineshorthand{"}{\detokenize{"}}%

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

\def\neutralize#1{%
  \begingroup\lccode`~=`#1\lowercase{\endgroup\def~}{\detokenize{#1}}}

and changing the line above into

\neutralize{"}

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

In LaTeX3 parlance this might be

\group_begin:
\char_set_catcode_active:N \~
\cs_new:Npn \mix_neutralize_active_char:n #1
  {
   \group_begin:
   \char_set_lccode:nn { `~ }{ `#1 }
   \tl_to_lowercase:n { \group_end: \cs_set:Npn ~ }{\token_to_str:N #1}
  }
\cs_new:Npn \mix_uribegin:
  {
   \group_begin:
   \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 \#}
  }
\group_end:
\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:

EDIT

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

\group_begin:
\char_set_catcode_active:N \~
\cs_new:Npn \mix_uribegin:
  {
   \group_begin:
   \tl_map_inline:nn {":/?[]@!$&'()*+,=-._~}
     {
      \group_begin:
      \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 \#}
  }
\group_end:
\cs_set_eq:NN \mix_uriend: \group_end:

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

10
  • 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, 2012 at 15:25
  • @AlexanderGrahn I was expecting that not everything would work immediately. I'll try doing some tests.
    – egreg
    Apr 4, 2012 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, 2012 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, 2012 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, 2012 at 20:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .