如何将1992年的纯文本转换为PDF格式的PostScript修改为实际指定页面大小?

如何将1992年的纯文本转换为PDF格式的PostScript修改为实际指定页面大小?,pdf,ghostscript,postscript,plaintext,pdf-conversion,Pdf,Ghostscript,Postscript,Plaintext,Pdf Conversion,我正在尝试将纯文本文档转换为PDF。唯一接近实际工作的方法是安装“GhostScript”,然后使用下面的PostScript脚本,由SE user@RedGrittyBrick(谢谢)挖掘,它获取一个纯文本文档(在脚本下面)并从中生成PDF 它在技术上是可行的,但在视觉上会把每页的上页边距和左页边距弄得一团糟,以至于上页边距变得“太多了”,而左页边距“太少了”(与右页边距相比)。至少在苏门答腊PDF中查看时,这是我仅有的PDF查看器 脚本说明: /topmargin 1 inch def /l

我正在尝试将纯文本文档转换为PDF。唯一接近实际工作的方法是安装“GhostScript”,然后使用下面的PostScript脚本,由SE user@RedGrittyBrick(谢谢)挖掘,它获取一个纯文本文档(在脚本下面)并从中生成PDF

它在技术上是可行的,但在视觉上会把每页的上页边距和左页边距弄得一团糟,以至于上页边距变得“太多了”,而左页边距“太少了”(与右页边距相比)。至少在苏门答腊PDF中查看时,这是我仅有的PDF查看器

脚本说明:

/topmargin 1 inch def
/leftmargin 1 inch def
但是,它在视觉上看起来像文件中所说的顶部边距可能是4英寸,而不是1英寸。如果我将其修改为0,则完成的PDF在视觉上似乎有1英寸的上边距。另一方面,如果我将leftmargin修改为0英寸,它将一直延伸到左边框

在我看来,它的视觉效果是正确的,在上/右/下/左上有适当的、均匀的边距,是:

/topmargin 0 inch def
/leftmargin 0.8 inch def
但我不能就这样保存它,因为它很可能会在其他人的计算机/PDF查看器上崩溃。即使不是这样,我还是觉得很烦,我不明白到底发生了什么

我被告知发生这种情况的原因是PostScript没有指定“页面大小”。然而,我不知道我将如何在文档中详细说明这一点,也不知道脚本作者如何可能从一开始就没有这样做。这似乎是一个基本的、重大的错误,但给我的人声称已经在许多不同的环境中成功地使用了多年,那么这意味着什么呢?苏门答腊PDF有非常奇特的默认设置?这个人的标准很低?我快要疯了?我真的不知道该怎么做,也不知道该怎么解决

我认为PDF的全部要点是始终创建一个1:1的副本,在维度和呈现方式上没有任何歧义。。。显然不是。以下是脚本:

%!
%
% From: Jonathan Monsarrat (jgm@cs.brown.edu)
% Subject: PostScript -> ASCII *and* ASCII -> PostScript programs
% Newsgroups: comp.lang.postscript
% Date: 1992-10-01 04:45:38 PST 
%
% "If anyone is interested, here is an interesting program written by
% Professor John Hughes here at Brown University that formats ASCII
% in PostScript without a machine generator of any kind."
%
%%%
%%% Plan:
%%% Start with an empty string.
%%% For each character in the input stream, 
%%%    check to see if it's a carriage return.
%%%    if so, show the current string and reset it to empty
%%%    if not, add it to the current string.

/Courier findfont 10 scalefont setfont  %% Choose a fixed width font
/lineheight 
currentfont /FontBBox get dup      %% bbox bbox
0 2 getinterval    %% bbox {xm ym}
exch     %% {xm ym} bbox
2 2 getinterval    %% {xm ym} {xM yM}
aload pop    %% {xm ym} xM yM
3 2 roll     %% xM yM {xm ym}
aload pop
currentfont /FontMatrix get  %% xM yM xm ym MAT
transform    %% xM yM xm' ym'
4 2 roll
currentfont /FontMatrix get  %% xm' ym' xM yM MAT
transform    %% xm' ym' xM' yM'
exch pop     %% xm' ym' yM'
sub     %% xm' ym'-yM'
exch pop    %% dy
neg def 

lineheight pstack pop

/str 500 string def   %% Room to store a long string...
/empty 500 string def   %% An empty string to work with
/stringindex 0 def   %% How far we've filled the string
/inch {72 mul } def   %% A useful tool...
/pageheight 11 inch def
/topmargin 1 inch def
/botmargin 1 inch def
/leftmargin 1 inch def
/linesperpage pageheight topmargin sub botmargin sub lineheight div cvi def
/linenumber 1 def   %% the line we're about to write on

/newline {   %% move to a new line; flush page if necessary
   linenumber linesperpage gt {/linenumber 1 def showpage } if
   leftmargin pageheight topmargin sub linenumber lineheight mul sub moveto
   /linenumber linenumber 1 add def
} def

