📄 foomatic-rip
字号:
while ($optstr =~ s!(((even|odd|[\d,-]+):|)\w+:[\'\"].*?[\'\"]) ?!!i) {#while ($optstr =~ s!(\w+=[\'\"].*?[\'\"])!!i) { push (@opts, $1);}# "'bar nut'", "'foo=bar nut'", "'foo:bar nut'"while ($optstr =~ s!([\'\"].+?[\'\"]) ?!!) { my $opt = $1; $opt =~ s/[\'\"]//g; # Make only sure that we didn't quote # the option for a second time when we read # rge options from the command line or # environment variable push (@opts, $opt); }# "foo", "nofoo"push(@opts, split(/ /,$optstr));# Now actually process those pesky options...for (@opts) { print $logh "Pondering option '$_'\n"; # "docs" option to print help page if ((lc($_) =~ /^\s*docs\s*$/) || (lc($_) =~ /^\s*docs\s*=\s*true\s*$/)) { # The second one is necessary becuase CUPS 1.1.15 or newer sees # "docs" as boolean option and modifies it to "docs=true" $do_docs = 1; next; } # "profile" option to supply a color correction profile to a # CUPS raster driver if (lc($_) =~ /^\s*profile=(\S+)\s*$/) { $cupscolorprofile=$1; $dat->{'cmd'} =~ s!\%X!profile=$cupscolorprofile!g; $dat->{'cmd'} =~ s!\%W! -c\"<</cupsProfile($cupscolorprofile)>>setpagedevice\"!g; next; } # Is the command line option limited to certain page ranges? If so, # mark the setting with a hash key containing the ranges my $optionset; if (s/^(even|odd|[\d,-]+)://i) { $optionset = "pages:$1"; } else { $optionset = 'userval'; } my $arg; if ((m!([^=]+)=\'?(.*)\'?!) || (m!([^=:]+):\'?(.*)\'?!)) { my ($aname, $avalue) = ($1, $2); if (($optionset =~ /pages/) && ($arg = argbyname($aname)) && ((!defined($arg->{'section'})) || ($arg->{'section'} !~ /^(Any|Page)Setup/))) { print $logh "This option is not a \"PageSetup\" or " . "\"AnySetup\" option, so it cannot be restricted to " . "a page range.\n"; next; } # At first look for the "backend" option to determine the PPR # backend to use if (($aname =~ m!^backend$!i) && ($spooler eq 'ppr_int')) { # Backend interface name $backend = $avalue; } elsif ($aname =~ m!^media$!i) { # Standard arguments? # media=x,y,z # sides=one|two-sided-long|short-edge # Rummage around in the media= option for known media, source, # etc types. # We ought to do something sensible to make the common manual # boolean option work when specified as a media= tray thing. # # Note that this fails miserably when the option value is in # fact a number; they all look alike. It's unclear how many # drivers do that. We may have to standardize the verbose # names to make them work as selections, too. my @values = split(',',$avalue); for (@values) { my $val; if ($dat->{'args_byname'}{'PageSize'} and $val=valbyname($dat->{'args_byname'}{'PageSize'},$_)) { $dat->{'args_byname'}{'PageSize'}{$optionset} = $val->{'value'}; # Keep "PageRegion" in sync if ($dat->{'args_byname'}{'PageRegion'} and $val=valbyname($dat->{'args_byname'}{'PageRegion'}, $_)) { $dat->{'args_byname'}{'PageRegion'}{$optionset} = $val->{'value'}; } } elsif ($dat->{'args_byname'}{'PageSize'} and /^Custom/) { $dat->{'args_byname'}{'PageSize'}{$optionset} = $_; # Keep "PageRegion" in sync if ($dat->{'args_byname'}{'PageRegion'}) { $dat->{'args_byname'}{'PageRegion'}{$optionset} = $_; } } elsif ($dat->{'args_byname'}{'MediaType'} and $val=valbyname($dat->{'args_byname'}{'MediaType'}, $_)) { $dat->{'args_byname'}{'MediaType'}{$optionset} = $val->{'value'}; } elsif ($dat->{'args_byname'}{'InputSlot'} and $val=valbyname($dat->{'args_byname'}{'InputSlot'}, $_)) { $dat->{'args_byname'}{'InputSlot'}{$optionset} = $val->{'value'}; } elsif (lc($_) eq 'manualfeed') { # Special case for our typical boolean manual # feeder option if we didn't match an InputSlot above if (defined($dat->{'args_byname'}{'ManualFeed'})) { $dat->{'args_byname'}{'ManualFeed'}{$optionset} = 1; } } else { print $logh "Unknown \"media\" component: \"$_\".\n"; } } } elsif ($aname =~ m!^sides$!i) { # Handle the standard duplex option, mostly if ($avalue =~ m!^two-sided!i) { if (defined($dat->{'args_byname'}{'Duplex'})) { # We set "Duplex" to '1' here, the real argument setting # will be done later $dat->{'args_byname'}{'Duplex'}{$optionset} = '1'; # Check the binding: "long edge" or "short edge" if ($avalue =~ m!long-edge!i) { if (defined($dat->{'args_byname'}{'Binding'})) { $dat->{'args_byname'}{'Binding'}{$optionset} = $dat->{'args_byname'}{'Binding'}{'vals_byname'}{'LongEdge'}{'value'}; } else { $dat->{'args_byname'}{'Duplex'}{$optionset} = 'LongEdge'; } } elsif ($avalue =~ m!short-edge!i) { if (defined($dat->{'args_byname'}{'Binding'})) { $dat->{'args_byname'}{'Binding'}{$optionset} = $dat->{'args_byname'}{'Binding'}{'vals_byname'}{'ShortEdge'}{'value'}; } else { $dat->{'args_byname'}{'Duplex'}{$optionset} = 'ShortEdge'; } } } } elsif ($avalue =~ m!^one-sided!i) { if (defined($dat->{'args_byname'}{'Duplex'})) { # We set "Duplex" to '0' here, the real argument setting # will be done later $dat->{'args_byname'}{'Duplex'}{$optionset} = '0'; } } # We should handle the other half of this option - the # BindEdge bit. Also, are there well-known ipp/cups # options for Collate and StapleLocation? These may be # here... } else { # Various non-standard printer-specific options if ($arg = argbyname($aname)) { if (defined(my $newvalue = checkoptionvalue($dat, $aname, $avalue, 0))) { # If the choice is valid, use it, otherwise # ignore it. $arg->{$optionset} = $newvalue; # If this argument is PageSize or PageRegion, # also set the other syncpagesize($dat, $aname, $avalue, $optionset); } else { # Invalid choice, make log entry print $logh "Invalid choice $aname=$avalue.\n"; } } elsif ($spooler eq 'ppr_int') { # Unknown option, pass it to PPR's backend interface push (@backendoptions, "$aname=$avalue"); } else { # Unknown option, make log entry print $logh "Unknown option $aname=$avalue.\n"; } } } elsif (m!^([\d\.]+)x([\d\.]+)([A-Za-z]*)$!) { my ($w, $h, $u) = ($1, $2, $3); # Custom paper size if (($w != 0) && ($h != 0) && ($arg=argbyname("PageSize")) && (defined($arg->{'vals_byname'}{'Custom'}))) { $arg->{$optionset} = "Custom.${w}x${h}${u}"; # Keep "PageRegion" in sync if ($dat->{'args_byname'}{'PageRegion'}) { $dat->{'args_byname'}{'PageRegion'}{$optionset} = $arg->{$optionset}; } } } elsif ((m!^\s*no(.+)\s*$!i) and ($arg=argbyname($1))) { # standard bool args: # landscape; what to do here? # duplex; we should just handle this one OK now? $arg->{$optionset} = 0; } elsif (m!^\s*(.+)\s*$!) { if ($arg=argbyname($1)) { $arg->{$optionset} = 1; } else { print $logh "Unknown boolean option \"$1\".\n"; } }}$do_docs = 1 if( $show_docs );## Were we called to build the PDQ driver declaration file?my @pdqfile;if ($genpdqfile) { @pdqfile = buildpdqdriver($dat, 'userval'); open PDQFILE, $genpdqfile or rip_die("Cannot write PDQ driver declaration file", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); print PDQFILE join('', @pdqfile); close PDQFILE; exit $EXIT_PRINTED;}## Set the $postpipe# $postpipe when running as a PPR RIPif ($spooler eq 'ppr') { # The PPR RIP sends the data output to /dev/fd/3 instead of to STDOUT if (-w "/dev/fd/3") { $postpipe = "| cat - > /dev/fd/3"; } else { $postpipe = "| cat - >&3"; }}# Set up PPR backend (if we run as a PPR interface).if ($spooler eq 'ppr_int') { # Is the chosen backend installed and executable if (!-x "interfaces/$backend") { my $pwd = cwd; print $logh "The backend interface $pwd/interfaces/$backend " . "does not exist/is not executable!\n"; rip_die ("The backend interface $pwd/interfaces/$backend " . "does not exist/is not executable!", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } # foomatic-rip cannot use foomatic-rip as backend if ($backend eq "foomatic-rip") { print $logh "\"foomatic-rip\" cannot use itself as backend " . "interface!\n"; ppr_die ($ppr_printer, "\"foomatic-rip\" cannot use itself as backend interface!", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } # Put the backend interface into the $postpipe $postpipe = "| ( interfaces/$backend \"$ppr_printer\" ". "\"$ppr_address\" \"" . join(" ",@backendoptions) . "\" \"$ppr_jobbreak\" \"$ppr_feedback\" " . "\"$ppr_codes\" \"$ppr_jobname\" \"$ppr_routing\" " . "\"$ppr_for\" \"\" )";}# CUPS and PDQ have their own backends, they do not need a $postpipeif (($spooler eq 'cups') || ($spooler eq 'pdq')) { # No $postpipe for CUPS or PDQ, even if one is defined in the PPD file $postpipe = "";}# CPS needs always a $postpipe, set the default one for local printing# if none is setif (($spooler eq 'cps') && !$postpipe) { $postpipe = "| cat - > \$LPDDEV";}if ($postpipe) { print $logh "${added_lf}Output will be redirected to:\n$postpipe${added_lf}\n";}## Print documentation page when asked formy ($docgeneratorhandle, $docgeneratorpid,$retval);if ($do_docs) { # Don't print the supplied files, STDIN will be redirected to the # documentation page generator @filelist = ("<STDIN>"); # Start the documentation page generator ($docgeneratorhandle, $docgeneratorpid) = getdocgeneratorhandle($dat); if ($retval != $EXIT_PRINTED) { rip_die ("Error opening documentation page generator", $retval); } # Read the further data from the documentation page generator and # not from STDIN if (!close STDIN) { rip_die ("Couldn't close STDIN", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } if (!open (STDIN, "<&$docgeneratorhandle")) { rip_die ("Couldn't dup \$docgeneratorhandle", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } if( $show_docs ){ while( <$docgeneratorhandle> ){ print; } exit(0); }}## In debug mode save the data supposed to be fed into the## renderer also into a file, reset the file hereif ($debug) { system("> ${logfile}.ps");} ## From here on we have to repeat all the rest of the program for## every file to printfor $file (@filelist) { print $logh"${added_lf}================================================\n${added_lf}"."File: $file\n${added_lf}" ."================================================\n${added_lf}"; ## If we do not print standard input, open the file to print if ($file ne "<STDIN>") { if (! -r $file) { print $logh "File $file missing or not readable, skipping.\n"; next; } close STDIN; open STDIN, "< $file" || do { print $logh "Cannot open $file, skipping.\n"; next; } } ## Do we have a raw queue if ($dontparse == 2) { # Raw queue, simply pass the input into the $postpipe (or to STDOUT # when there is no $postpipe) print $logh "Raw printing, executing \"cat $postpipe\"${added_lf}\n"; system("cat $postpipe"); next; } ## First, for arguments with a default, stick the default in as ## the initial value for the "header" option set, this option set ## consists of the PPD defaults, the options specified on the ## command line, and the options set in the header part of the ## PostScript file (all before the first page begins). copyoptions($dat, 'userval', 'header'); ## Next, examine the PostScript job for traces of command-line and ## JCL options. PPD-aware applications and spoolers stuff option ## settings directly into the file, they do not necessarily send ## PPD options by the command line. Also stuff in PostScript code ## to apply option settings given by the command line and to set ## the defaults given in the PPD file. # Examination strategy: read lines from STDIN until the first # %%Page: comment appears and save them as @psheader. This is the # page-independent header part of the PostScript file. The # PostScript interpreter (renderer) must execute this part once # before rendering any assortment of pages. Then pages can be # printed in any arbitrary selection or order. All option # settings we find here will be collected in the default option # set for the RIP command line. # Now the pages will be read and sent to the renderer, one after # the other. Every page is read into memory until the # %%EndPageSetup comment appears (or a certain amount of lines was # read). So we can get option settings only valid for this # page. If we have such settings we set them in the modified # command set for this page. # If the renderer is not running yet (first page) we start it with # the command line built from the current modified command set and # send the first page to it, in the end we leav
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -