📄 foomatic-rip
字号:
# selected. if (!$printer) { rip_die("No printer definition (option \"-P <name>\") " . "specified!", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } # Search for the PPD file # Search also common spooler-specific locations, this way a printer # configured under a certain spooler can also be used without # spooler if (-r $printer) { $ppdfile = $printer; # CPS can have the PPD in the spool directory } elsif (($spooler eq 'cps') && (-r "/var/spool/lpd/${printer}/${printer}.ppd")) { $ppdfile = "/var/spool/lpd/${printer}/${printer}.ppd"; } elsif (($spooler eq 'cps') && (-r "/var/local/spool/lpd/${printer}/${printer}.ppd")) { $ppdfile = "/var/local/spool/lpd/${printer}/${printer}.ppd"; } elsif (($spooler eq 'cps') && (-r "/var/local/lpd/${printer}/${printer}.ppd")) { $ppdfile = "/var/local/lpd/${printer}/${printer}.ppd"; } elsif (($spooler eq 'cps') && (-r "/var/spool/lpd/${printer}.ppd")) { $ppdfile = "/var/spool/lpd/${printer}.ppd"; } elsif (($spooler eq 'cps') && (-r "/var/local/spool/lpd/${printer}.ppd")) { $ppdfile = "/var/local/spool/lpd/${printer}.ppd"; } elsif (($spooler eq 'cps') && (-r "/var/local/lpd/${printer}.ppd")) { $ppdfile = "/var/local/lpd/${printer}.ppd"; } elsif (-r "${printer}.ppd") { # current dir $ppdfile = "${printer}.ppd"; } elsif (-r "$user_default_path/${printer}.ppd") { # user dir $ppdfile = "$user_default_path/${printer}.ppd"; } elsif (-r "$configpath/direct/${printer}.ppd") { # system dir $ppdfile = "$configpath/direct/${printer}.ppd"; } elsif (-r "$configpath/${printer}.ppd") { # system dir $ppdfile = "$configpath/${printer}.ppd"; } elsif (-r "/etc/cups/ppd/${printer}.ppd") { # CUPS config dir $ppdfile = "/etc/cups/ppd/${printer}.ppd"; } elsif (-r "/usr/local/etc/cups/ppd/${printer}.ppd") { $ppdfile = "/usr/local/etc/cups/ppd/${printer}.ppd"; } elsif (-r "/usr/share/ppr/PPDFiles/${printer}.ppd") { # PPR PPDs $ppdfile = "/usr/share/ppr/PPDFiles/${printer}.ppd"; } elsif (-r "/usr/local/share/ppr/PPDFiles/${printer}.ppd") { $ppdfile = "/usr/local/share/ppr/PPDFiles/${printer}.ppd"; } else { rip_die ("There is no readable PPD file for the printer " . "$printer, is it configured?", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } }}## Files to be printed (can be more than one for spooler-less printing)# Empty file list -> print STDINif ($#filelist < 0) { @filelist = ("<STDIN>");}# Check file listmy $file;my $filecnt = 0;for $file (@filelist) { if ($file ne "<STDIN>") { if ($file =~ /^-/) { rip_die ("Invalid argument: $file", $EXIT_PRNERR_NORETRY_BAD_SETTINGS); } elsif (! -r $file) { print $logh "File $file does not exist/is not readable\n"; splice(@filelist, $filecnt, 1); $filecnt --; } } $filecnt ++;}## When we print without spooler or with CPS do not log onto STDERR unless ## the "-v" ('Verbose') is set or the debug mode is usedif ((($spooler eq 'direct') || ($spooler eq 'cps') || ($genpdqfile)) && (!$verbose) && (!$debug)) { close $logh; open LOG, "> /dev/null"; $logh = *LOG; use IO::Handle; $logh->autoflush(1);}## Start loggingif (!$debug) { # If we are in debug mode, we do this earlier. print $logh "foomatic-rip version $ripversion running...\n"; # Print the command line only in debug mode, Mac OS X adds very many # options so that CUPS cannot handle the output of the command line # 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 "called with arguments: '", join("', '",@ARGV), "'\n"; }}## PPD file# Load the PPD file and build a data structure for the renderer's# command line and the optionsopen PPD, "$ppdfile" || do { print $logh "error opening $ppdfile.\n"; rip_die ("Unable to open PPD file $ppdfile", $EXIT_PRNERR_NORETRY_BAD_SETTINGS);};print $logh "Parsing PPD file ...\n";my $dat = {}; # data structure for the optionsmy $currentargument = ""; # We are currently reading this argument# If we have an old Foomatic 2.0.x PPD file, read its built-in Perl# data structure into @datablob and the default values in %ppddefaults# Then delete the $dat structure, replace it by the one "eval"ed from# @datablob, and correct the default settings according to the ones of# the main PPD structuremy @datablob;# Parse the PPD filesub undossify( $ );while(<PPD>) { # foomatic-rip should also work with PPD file downloaded under Windows. $_ = undossify($_); # Parse keywords if (m!^\*NickName:\s*\"(.*)$!) { # "*NickName: <code>" my $line = $1; # Store the value # Code string can have multiple lines, read all of them my $cmd = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $cmd .= substr($line, 0, -2); } else { # line ends here $cmd .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $cmd .= $1; $model = unhtmlify($cmd); } elsif (m!^\*FoomaticIDs:\s*(\S+)\s+(\S+)\s*$!) { # "*FoomaticIDs: <printer ID> <driver ID>" my $id = $1; my $driver = $2; # Store the values $dat->{'id'} = $id; $dat->{'driver'} = $driver; } elsif (m!^\*FoomaticRIPPostPipe:\s*\"(.*)$!) { # "*FoomaticRIPPostPipe: <code>" my $line = $1; # Store the value # Code string can have multiple lines, read all of them my $cmd = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $cmd .= substr($line, 0, -2); } else { # line ends here $cmd .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $cmd .= $1; $postpipe = unhtmlify($cmd); } elsif (m!^\*FoomaticRIPCommandLine:\s*\"(.*)$!) { # "*FoomaticRIPCommandLine: <code>" my $line = $1; # Store the value # Code string can have multiple lines, read all of them my $cmd = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $cmd .= substr($line, 0, -2); } else { # line ends here $cmd .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $cmd .= $1; $dat->{'cmd'} = unhtmlify($cmd); } elsif (m!^\*cupsFilter:\s*\"(.*)$!) { # "*cupsFilter: <code>" my $line = $1; # Store the value # Code string can have multiple lines, read all of them my $cmd = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $cmd .= substr($line, 0, -2); } else { # line ends here $cmd .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $cmd .= $1; my $cupsfilterline = unhtmlify($cmd); if ($cupsfilterline =~ /^\s*(\S+)\s+\d+\s+(\S+)\s*$/) { print $logh "*cupsFilter: \"$cupsfilterline\"\n"; # Make a hash by mime type for all CUPS filters set in this PPD $dat->{'cupsfilter'}{$1} = $2; } } elsif (m!^\*CustomPageSize\s+True:\s*\"(.*)$!) { # "*CustomPageSize True: <code>" my $setting = "Custom"; my $translation = "Custom Size"; my $line = $1; # Make sure that the argument is in the data structure checkarg ($dat, "PageSize"); checkarg ($dat, "PageRegion"); # Make sure that the setting is in the data structure checksetting ($dat, "PageSize", $setting); checksetting ($dat, "PageRegion", $setting); $dat->{'args_byname'}{'PageSize'}{'vals_byname'}{$setting}{'comment'} = $translation; $dat->{'args_byname'}{'PageRegion'}{'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!m) { $dat->{'args_byname'}{'PageSize'}{'vals_byname'}{$setting}{'driverval'} = $code; $dat->{'args_byname'}{'PageRegion'}{'vals_byname'}{$setting}{'driverval'} = $code; } } elsif (m!^\*(JCL|)OpenUI\s+\*([^:]+):\s*(\S+)\s*$!) { # "*[JCL]OpenUI *<option>[/<translation>]: <type>" my $argnametrans = $2; my $argtype = $3; my $argname; my $translation = ""; if ($argnametrans =~ m!^([^:/\s]+)/([^:]*)$!) { $argname = $1; $translation = $2; } else { $argname = $argnametrans; } # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the values $dat->{'args_byname'}{$argname}{'comment'} = $translation; # Set the argument type only if not defined yet, a # definition in "*FoomaticRIPOption" has priority if ( !($dat->{'args_byname'}{$argname}{'type'}) ) { if ($argtype eq "PickOne") { $dat->{'args_byname'}{$argname}{'type'} = 'enum'; } elsif ($argtype eq "PickMany") { $dat->{'args_byname'}{$argname}{'type'} = 'pickmany'; } elsif ($argtype eq "Boolean") { $dat->{'args_byname'}{$argname}{'type'} = 'bool'; } } # Mark in which argument we are currently, so that we can find # the entries for the choices $currentargument = $argname; } elsif (m!^\*(JCL|)CloseUI:\s+\*([^:/\s]+)\s*$!) { # "*[JCL]CloseUI *<option>" my $argname = $2; # Unmark the current argument to do not mis-interpret any keywords # as choices $currentargument = ""; } elsif ((m!^\*FoomaticRIPOption ([^/:\s]+):\s*(\S+)\s+(\S+)\s+(\S)\s*$!) || (m!^\*FoomaticRIPOption ([^/:\s]+):\s*(\S+)\s+(\S+)\s+(\S)\s+(\S+)\s*$!)){ # "*FoomaticRIPOption <option>: <type> <style> <spot> [<order>]" # <order> only used for 1-choice enum options my $argname = $1; my $argtype = $2; my $argstyle = $3; my $spot = $4; my $order = $5; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the values $dat->{'args_byname'}{$argname}{'type'} = $argtype; if ($argstyle eq "PS") { $dat->{'args_byname'}{$argname}{'style'} = 'G'; } elsif ($argstyle eq "CmdLine") { $dat->{'args_byname'}{$argname}{'style'} = 'C'; } elsif ($argstyle eq "JCL") { $dat->{'args_byname'}{$argname}{'style'} = 'J'; $dat->{'jcl'} = 1; } elsif ($argstyle eq "Composite") { $dat->{'args_byname'}{$argname}{'style'} = 'X'; } $dat->{'args_byname'}{$argname}{'spot'} = $spot; # $order only defined here for 1-choice enum options if ($order) { $dat->{'args_byname'}{$argname}{'order'} = $order; } } elsif (m!^\*FoomaticRIPOptionPrototype\s+([^/:\s]+):\s*\"(.*)$!) { # "*FoomaticRIPOptionPrototype <option>: <code>" # Used for numerical and string options only my $argname = $1; my $line = $2; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the value # Code string can have multiple lines, read all of them my $proto = ""; while ($line !~ m!\"!) { if ($line =~ m!&&$!) { # line continues in next line $proto .= substr($line, 0, -2); } else { # line ends here $proto .= "$line\n"; } # Read next line $line = <PPD>; chomp $line; } $line =~ m!^([^\"]*)\"!; $proto .= $1; $dat->{'args_byname'}{$argname}{'proto'} = unhtmlify($proto); } elsif (m!^\*FoomaticRIPOptionRange\s+([^/:\s]+):\s*(\S+)\s+(\S+)\s*$!) { # "*FoomaticRIPOptionRange <option>: <min> <max>" # Used for numerical options only my $argname = $1; my $min = $2; my $max = $3; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the values $dat->{'args_byname'}{$argname}{'min'} = $min; $dat->{'args_byname'}{$argname}{'max'} = $max; } elsif (m!^\*FoomaticRIPOptionMaxLength\s+([^/:\s]+):\s*(\S+)\s*$!) { # "*FoomaticRIPOptionMaxLength <option>: <length>" # Used for string options only my $argname = $1; my $maxlength = $2; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the value $dat->{'args_byname'}{$argname}{'maxlength'} = $maxlength; } elsif (m!^\*FoomaticRIPOptionAllowedChars\s+([^/:\s]+):\s*\"(.*)$!) { # "*FoomaticRIPOptionAllowedChars <option>: <code>" # Used for string options only my $argname = $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; # Make sure that the argument is in the data structure checkarg ($dat, $argname); # Store the value $dat->{'args_byname'}{$argname}{'allowedchars'} = unhtmlify($code); } elsif (m!^\*FoomaticRIPOptionAllowedRegExp\s+([^/:\s]+):\s*\"(.*)$!) { # "*FoomaticRIPOptionAllowedRegExp <option>: <code>" # Used for string options only my $argname = $1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -