1# -*- mode: Perl -*- 2# /=====================================================================\ # 3# | color | # 4# | Implementation for LaTeXML | # 5# |=====================================================================| # 6# | Part of LaTeXML: | # 7# | Public domain software, produced as part of work done by the | # 8# | United States Government & not subject to copyright in the US. | # 9# |---------------------------------------------------------------------| # 10# | Bruce Miller <bruce.miller@nist.gov> #_# | # 11# | http://dlmf.nist.gov/LaTeXML/ (o o) | # 12# \=========================================================ooo==U==ooo=/ # 13package LaTeXML::Package::Pool; 14use strict; 15use warnings; 16use LaTeXML::Package; 17 18#====================================================================== 19# Ignorable options (mostly drivers) 20foreach my $option (qw(monochrome debugshow dvipdf dvipdfm dvipdfmx pdftex xetex 21 dvipsone dviwindo emtex dviwin textures pctexps pctexwin 22 pctexhp pctex32 truetex tcidvi vtex nodvipsnames 23 usenames)) { 24 DeclareOption($option, undef); } 25 26# options that want the dvipsnam definitions 27foreach my $option (qw(dvips xdvi oztex dvipsnames)) { 28 DeclareOption($option, sub { InputDefinitions('dvipsnam', type => 'def'); return; }); } 29 30#====================================================================== 31# change this to something like ConvertColor... Oh, already have that? 32sub ParseColor { 33 my ($model, $spec) = @_; 34 $model = ToString($model) if ref $model; $model = lc($model) if $model; 35 $spec = ToString($spec) if ref $spec; 36 $spec =~ s/^\s+//; 37 $spec =~ s/\s+$//; 38 if ($spec =~ /^\{\s*(.*?)\s*\}$/) { # Trim 39 $spec = $1; } 40 my $color; 41 if ($model && $model eq 'named') { 42 $spec = 'named_' . $spec; $model = undef; } 43 if ($model) { 44 $color = Color($model, ($spec =~ /,/ ? split(/\s*,\s*/, $spec) : split(/\s+/, $spec)))->toCore; 45 Error('unexpected', $spec, $STATE->getStomach, 46 "Don't understand '$spec' as a color") unless $color; } 47 else { 48 $color = LookupColor($spec); 49 if (!$color) { 50 AssignValue('color_' . $spec => Black); 51 Error('unexpected', $spec, $STATE->getStomach, 52 "Can't find color named '$spec'; assuming Black"); } } 53 return $color || Black; } 54 55#====================================================================== 56# are there default named colors that we should be loading? 57 58DefPrimitive('\definecolor{}{}{}', sub { 59 my ($stomach, $name, $model, $spec) = @_; 60 ($name, $model, $spec) = map { $_ && Expand($_) } $name, $model, $spec; 61 DefColor(ToString($name), ParseColor($model, $spec)); 62 Box(undef, undef, undef, Invocation(T_CS('\definecolor'), $name, $model, $spec)); }); 63 64# I don't think this is quite right, but... 65# [I think we need do do something like "named_color_".$name 66# and corresponding changes to getColor, as well? 67# What are we supposed to do with $dmodel??? 68DefPrimitive('\DefineNamedColor{}{}{}{}', sub { 69 my ($stomach, $dmodel, $name, $model, $spec) = @_; 70 ($dmodel, $name, $model, $spec) = map { $_ && Expand($_) } $dmodel, $name, $model, $spec; 71 DefColor('named_' . ToString($name), ParseColor($model, $spec)); 72 Box(undef, undef, undef, Invocation(T_CS('\DefineNamedColor'), $dmodel, $name, $model, $spec)); }); 73 74# \color{name} or \color[model]{spec} 75DefPrimitive('\color[]{}', sub { 76 my ($stomach, $model, $spec) = @_; 77 ($model, $spec) = map { $_ && Expand($_) } $model, $spec; 78 my $color = ParseColor($model, $spec); 79 AssignValue('preambleTextcolor', $color) if LookupValue('inPreamble'); 80 MergeFont(color => $color); 81 Box(undef, undef, undef, 82 Invocation(T_CS('\color'), T_OTHER('rgb'), # Revert to ACTUAL color, not user's name 83 T_OTHER(join(',', $color->rgb->components)))); }); 84 85#\pagecolor{name} or \pagecolor[model]{spec} 86DefPrimitive('\pagecolor[]{}', sub { 87 my ($stomach, $model, $spec) = @_; 88 ($model, $spec) = map { $_ && Expand($_) } $model, $spec; 89 my $color = ParseColor($model, $spec); 90 MergeFont(background => $color); 91 Box(undef, undef, undef, Invocation(T_CS('\pagecolor'), $model, $spec)); }); 92 93# NOTE: the color in effect at \begin{document} will be returned by \normalcolor 94# Do other font properties act this way? 95DefPrimitive('\normalcolor', sub { 96 my $color = (LookupValue('preambleTextcolor') || Black()); 97 MergeFont(color => $color); 98 Box(undef, undef, undef, T_CS('\normalcolor')); }); 99 100#\textcolor{name}{text} or \textcolor[model]{spec}{text} 101DefMacro('\textcolor[]{}{}', '{\ifx.#1.\color{#2}\else\color[#1]{#2}\fi#3}'); 102 103#\colorbox{name}{text} or \colorbox[model]{spec}{text} 104DefMacro('\colorbox[]{}{}', '\hbox{\ifx.#1.\pagecolor{#2}\else\pagecolor[#1]{#2}\fi#3}'); 105 106#\fcolorbox{name}{text} or \fcolorbox[model]{spec}{text} 107DefConstructor('\fcolorbox[]{}{} Undigested', 108 "<ltx:text framed='rectangle' framecolor='#framecolor'" 109 . " _noautoclose='1'>#text</ltx:text>", 110 bounded => 1, mode => 'text', 111 afterDigest => sub { 112 my ($stomach, $whatsit) = @_; 113 my ($model, $fspec, $bspec, $text) = $whatsit->getArgs; 114 $whatsit->setProperty(framecolor => ParseColor($model, $fspec)); 115 MergeFont(background => ParseColor($model, $bspec)); 116 $whatsit->setProperty(text => Digest($text)); }); 117 118#******************************************************************************** 119# Low-level stuff; redefined from LaTeX stubs 120 121# Not sure what \current@color should return... the string form? 122# \current@color 123# Similarly, I'm not sure what set@color needs to do that isn't redundant 124DefMacroI('\set@color', undef, ''); 125 126DefMacroI('\color@begingroup', undef, '\begingroup'); 127DefMacroI('\color@endgroup', undef, '\endgroup'); 128DefMacroI('\color@setgroup', undef, '\begingroup\set@color'); 129DefMacroI('\color@hbox', undef, '\hbox\bgroup\color@begingroup'); 130DefMacroI('\color@vbox', undef, '\vbox\bgroup\color@begingroup'); 131DefMacroI('\color@endbox', undef, '\color@endgroup\egroup'); 132 133#******************************************************************************** 134# Default defined colors 135RawTeX(<<'EOTeX'); 136\definecolor{black}{rgb}{0,0,0} 137\definecolor{white}{rgb}{1,1,1} 138\definecolor{red}{rgb}{1,0,0} 139\definecolor{green}{rgb}{0,1,0} 140\definecolor{blue}{rgb}{0,0,1} 141\definecolor{cyan}{cmyk}{1,0,0,0} 142\definecolor{magenta}{cmyk}{0,1,0,0} 143\definecolor{yellow}{cmyk}{0,0,1,0} 144EOTeX 145#******************************************************************************** 146ProcessOptions(); 1471; 148