% Copyright (c) 2008 Ross Moore % mmap package -- include CMap resources for math symbols into PDF % to make "search" and "copy-n-paste" functions work properly % % -m.cmap CMap uses ascii strings for the macro-names % .cmap CMap uses the Unicode code-point of the symbols % % You may distribute and/or modify this program under the terms of LPPL % the program consists of mmap.sty and .cmap files: % % {t1,lmr,ly1,oml,oms,omx,ot1,ulasy,umsa,umsb,ueuf,upsy,upzd}.cmap % {oml{b,m}it,omsb,ot1{rbxit,rbxn,rmit,rmn,ssbxn,ssmn,ttmn}}.cmap % % {t1,oml,oms,omx,ot1,ueuf,ueufb,ulasy,umsa,umsb,upsy,upzd}-m.cmap % {oml{b,m}it,omsb,ot1{rbxit,rbxn,rmit,rmn,ssbxn,ssmn,ttmn}}-m.cmap % % Usage: % put \usepackage{mmap} to load CMAP resources from -m.cmap files. % Or put \usepackage[noTeX]{mmap} to load CMAP resources from .cmap files. % Or put \usepackage[useTeX]{mmap} to load CMAP resources from -m.cmap files. % % IMPORTANT: place this immediately after the \documentclass line % to ensure that all fonts are checked for appropriate resources. % % TODO: % add *.cmap files for other font encodings (contributions are welcome): % TS1, OT2, IL2, ... % support dvips? % % History: % 2008/08/11 Fixed error for <3D> character ('equals') in ot1*-m files. % % 2008/07/08 Adjusted the documentation in the header of this file. % % 2008/07/02 Full support for math styles in OT1 and Euler Fraktur. % Fixed loading to avoid multiple inclusion of CMaps. % Ensure default OT1 font cancelled, to get CMap for math. % Improved CMap ranges and support for Plane-0 math letters. % Added /CMapVersion number to all .cmap files % % 2008/06/29 Now has partial support for different math styles in OT1. % % 2008/05/26 First version, including patch for \setaccent . % Cancel the default pre-loaded main font, so it can reload % later with a associated CMap resource. % % 2007/04/22 First attempt, to work seamlessly with cmap.sty % Previous work used a modified version of that package. % \ProvidesPackage{mmap}[2008/08/11 v1.03 CMAP support for math in PDF] \@ifundefined{pdffontattr}{% % The mmap package can be used only with pdflatex, % but not with ordinary latex \PackageWarningNoLine{mmap}{pdftex not detected - will not do anything}% \endinput }\relax \ifnum\pdfoutput<1 \PackageWarningNoLine{mmap}{pdftex in DVI mode - will not do anything} \expandafter\endinput \fi \RequirePackage{cmap} \RequirePackage{ifpdf} \let\real@cmap@load\cmap@load \bgroup \catcode`\m 12\relax \def\next{\egroup\def\nonletter@style{m}}% \next {\catcode`\U 12\relax \catcode`\O 12\relax \catcode`\T 12\relax \catcode`\M 12\relax \catcode`\L 12\relax \catcode`\S 12\relax \gdef\mmap@enc@unknown@{U}% \gdef\mmap@enc@math@{OML}% \gdef\mmap@enc@symb@{OMS}% \gdef\mmap@enc@oldtex@{OT1}% \gdef\mmap@enc@newtex@{T1}% \gdef\mmap@oti@cancel@#1/#2/#3/#4/#5@@{% \def\oti@font@name{OT1/#2/#3/#4/#5}% \expandafter\let\csname\oti@font@name\endcsname\relax }% \gdef\mmap@enc@getname@#1/#2/#3/#4/#5@@{% \def\cmap@f@namestyle{#1-#3}% \def\this@f@style{#3}% \ifx\nonletter@style\this@f@style \def\cmap@f@encoding{u#2}% \else % use the style when not 'm' \def\cmap@f@encoding{u#2#3}% \fi}% \gdef\mmap@enc@getmathname@#1/#2/#3/#4/#5@@{% \def\cmap@f@namestyle{#1-#3}% \def\cmap@f@encoding{oml#3#4}}% \gdef\mmap@enc@getsymbname@#1/#2/#3/#4/#5@@{% \def\cmap@f@namestyle{#1-#3}% \def\this@f@style{#3}% \ifx\nonletter@style\this@f@style \def\cmap@f@encoding{oms}% \else % use the style when not 'm' \def\cmap@f@encoding{oms#3}% \fi}% \gdef\mmap@enc@oldtexname@#1/#2/#3/#4/#5@@{% \def\cmap@f@namestyle{#1-#3}% \ifmmode\def\cmap@f@encoding{ot1#2#3#4}% \else\def\cmap@f@encoding{ot1}\fi}% \gdef\mmap@enc@newtexname@#1/#2/#3/#4/#5@@{% \def\cmap@f@namestyle{#1-#3}% \ifmmode\def\cmap@f@encoding{t1#2#3#4}% \show\cmap@f@encoding % this is not accessed normally \else\def\cmap@f@encoding{t1}\fi}% }% % % strip the 'cm' part from the resulting name {\catcode`\m 12\relax \catcode`\c 12\relax \gdef\strip@CM@prefix@#1cm#2@#3!{% \def\this@f@enCoding{#1#2}}% }% end of \catcode \def\strip@CM@prefix{% \expandafter\strip@CM@prefix@\cmap@f@encoding @cm@!% \edef\cmap@f@encoding{\this@f@enCoding}} % % % extra indirection, to allow features to be easily isolated % when doing detailed testing \edef\mmap@enc@unknown{\mmap@enc@unknown@} \edef\mmap@enc@math{\mmap@enc@math@} \edef\mmap@enc@symb{\mmap@enc@symb@} \edef\mmap@enc@oldtex{\mmap@enc@oldtex@} \edef\mmap@enc@newtex{\mmap@enc@newtex@} % \def\mmap@cmap@load{% \ifx\cmap@f@encoding\mmap@enc@unknown % check unknown encoding for math support \expandafter\expandafter\expandafter\mmap@enc@getname@\expandafter\string\font@name @@% \else % cmap doesn't get this far ! % check OT1 encoding for old-tex letters \ifx\cmap@f@encoding\mmap@enc@oldtex \expandafter\expandafter\expandafter\mmap@enc@oldtexname@\expandafter\string\font@name @@% \ifmmode\strip@CM@prefix\fi \else % check T1 encoding for new-tex letters \ifx\cmap@f@encoding\mmap@enc@newtex \expandafter\expandafter\expandafter\mmap@enc@newtexname@\expandafter\string\font@name @@% \ifmmode\strip@CM@prefix\fi \else % check OML encoding for math style \ifx\cmap@f@encoding\mmap@enc@math \expandafter\expandafter\expandafter\mmap@enc@getmathname@\expandafter\string\font@name @@% \else % check OMS encoding for math style \ifx\cmap@f@encoding\mmap@enc@symb \expandafter\expandafter\expandafter\mmap@enc@getsymbname@\expandafter\string\font@name @@% \else % write out a message to the .log file, but don't change the encoding, % unless \mmap@enc@getname@ alters the value of \this@f@encoding \edef\this@f@encoding{\cmap@f@encoding}% \expandafter\expandafter\expandafter\mmap@enc@getname@\expandafter\string\font@name @@% \typeout{\cmap@f@namestyle\space encoding encountered}% \edef\cmap@f@encoding{\this@f@encoding}% \fi\fi\fi\fi \fi \mmap@filecheck@ } \def\mmap@filecheck@@{% \edef\reserved@f{\lowercase{\def\noexpand\reserved@f{\cmap@f@encoding\mmap@end@}}}% \reserved@f \IfFileExists{\reserved@f}{\mmap@loadi}{% \PackageWarning{mmap}{!!! No \mmap@end@\space file found for \cmap@f@encoding\space !!! }% \real@cmap@load}% fall back to the original cmap loading } \let\mmap@filecheck@\mmap@filecheck@@ % \cmap@hook is used when loading math-versions \let\real@cmap@hook\cmap@hook \def\mmap@cmap@hook{% \edef\cmap@f@encoding{\f@encoding}% \let\mmap@filecheck@\relax \mmap@cmap@load \@ifundefined{cmap@set@\cmap@f@encoding}% {\mmap@filecheck@@}\relax \csname cmap@set@\cmap@f@encoding\endcsname \let\mmap@filecheck@\mmap@filecheck@@ } % place the /ToUnincode resource and save its object reference \def\mmap@loadi{% \immediate\pdfobj stream %attr {/Type /CIDFile} file {\reserved@f}% \expandafter\xdef\csname cmap@set@\cmap@f@encoding\endcsname{% \noexpand\expandafter\pdffontattr\noexpand\font@name {/ToUnicode \the\pdflastobj\space 0 R}}% } % for combining accent characters to work, they must come % after the letter being accented. % The following coding achieves this; e.g. for OT1 encoded fonts. \let\mmap@latex@add@accent\add@accent \def\mmap@add@accent#1#2{% \hmode@bgroup \let \hmode@start@before@group \@firstofone \setbox\@tempboxa\hbox{% #2\global\mathchardef\accent@spacefactor\spacefactor}% #2\kern-\wd\@tempboxa % \ifdim\ht\@tempboxa>1ex\relax \dimen@=\ht\@tempboxa\advance\dimen@-1ex\relax \raise\dimen@\hbox to\wd\@tempboxa{\hss \accent#1{\vphantom{#2}}\hss}% % \else % \accent#1{%\vphantom{#2} % \vrule width\z@ height\ht\@tempboxa depth\dp\@tempboxa}% % \fi \egroup \spacefactor\accent@spacefactor % % \accent#1 #2\spacefactor\accent@spacefactor } \def\mmap@check@add@accent{% \ifx\mmap@end@\cmap@ending \let\add@accent\mmap@add@accent \else \let\add@accent\mmap@latex@add@accent \fi } %%% %%% Handle some special cases %%% %\OT1\c #1-> \def\mmap@OTcedilla#1{\bgroup \leavevmode\setbox\z@\hbox{#1}% {\ooalign{\unhbox\z@\crcr\hidewidth\char 24\hidewidth}}% \egroup } \def\mmap@OTcedillabefore#1{\bgroup \leavevmode\setbox\z@\hbox{#1}% {\ooalign{\cr\hidewidth\char 24\hidewidth\cr\raise\baselineskip\box\z@\cr\cr}}% \egroup } \def\mmap@bindOTcedilla{\expandafter\let\csname OT1\string\c\endcsname\mmap@OTcedilla} \def\mmap@bindcedillabefore{% \expandafter\let\csname OT1\string\c\endcsname\mmap@OTcedillabefore % \expandafter\let\csname T1\string\c\endcsname\mmap@TIcedillabefore } %\OT1\b #1-> \def\mmap@OTunderbar#1{% \hmode@bgroup \setbox\z@\hbox{#1}% \o@lign{\unhbox\z@\crcr\hidewidth\ltx@sh@ft{-3ex}\vbox to.2ex{\hbox{\char22}\vss}\hidewidth}% \egroup } \def\mmap@OTunderbarbefore#1{% \hmode@bgroup \o@lign{\relax#1\crcr\hidewidth\ltx@sh@ft{-3ex}\vbox to.2ex{\hbox{\char22}\vss}\hidewidth}% \egroup } \def\mmap@bindOTunderbar{\expandafter\let\csname OT1\string\b\endcsname\mmap@OTunderbar} \def\mmap@bindunderbarbefore{% \expandafter\let\csname OT1\string\b\endcsname\mmap@OTunderbarbefore % \expandafter\let\csname T1\string\b\endcsname\mmap@TIunderbarbefore } %\T1\c #1-> \def\mmap@TIcedilla#1{% \@text@composite\T1\c#1\@empty\@text@composite {\leavevmode \setbox \z@ \hbox {#1}% {\ooalign{\unhbox\z@\crcr\hidewidth\char 11\hidewidth}}% }% } \def\mmap@bindTIcedilla{\expandafter\let\csname T1\string\c\endcsname\mmap@TIcedilla} %\T1\k #1-> \def\mmap@TIcedillabefore#1{% \@text@composite\T1\c#1\@empty\@text@composite {\hmode@bgroup\setbox\z@\hbox{#1}% \ooalign{\cr\hidewidth\char 11\hidewidth\cr\raise\baselineskip\box\z@\cr\cr}% \egroup}% } \def\mmap@bindTIcedillabefore{\expandafter\let\csname T1\string\c\endcsname\mmap@TIcedillabefore} %\T1\k #1-> \def\mmap@TIcaronbefore#1{% \@text@composite\T1\c#1\@empty\@text@composite {\hmode@bgroup\setbox\z@\hbox{#1}% \ooalign{\cr\hidewidth\char 12\hidewidth\cr\raise\baselineskip\box\z@\cr\cr}% \egroup}% } \def\mmap@bindTIcaronbefore{\expandafter\let\csname T1\string\k\endcsname\mmap@TIcaronbefore} %\OT1\d #1-> \def\mmap@underdotbefore#1{\bgroup \leavevmode\setbox\z@\hbox{#1}% \dimen@=\dp\z@ \advance\dimen@.4ex\relax {\ooalign{\cr\hidewidth\lower\dimen@\hbox{\char 46}\hidewidth\cr\raise\baselineskip\box\z@\cr\cr}}% \egroup } \def\mmap@bindunderdotbefore{% \expandafter\let\csname OT1\string\d\endcsname\mmap@underdotbefore % \expandafter\let\csname T1\string\d\endcsname\mmap@underdotbefore } %\\OT1\r-A -> \def\mmap@Aring{\mmap@add@accent{23}A} \def\mmap@bindOTring{\expandafter\let\csname\string\OT1\string\r-A\endcsname\mmap@Aring} %\OT1\L -> %\OT1\l -> \expandafter\let\expandafter\realOTL\csname OT1\string\L\endcsname \expandafter\let\expandafter\realOTl\csname OT1\string\l\endcsname \def\mmap@stroke#1#2{\hmode@bgroup \setbox\@tempboxa\hbox{#1}% \hbox to\wd\@tempboxa{#1%\global\mathchardef\accent@spacefactor\spacefactor \kern-\wd\@tempboxa\kern-#2em\hss\@xxxii\hfil}% \egroup \spacefactor\accent@spacefactor } % These don't work well, as the combination isn't honored adequately \def\mmap@bindOTLstroke{\expandafter\def\csname OT1\string\L\endcsname{\mmap@stroke{L}{.27}}} \def\mmap@bindOTlstroke{\expandafter\def\csname OT1\string\l\endcsname{\mmap@stroke{l}{0}}} % cancel the current font, which have been preloaded without a CMap % when needed it will load again, this time having a CMap % also always cancel OT1, as this may be needed in math \expandafter\expandafter\expandafter\mmap@oti@cancel@\expandafter\string\font@name @@% \expandafter\let\font@name\relax \def\mmap@ending{-m.cmap} \def\cmap@ending{.cmap} \DeclareOption{noTeX}{\let\mmap@end@\cmap@ending\mmap@check@add@accent} \DeclareOption{useTeX}{\let\mmap@end@\mmap@ending\mmap@check@add@accent} \def\mmapnotexcodes{\ds@noTeX\AtBeginDocument{\ds@noTeX}} \def\mmapusetexcodes{\ds@useTeX\AtBeginDocument{\ds@useTeX}} \ExecuteOptions{useTeX}% \ProcessOptions % Cannot delay the rebinding, since the .aux file or a package % may cause font-loading without the correct CMap \AtEndOfPackage{% \let\cmap@load\mmap@cmap@load \let\cmap@hook\mmap@cmap@hook } \ifx\mmap@end@\mmap@ending \AtEndOfPackage{\AtBeginDocument{% \mmap@bindcedillabefore \mmap@bindunderbarbefore \mmap@bindTIcedillabefore \mmap@bindTIcaronbefore \mmap@bindunderdotbefore }}\else \AtEndOfPackage{\AtBeginDocument{% \mmap@bindOTring \mmap@bindOTcedilla \mmap@bindTIcedilla % \mmap@bindOTLstroke % \mmap@bindOTlstroke }}\fi \endinput