/cleanup {  %% print out the last bit of whatever you had there...
   str show showpage
} def

/startstring {  %% empty the string and reset its counter.
   str 0 empty putinterval
   /stringindex 0 def
} def

/showstring {  %% print the string on a new line and flush it
   newline
   str show 
   startstring
} def

pstack 

/addtostring {  %% put another character in the string, if there's room
   dup 500 gt {pop}{str exch stringindex exch put
   /stringindex stringindex 1 add def} ifelse
} def

%
% Main program: get characters and deal with them
%
{
   currentfile read {}{cleanup exit} ifelse
   dup 10 eq                   %% if it's a carriage return...
      {pop showstring}         %% write out this line of text and start over
      {dup 0 eq         %% if it's an end-of-file mark...
       {exit}                %% stop!
       {addtostring}           %% otherwise, add the character to current string
       ifelse}
      ifelse                   %% Sample data follows.
} loop
然后我运行:

ps2pdf in.ps out.pdf
)

将“纯文本文档”转换为PDF的简单方法是在您喜爱的文本编辑器中打开文档,然后从中“另存为PDF”或“打印为PDF”。它远比试图使用一个古老的后记程序可靠得多,因为它缺乏功能(这一事实清楚地证明了它不适合你)。Linux、Windows和Mac的最新版本都具有此功能,避免了您看到的问题

程序应询问解释器以发现当前媒体大小并使用该大小,而不是假设媒体大小为11英寸。或者,正如我回答您之前的问题时所说,程序应该向解释器请求给定的媒体大小。如前所述,您需要添加如下内容:

<<
  /PageSize [612 792]
>> setpagedevice
>设置页面设备
其中,数组中以“[]”分隔的数字是请求的宽度和高度,单位为点(1/72英寸)。显然,你需要把它放在主循环之前的程序中。
setpagedevice
操作符初始化图形状态并擦除页面,因此确保在绘制任何图形之前执行该操作

显然,上述要求适用于11英寸长的美国信函媒体,正如您的程序所期望的那样

你一直说PDF应该避免含糊不清,是的,它确实如此,因为PDF文件中有媒体大小。但这里的不是PDF文件,而是PostScript程序

PostScript程序不需要(在您的情况下也不需要)请求媒体大小,它可以简单地使用解释器的任何默认值。例如美国的打印机通常有美国字母,欧洲的打印机有A4。因此,当您运行PostScript程序时,它会使用当前的默认值。在美国,您的程序可能会生成一个使用美国信函的PDF文件,在欧洲,它可能是A4,因此您运行程序生成的PDF文件将使用A4。我想这就是为什么你的经历不同于最初给你这个项目的人,你的环境也不同

名称/topmargin不是神奇的,它只是一个变量名。我不知道你熟悉的编程语言,但是如果我在C++中创建了一个名为TopSurf的局部变量,我不会期望它对我的程序有任何影响,仅仅因为它被称为TopMyIn。
但这与PDF无关,它是在两个不同环境中运行程序的结果。无论您选择使用哪种PDF查看器,您创建的每个PDF文件都是一致的,但是如果这两个文件是使用两种不同的媒体大小创建的,那么这两个文件看起来会不同。

因为您有ghostscript,并且希望自动执行此操作:

#!/bin/sh
exec gs -q -sDEVICE=pdfwrite -sPAPERSIZE=letter -dNOSAFER -dNOPAUSE -sOutputFile=$1.pdf -sPROGNAME=$0 -- gslp.ps --heading-center "`date`" "$@"
请参阅gslp手册页以获取一些稍微适用的帮助

编辑:当仅转换一个文本文件时,这也适用于使用-dNOSAFER for gs 9.50及更高版本的OUG:

#!/bin/sh
exec gs -q -sDEVICE=pdfwrite -sPAPERSIZE=letter --permit-file-read="$1" -dNOPAUSE -sOutputFile=$1.pdf -sPROGNAME=$0 -- gslp.ps --heading-center "`date`" "$1"

你的问题是如何更新一个在windows时代之前就已经非常先进的GS程序,以便在现代widows X系统上工作

专家GS编写人员/维护人员试图就此提出建议,但是现在有非常简单的方法在windows中回归XY任务

Windows使用记事本处理纯文本,您只需设置一次字体和边距即可。然后自动地,右键单击“打印”或在命令行上使用prining/PT选项,然后记事本将使用任何PS驱动程序(如GhostScript pdf writer)对其进行格式化,或者更容易将MS打印为PS/pdf。另外,您应该知道苏门答腊PDF可以读取纯文本,并具有命令行打印功能,可以打印到Image.PDF

所以有一个
%SystemRoot%\system32\notepad.exe /pt "%1" "My Print to PDF"
Copy C:\MyData\PrintOut.PDF "%~dpn1.pdf"
SumatraPDF "%~dpn1.pdf"
SumatraPDF -print-to "My Print to PDF" -print-settings "paperkind=A4L" "%1"
EbookUI [
...
    UseFixedPageUI = True