Как изменить этот PostScript-конвертирующий PostScript-формат с 1992 года, чтобы фактически указать размер страницы? - PullRequest
0 голосов
/ 29 января 2020

Я пытаюсь преобразовать обычный текст в PDF. Единственный метод, близкий к реальной работе, - это установить «GhostScript», а затем использовать следующий сценарий PostScript, откопанный пользователем SE @RedGrittyBrick (спасибо), который берет открытый текст (под сценарием) и создает PDF от него.

Технически это работает, но визуально портит верхнее и левое поля для каждой страницы таким образом, что верхнее поле становится «слишком много», а левое поле «слишком мало для "(по сравнению с правым полем). По крайней мере, при просмотре в SumatraPDF , который является единственным средством просмотра PDF, которое у меня есть.

Сценарий гласит:

/topmargin 1 inch def
/leftmargin 1 inch def

Однако это визуально выглядит как верхнее поле может быть 4 дюймов, а не 1 дюйм, как сказано в файле. Если я изменю его на 0, готовый PDF визуально будет иметь верхнее поле в 1 дюйм. С другой стороны, если я изменю левое поле на 0 дюймов, оно будет проходить вплоть до левой границы.

То, как оно выглядит визуально до me , с правильным, ровным поля сверху / справа / снизу / слева:

/topmargin 0 inch def
/leftmargin 0.8 inch def

Но я не могу просто так его сохранить, так как он, скорее всего, сломается на чужих компьютерах / в средствах просмотра PDF. И даже если этого не произойдет, я все еще действительно утешаю себя тем, что не понимаю, что происходит.

Мне сказали, что причина этого в том, что PostScript не указывает "страницу". размер". Тем не менее, я понятия не имею, как я могу указать это в документе, и как может быть возможно, что автор сценария никогда не делал этого в первую очередь. Это похоже на основную ошибку c, серьезную ошибку, но тот, кто дал мне его, утверждает, что успешно использовал его в течение многих лет во многих различных средах, так что это значит? Что SumatraPDF имеет очень экзотические c настройки по умолчанию? Что у данного человека очень низкие стандарты? Что я схожу с ума? Я действительно не знаю, что с этим делать или как это исправить.

Я думал, что весь смысл 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

Ответы [ 2 ]

0 голосов
/ 23 марта 2020

Поскольку у вас есть ghostscript и вы хотите сделать это автоматически:

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

См. Справочную страницу gslp для некоторой слегка применимой справки.

РЕДАКТИРОВАТЬ: это также работает без использования -dNOSAFER для GS 9.50 и выше при преобразовании только одного текстового файла:

#!/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"
0 голосов
/ 29 января 2020

)

Простой способ превратить «открытый текст» в PDF - открыть документ в вашем любимом текстовом редакторе, а затем «сохранить как PDF» или «Печатать в PDF» оттуда. Это гораздо более надежно, чем пытаться использовать древнюю программу PostScript, которая (как ясно показывает тот факт, что она не работает для вас) не имеет функций. Последние версии Linux, Windows и Ma c имеют такую ​​возможность и позволяют избежать проблем, с которыми вы сталкиваетесь.

Вместо того, чтобы считать размер носителя 11 дюймов, программа должен опросить переводчика, чтобы узнать текущий размер носителя и использовать его. Или, как я ответил на ваш предыдущий вопрос здесь , программа должна запросить у носителя переводчик определенного размера. Как я уже говорил ранее, вам нужно добавить что-то вроде:

<<
  /PageSize [612 792]
>> setpagedevice

Где числа в массиве, разделенные '[]', представляют собой запрошенную ширину и высоту в точках (1/72 дюйма). Очевидно, вам нужно поместить это в программу где-то перед основным l oop. Оператор setpagedevice инициализирует графическое состояние и стирает страницу, поэтому убедитесь, что вы делаете это до рисования чего-либо.

Вышеприведенный запрос, очевидно, относится к носителю US Letter, который равен 11 в дюймах, как и ожидает ваша программа.

Вы продолжаете утверждать, что PDF должен избегать неоднозначности, и да, так и есть, потому что файл PDF имеет размер носителя. Но здесь у вас есть не файл PDF, а программа PostScript.

Программа PostScript не должна (и в вашем случае не запрашивает) размер носителя, она может просто использовать все, что интерпретатор имеет в качестве дефолт. Например; принтеры в США обычно имеют американское письмо, принтеры в Европе имеют А4. Поэтому, когда вы запускаете вашу программу PostScript, она использует текущее значение по умолчанию. В США ваша программа, скорее всего, приведет к созданию файла PDF, в котором используется буква US, в Европе это, вероятно, будет формат A4, и поэтому файл PDF, созданный вами при запуске программы, будет использовать формат A4. Я полагаю, именно поэтому ваш опыт отличается от того, кто дал вам программу в первую очередь, ваше окружение отличается.

Имя / topmargin - это не magi c, это просто имя переменной. Я не знаю, с какими языками программирования вы знакомы, но если бы я создал локальную переменную topmargin в C ++, я бы не ожидал, что она повлияет на мою программу только потому, что она называется topmergin.

Но это не имеет ничего общего с PDF, это следствие запуска программы в двух разных средах. Каждый из созданных вами PDF-файлов будет согласованным независимо от того, какую программу просмотра PDF вы выберете, но если два файла создаются с двумя разными размерами носителей, эти два файла будут выглядеть по-разному.

...