📄 foomatic-rip
字号:
my $line = $2; # Store the value # Code string can have multiple lines, read all of them my $code = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $code .= substr($line, 0, -2); } else { # line ends here $code .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $code .= $1; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the value $dat->{'args_byname'}{$argname}{'allowedregexp'} = unhtmlify($code); } elsif (m!^\*OrderDependency:\s*(\S+)\s+(\S+)\s+\*([^:/\s]+)\s*$!) { # "*OrderDependency: <order> <section> *<option>" my $order = $1; my $section = $2; my $argname = $3; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the values $dat->{'args_byname'}{$argname}{'order'} = $order; $dat->{'args_byname'}{$argname}{'section'} = $section; } elsif (m!^\*Default([^/:\s]+):\s*([^/:\s]+)\s*$!) { # "*Default<option>: <value>" my $argname = $1; my $default = $2; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the value $dat->{'args_byname'}{$argname}{'default'} = $default; } elsif (m!^\*FoomaticRIPDefault([^/:\s]+):\s*([^/:\s]+)\s*$!) { # "*FoomaticRIPDefault<option>: <value>" # Used for numerical options only my $argname = $1; my $default = $2; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the value $dat->{'args_byname'}{$argname}{'fdefault'} = $default; } elsif (m!^\*$currentargument\s+([^:]+):\s*\"(.*)$!) { # "*<option> <choice>[/<translation>]: <code>" my $settingtrans = $1; my $line = $2; my $translation = ""; my $setting = ""; if ($settingtrans =~ m!^([^:/\s]+)/([^:]*)$!) { $setting = $1; $translation = $2; } else { $setting = $settingtrans; } # Make sure that the argument is in the data structure checkarg ($dat, $currentargument); # Make sure that the setting is in the data structure (enum options) my $bool = ($dat->{'args_byname'}{$currentargument}{'type'} eq 'bool'); if ($bool) { if (lc($setting) eq "true") { if (!$dat->{'args_byname'}{$currentargument}{'comment'}) { $dat->{'args_byname'}{$currentargument}{'comment'} = $translation; } $dat->{'args_byname'}{$currentargument}{'comment_true'} = $translation; } else { $dat->{'args_byname'}{$currentargument}{'comment_false'} = $translation; } } else { checksetting ($dat, $currentargument, $setting); # Make sure that this argument has a default setting, even if # none is defined in this PPD file if (!$dat->{'args_byname'}{$currentargument}{'default'}) { $dat->{'args_byname'}{$currentargument}{'default'} = $setting; } $dat->{'args_byname'}{$currentargument}{'vals_byname'}{$setting}{'comment'} = $translation; } # Store the value # Code string can have multiple lines, read all of them my $code = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $code .= substr($line, 0, -2); } else { # line ends here $code .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $code .= $1; if ($code !~ m!^%% FoomaticRIPOptionSetting!) { if ($bool) { if (lc($setting) eq "true") { $dat->{'args_byname'}{$currentargument}{'proto'} = $code; } else { $dat->{'args_byname'}{$currentargument}{'protof'} = $code; } } else { $dat->{'args_byname'}{$currentargument}{'vals_byname'}{$setting}{'driverval'} = $code; } } } elsif ((m!^\*FoomaticRIPOptionSetting\s+([^/:=\s]+)=([^/:=\s]+):\s*\"(.*)$!) || (m!^\*FoomaticRIPOptionSetting\s+([^/:=\s]+):\s*\"(.*)$!)) { # "*FoomaticRIPOptionSetting <option>[=<choice>]: <code>" # For boolean options <choice> is not given my $argname = $1; my $setting = $2; my $line = $3; my $bool = 0; if (!$line) { $line = $setting; $bool = 1; } # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Make sure that the setting is in the data structure (enum options) if (!$bool) { checksetting ($dat, $argname, $setting); # Make sure that this argument has a default setting, even if # none is defined in this PPD file if (!$dat->{'args_byname'}{$argname}{'default'}) { $dat->{'args_byname'}{$argname}{'default'} = $setting; } } # Store the value # Code string can have multiple lines, read all of them my $code = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $code .= substr($line, 0, -2); } else { # line ends here $code .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $code .= $1; if ($bool) { $dat->{'args_byname'}{$argname}{'proto'} = unhtmlify($code); } else { $dat->{'args_byname'}{$argname}{'vals_byname'}{$setting}{'driverval'} = unhtmlify($code); } } elsif (m!^\*JCL(Begin|ToPSInterpreter|End):\s*\"(.*)$!) { # "*JCL(Begin|ToPSInterpreter|End): <code>" # The printer supports PJL/JCL when there is such a line $dat->{'jcl'} = 1; my $item = $1; my $line = $2; # Store the value # Code string can have multiple lines, read all of them my $code = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $code .= substr($line, 0, -2); } else { # line ends here $code .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $code .= $1; if ($item eq 'Begin') { $jclbegin = unhexify($code); } elsif ($item eq 'ToPSInterpreter') { $jcltointerpreter = unhexify($code); } elsif ($item eq 'End') { $jclend = unhexify($code); } } elsif (m!^\*\% COMDATA \#(.*)$!) { # If we have an old Foomatic 2.0.x PPD file, collect its Perl data push (@datablob, $1); }}close PPD;# If we have an old Foomatic 2.0.x PPD file use its Perl data structureif ($#datablob >= 0) { print $logh "${added_lf}You are using an old Foomatic 2.0 PPD file, consider " . "upgrading.${added_lf}\n"; my $VAR1; if (eval join('',@datablob)) { # Overtake default settings from the main structure of the PPD file for my $arg (@{$dat->{'args'}}) { if ($arg->{'default'}) { $VAR1->{'argsbyname'}{$arg->{'name'}}{'default'} = $arg->{'default'}; } } undef $dat; $dat = $VAR1; $dat->{'jcl'} = $dat->{'pjl'}; } else { # Perl structure broken print $logh "${added_lf}Unable to evaluate datablob, print job may come " . "out incorrectly or not at all.${added_lf}\n"; }}## We do not need to parse the PostScript job when we don't have## any options. If we have options, we must check whether the## default settings from the PPD file are valid and correct them## if nexessary.my $dontparse = 0;if ((!defined(@{$dat->{'args'}})) || ($#{$dat->{'args'}} < 0)) { # We don't have any options, so we do not need to parse the # PostScript data $dontparse = 1;} else { # Let the default value of a boolean option being 0 or 1 instead of # "True" or "False", range-check the defaults of all options and # issue warnings if the values are not valid checkoptions($dat, 'default'); # Adobe's PPD specs do not support numerical # options. Therefore the numerical options are mapped to # enumerated options in the PPD file and their characteristics # as a numerical option are stored in "*Foomatic..." # keywords. A default must be between the enumerated # fixed values. The default # value must be given by a "*FoomaticRIPDefault<option>: # <value>" line in the PPD file. But this value is only valid # if the "official" default given by a "*Default<option>: # <value>" line (it must be one of the enumerated values) # points to the enumerated value which is closest to this # value. This way a user can select a default value with a # tool only supporting PPD files but not Foomatic extensions. # This tool only modifies the "*Default<option>: <value>" line # and if the "*FoomaticRIPDefault<option>: <value>" had always # priority, the user's change in "*Default<option>: <value>" # would have no effect. for my $arg (@{$dat->{'args'}}) { if ($arg->{'fdefault'}) { if ($arg->{'default'}) { if ($arg->{'type'} =~ /^(int|float)$/) { if ($arg->{'fdefault'} < $arg->{'min'}) { $arg->{'fdefault'} = $arg->{'min'}; } if ($arg->{'fdefault'} > $arg->{'max'}) { $arg->{'fdefault'} = $arg->{'max'}; } my $mindiff = abs($arg->{'max'} - $arg->{'min'}); my $closestvalue; for my $val (@{$arg->{'vals'}}) { if (abs($arg->{'fdefault'} - $val->{'value'}) < $mindiff) { $mindiff = abs($arg->{'fdefault'} - $val->{'value'}); $closestvalue = $val->{'value'}; } } if (($arg->{'default'} == $closestvalue) || (abs($arg->{'default'} - $closestvalue) / $closestvalue < 0.001)) { $arg->{'default'} = $arg->{'fdefault'}; } } } else { $arg->{'default'} = $arg->{'fdefault'}; } } }}# Is our PPD for a CUPS raster driverif (my $cupsfilter = $dat->{'cupsfilter'}{"application/vnd.cups-raster"}) { # Search filter in cupsfilterpath # The %Y is a placeholder for the option settings my $havefilter = 0; for (split(':', $cupsfilterpath)) { if (-x "$_/$cupsfilter") { $havefilter=1; $cupsfilter = "$_/$cupsfilter 0 '' '' 0 '%Y%X'"; last; } } if (!$havefilter) { # We do not have the required filter, so we assume that # rendering this job is supposed to be done on a remote # server. So we do not define a renderer command line and # embed only the option settings (as we had a PostScript # printer). This way the settings are # taken into account # when the job is rendered on the server. print $logh "${added_lf}CUPS filter for this PPD file not found " . "assuming that job will be rendered on a remote server. Only " . "the PostScript of the options will be inserted into the " . "PostScript data stream.${added_lf}\n"; } else { # use pstoraster script if available, otherwise run GhostScript # directly my $pstoraster = "pstoraster"; my $havepstoraster = 0; for (split(':', $cupsfilterpath)) { if (-x "$_/$pstoraster") { $havepstoraster=1; $pstoraster = "$_/$pstoraster 0 '' '' 0 '%X'"; last; } } if (!$havepstoraster) { # Build GhostScript command line $pstoraster = "gs -dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH -dNOMEDIAATTRS -sDEVICE=cups -sOutputFile=-%W -" } # build GhostScript/CUPS driver command line $dat->{'cmd'} = "$pstoraster | $cupsfilter"; # Set environment variables $ENV{'PPD'} = $ppdfile; }}# Was the RIP command line defined in the PPD file? If not, we assume a# PostScript printer and do not render/translate the input dataif (!defined($dat->{'cmd'})) { $dat->{'cmd'} = "cat%A%B%C%D%E%F%G%H%I%J%K%L%M%Z"; if ($dontparse) { # No command line, no options, we have a raw queue, don't check # whether the input is PostScript and ignore the "docs" option, # simply pass the input data to the backend. $dontparse = 2; $model = "Raw queue"; }}## Summary for debuggingprint $logh "${added_lf}Parameter Summary\n";print $logh "-----------------${added_lf}\n";print $logh "Spooler: $spooler\n";print $logh "Printer: $printer\n";print $logh "PPD file: $ppdfile\n";print $logh "Printer model: $model\n";# Print the options string only in debug mode, Mac OS X adds very many# options so that CUPS cannot handle the output of the option string# in its log files. If CUPS encounters a line with more than 1024 characters# sent into its log files, it aborts the job with an error.if (($debug) || ($spooler ne 'cups')) { print $logh "Options: $optstr\n";}print $logh "Job title: $jobtitle\n";print $logh "File(s) to be printed: ${added_lf}@filelist${added_lf}\n";## Parse options from command line ($optstr)# Before we start, save the defaults for printing documentation pagescopyoptions($dat, 'default', 'userval');# The options are "foo='bar nut'", "foo", "nofoo", "'bar nut'", or# "foo:'bar nut'" (when GPR was used) all with spaces between...# In addition they can be preceeded by page ranges, separated with a# colon.my @opts;# Variable for PPR's backend interface name (parallel, tcpip, atalk, ...)my $backend = "";# Array to collect unknown options so that they can get passed to the# backend interface of PPR. For other spoolers we ignore them.my @backendoptions = ();# "foo='bar nut'"while ($optstr =~ s!(((even|odd|[\d,-]+):|)\w+=[\'\"].*?[\'\"]) ?!!i) { push (@opts, $1);}# "foo:'bar nut'" (GPR separates option and setting with a colon ":")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -