私は同じ問題に遭遇しました。最終的に、 PDF形式の誤解が原因で、間違った方法で行っていたことに気付きました。私たちは PDF ファイルをプリンターの WYSIWYG と考えています。これはそうではありません。どのような種類の印刷フローでも、PDF ファイルは通常、中間形式のPostScript、TIFF画像、またはPCLに変換されます。
これは、ローカル マシンで発生する可能性があるため、ドライバーが必要になるか、プリンター自体で発生する可能性があります。プリンターで発生した場合は、適切な変換システムが設定された別のコンピューターに PDF ファイルを転送しているだけです。
これは、 PDF がページ順序を定義していないことを除いて、すべて問題なくダンディーです。これは、ドキュメントの最初のページがなく、どのような形やフォームでもネイティブに定義できないことを意味します。
次の 2 つの解決策があります。
プリンタ アーキテクチャを選択し、メディア タイプを設定する独自の方法を使用します。これは面倒で、移植性がありません。
PostScript など、メディア タイプの設定が可能で、ページ順序の概念を含む形式に変換します。次に、メディア コマンドを追加し、このファイルをプリンターに送信します。選択した中間形式を読み取るためのドライバーがプリンターにある場合、コマンドをそのバージョンのメディア切り替えに変換する必要があります。これはより移植性がありますが、まだ完全ではありません。
これは、 Cプログラムをアセンブリに変換して新しいアーキテクチャに移植するという考え方に似ています。ほとんどの場合は機能しますが、各システムを操作する必要があります。
仮想パイプラインは次のようになります。
PDF ファイルを作成する > PDF から PostScript への変換ユーティリティまたはライブラリを介して実行する > カスタム レクサーを実行して、新しいページごとにメディア タイプ コマンドを追加する > PostScript ファイルをプリンターに送信する
大変な作業ですが、それが問題を解決する唯一の方法です。
サンプル
%{
char paper[] = 'yourPaper';
%}
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
showpage { printf("showpage\nsetpagedevice MediaType '%s'", paper); }
%%
int main(int argc, char **argv);
int main (argc,argv)
int argc;
char **argv;
{
yylex();
return 0;
}
上記は、stdin から取得したすべての showpage コマンドを検索し、showpage setpagedevice コマンド セットを出力する、非常に単純なレクサーです。setpagedevice MediaType コマンドは、ページに使用する用紙の種類を設定するプリンターに依存しない方法です。
flexとGCCを使用してコードをコンパイルするには:
flex -Cf scanner.l
gcc -O -o lineCount.exe scanner.c
stdin を介して入力を受け入れ、stdout に出力します。
より完全なレクサーを以下に示します。コマンド ライン オプションにGNU getoptsを使用し、最初のページにもページ デバイスを設定するように 2 つのルールがあります。ページを完全に取得できない可能性があり、用紙タイプの変数が 1 つしかないため、機能が制限されます。一方、使用するページデバイスを決定したい場合は非常にオープンです。
見ているページの種類を認識するための新しいルールか、1 ページに 1 行の追加の入力ファイルの 2 つがすぐに思い浮かびます。
/*
* This file is part of flex.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**************************************************
Start of definitions section
***************************************************/
%{
/* A template scanner file to build "scanner.c". */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
/*#include "parser.h" */
//put your variables here
char FileName[256];
FILE *outfile;
char inputName[256];
char paper[] = 'yourPaper';
// flags for command line options
static int specificFile_flag = 0;
static int output_flag = 0;
static int help_flag = 0;
%}
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
/************************************************
start of rules section
*************************************************/
/* These flex patterns will eat all input */
EndSetup { printf("showpage\nsetpagedevice MediaType '%s'", paper); }
showpage { printf("showpage\nsetpagedevice MediaType '%s'", paper); }
%%
/****************************************************
Start of code section
*****************************************************/
int main(int argc, char **argv);
int main (argc,argv)
int argc;
char **argv;
{
/****************************************************
The main method drives the program. It gets the filename from the
command line, and opens the initial files to write to. Then it calls the lexer.
After the lexer returns, the main method finishes out the report file,
closes all of the open files, and prints out to the command line to let the
user know it is finished.
****************************************************/
int c;
// The GNU getopt library is used to parse the command line for flags
// afterwards, the final option is assumed to be the input file
while (1) {
static struct option long_options[] = {
/* These options set a flag. */
{"help", no_argument, &help_flag, 1},
/* These options don't set a flag. We distinguish them by their indices. */
{"useStdOut", no_argument, 0, 'o'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "o",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c) {
case 0:
/* If this option set a flag, do nothing else now. */
if (long_options[option_index].flag != 0)
break;
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case 'o':
output_flag = 1;
break;
case '?':
/* getopt_long already printed an error message. */
break;
default:
abort ();
}
}
if (help_flag == 1) {
printf("proper syntax is: traySwitch.exe [OPTIONS]... INFILE OUTFILE\n");
printf("adds tray switching information to postscript file\n\n");
printf("Option list: \n");
printf("-o sets output to stdout\n");
printf("--help print help to screen\n");
printf("\n");
printf("inputfile example: traySwitch.exe test.ps\n");
printf("If infile is left out, then stdin is used for input.\n");
printf("If outfile is a filename, then that file is used.\n");
printf("If there is no outfile, then infile-EDIT.ps is used.\n");
printf("There cannot be an outfile without an infile.\n");
return 0;
}
//Get the filename off the command line and redirect it to input
//if there is no filename or it is a - then use stdin.
if (optind < argc) {
FILE *file;
file = fopen(argv[optind], "rb");
if (!file) {
fprintf(stderr, "Flex could not open %s\n",argv[optind]);
exit(1);
}
yyin = file;
strcpy(inputName, argv[optind]);
}
else {
printf("no input file set, using stdin. Press ctrl-c to quit");
yyin = stdin;
strcpy(inputName, "\b\b\b\b\bagainst stdin");
}
//Increment current place in argument list
optind++;
/********************************************
If no input name, then output set to stdout.
If no output name then copy input name and add -EDIT.csv.
If input name is '-' then output set to stdout,
otherwise use output name.
*********************************************/
if (optind > argc) {
yyout = stdout;
}
else if (output_flag == 1) {
yyout = stdout;
}
else if (optind < argc){
outfile = fopen(argv[optind], "wb");
if (!outfile) {
fprintf(stderr, "Flex could not open %s\n",FileName);
exit(1);
}
yyout = outfile;
}
else {
strncpy(FileName, argv[optind-1], strlen(argv[optind-1])-4);
FileName[strlen(argv[optind-1])-4] = '\0';
strcat(FileName, "-EDIT.ps");
outfile = fopen(FileName, "wb");
if (!outfile) {
fprintf(stderr, "Flex could not open %s\n",FileName);
exit(1);
}
yyout = outfile;
}
yylex();
if (output_flag == 0) {
fclose(yyout);
}
printf("Flex program finished running file %s\n", inputName);
return 0;
}