为什么 media9 需要 babel?

为什么 media9 需要 babel?

我想知道为什么这个media9包( 的新替代品movie15)需要babel?如果我想加载 而polyglossia不是会发生什么babel,因为 XeLaTeX 需要它来编译俄语文本(请注意,如果需要俄语,标准 babel 会与 XeLaTeX 冲突)?

注意:幸运的是,babel 有一个自定义的俄语版本(http://ctan.org/pkg/russian) 这与 XeLaTeX 并不冲突——我只是好奇。

答案1

在 中,中定义的media9命令用于正确处理可能出现在传递给 的 URL 和路径规范中的活动字符。\defineshorthandbabel\includemedia

URL 中经常出现的一些字符,例如:~在标准 LaTeX 环境中具有特殊含义,或者如果某个语言包加载了 ,则具有相同的含义babel。但是,包含此类字符的 URL 和路径必须逐字插入到与媒体包含相关的某些 PDF 对象中。

例如,\usepackage[french]{babel}激活的字符之一是:。在文件 中frenchb.ldf:被重新定义为

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

为了防止\includemedia在PDF中插入垃圾,暂时将其重新定义为简单字母:

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

一旦命令\includemedia完成,就会撤消。

我不喜欢media9依赖babel。我更喜欢独立的解决方案。也许有人能帮忙?

答案2

似乎只需media9要有babel可用的\defineshorthand,它在宏中使用\mix@uribegin,它有几行,如

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

意思是:如果"是活动的,则将其重新定义为\detokenize{"}。使用辅助宏可以获得相同的效果:

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

并将上面的行改为

\neutralize{"}

"如果发现活动状态,它将被更改为去标记化状态"

按照 LaTeX3 的说法,这可能是

\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:

\mix@uribegin这应该取代和的定义\mix@uriend;如果出现,它们必须被\mix_uribegin:和取代\mix_uriend:

编辑

根据 Joseph Wright 的建议,这里有一个更简短的定义:

\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:

原理一模一样,但是代码至少更加优雅。

相关内容