Jak utworzyć pusty plik PDF z wiersza polecenia?

57

Niedawno potrzebowałem jednej pustej strony PDF (rozmiar 8,5 x 11 cali) i zdałem sobie sprawę, że nie wiem, jak zrobić ją z wiersza poleceń.

Wydanie touch blank.pdfpowoduje powstanie pustego pliku PDF . Czy istnieje narzędzie wiersza polecenia, które generuje pustą stronę PDF ?

Brian Fitzpatrick
źródło
A po co ci to? Mam pakiet drukowania do emulacji drukowania dwustronnego (dupleks) na drukarkach innych niż dupleks. W tym celu należy wydrukować dodatkową pustą stronę podczas drukowania stron parzystych dla zadania, które ma nieparzystą liczbę stron. Aby to zrobić, po prostu wysyłam formularz do lp. To załatwia sprawę bez tworzenia pustego pliku strony itp.
Joe
10
@Joe To nie jest nasza sprawa, dlaczego Brian tego chce lub potrzebuje.
Iain Holder
6
@IndHolder: Chciałbym, aby więcej użytkowników SE myślało tak jak ty.
Mehrdad
3
@IndHolder - Nie próbuję wtrącać się w działalność OP! Chciałem tylko zasugerować, że jeśli jest to coś, co robiłem, to jest inny sposób, aby to zrobić. Często takie rzeczy to problemy xy ( meta.stackexchange.com/questions/66377/what-is-the-xy-problem ), więc pytanie o cel może być całkiem odpowiednie.
Joe
5
Właśnie przeczytałem szczegółowo powyższy link. Nie zdawałem sobie sprawy, że to taka kontrowersyjna kwestia. TL; DR - jeśli wiesz, co robisz, to potrzebujesz odpowiedzi na zadane pytanie. Jeśli nie znasz się tak dobrze, być może zadałeś niewłaściwe pytanie, a wyjaśnienie, na czym polega prawdziwy problem, może pomóc.
Joe

Odpowiedzi:

85

convert, narzędzie ImageMagick użyte w odpowiedzi Ketana, pozwala również napisać coś podobnego

convert xc:none -page Letter a.pdf

lub

convert xc:none -page A4 a.pdf

lub (dla poziomego papieru A4)

convert xc:none -page 842x595 a.pdf

itp. , bez tworzenia pustego pliku tekstowego. @chbrown zauważył, że tworzy to mniejszy plik pdf.

„xc:” oznacza „X Stały obraz”, ale tak naprawdę można go uznać za „x płótno”. Jest to sposób na określenie pojedynczego bloku koloru, w tym przypadku żadnego. Więcej informacji na stronie http://imagemagick.org/Usage/canvas/#solid, która jest „de facto” instrukcją dla ImageMagick. [uzupełnione informacjami z rurą] (Takie rzeczy pdf:amogą być wykorzystane do jawnie zadeklarować format pliku. label:'some text', gradient:, rose:i logo: wydają się być inne przykłady specjalnych formatów plików).

Anko zasugerowała opublikowanie tej modyfikacji jako osobnej odpowiedzi, więc to robię.

BartekChom
źródło
2
ImageMagick tak naprawdę nie ma przydatnej instrukcji. „xc: <foo>” oznacza „X Stały obraz”, ale tak naprawdę można go traktować jako „x canvas”. Jest to sposób na określenie pojedynczego bloku koloru, w tym przypadku żadnego . Więcej informacji na imagemagick.org/Usage/canvas/#solid, który jest „de facto” instrukcją dla ImageMagick.
rura
2
Nawiasem mówiąc, działa to również z A4 zamiast Letter, jeśli chcesz rozsądnych rozmiarów papieru.
TRiG
@TRiG: Oczywiście. Przykro mi, że nie wspomniałem o tobie w moim wydaniu, ale w tym przypadku o tym wiedziałem.
BartekChom 21.04.16
Zmieniłem to na zaakceptowaną odpowiedź, ponieważ jest to ta, którą umieściłem~/bin
Brian Fitzpatrick
Czy to polecenie można zmienić, aby utworzyć plik pdf zawierający n pustych stron?
Brian Fitzpatrick,
34

Podobnie jak najmniejszy możliwy GIF , należy ręcznie opracować najmniejszy możliwy pusty plik PDF, ponieważ jest tak mały, że niepotrzebne, ale nieszkodliwe fragmenty metadanych stają się znaczną częścią rozmiaru pliku, a kompresja faktycznie powiększa . Wymaga to również starannego zwrócenia uwagi na reguły w specyfikacji PDF dotyczące tego, jakie bity struktury pliku są i nie są wymagane. (Czy wiesz, że obiekty strony muszą zawierać /Resourcessłownik, nawet jeśli jest pusty, ale nie muszą zawierać /Contentsstrumienia?)

Jeśli nie korzystasz ze strumieni obiektów PDF i strumieni odsyłaczy (co ma tę zaletę, że plik można w całości wydrukować w formacie ASCII), uważam, że najlepiej jest zrobić 317 bajtów. W przypadku kopiowania i wklejania, zwróć uwagę, że nie musi być spacją na wszystkich czterech wpisów tabeli odsyłaczy (granice pomiędzy 0 4i trailer<<...), i że nie jest nie ma być końcowy znak nowej linii po %%EOF.

%PDF-1.4
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj
3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj
xref
0 4
0000000000 65535 f 
0000000009 00000 n 
0000000052 00000 n 
0000000101 00000 n 
trailer<</Size 4/Root 1 0 R>>
startxref
178
%%EOF

Zastąpienie tabeli odsyłaczy ręcznie spreparowanym strumieniem odsyłaczy w wersji 1.5 sprawia, że ​​plik jest nieco mniejszy, a cena nie jest już możliwa do wydrukowania w ASCII: 294 bajtów. (Ze względu na czytelność, nie mówiąc już o możliwości wpisania go, poniższy strumień odnośników został zrzucony heksadecymalnie, ale nie znajduje to odzwierciedlenia w słowniku strumieni. Aby odzyskać prawidłowy plik PDF, należy albo zastąpić zrzut heksowy odpowiadająca surowych bajtów binarnych, lub zmienić /Length 15na /Length 30/Filter/ASCIIHexDecodei zaakceptować plik o długości 328 bajtów).

%PDF-1.5
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj
3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj
4 0 obj<</Type/XRef/Size 5/W[1 1 1]/Root 1 0 R/Length 15>>stream
0000ff01090001340001650001b200endstream endobj
startxref
178
%%EOF

Eksperymentowałem również z zawijaniem obiektów od 1 do 3 w strumień obiektów, ale to dodaje więcej narzutu niż oszczędza, nawet gdy strumień jest skompresowany.

Możliwe alternatywne sformułowanie strumienia odnośnika zewnętrznego to

4 0 obj<</Type/XRef/Size 4/W[0 1 0]/Index[1 4]/Root 1 0 R/Length 4>>stream
091365b2endstream endobj

Niestety, pomimo znacznych oszczędności w długości rzeczywistych danych strumienia, dodatkowe /Index[1 4]zjadają wszystkie oprócz jednego bajta oszczędności. Ponadto nie jest dla mnie jasne, czy wolno pozostawić obiekt 0 całkowicie poza plikiem. (Nie jest też dla mnie jasne, czy obiekt 0 musi mieć numer generacji -1. Jeśli nie jest to wymagane, faktycznie zapisujesz więcej bajtów za pomocą

4 0 obj<</Type/XRef/Size 5/W[1 1 0]/Root 1 0 R/Length 10>>stream
000001090134016501b2endstream endobj

.)

Aby zmienić rozmiar papieru, zamień 612 792na odpowiednią szerokość i wysokość, wyrażoną w punktach PostScript (72 punkty PostScript = 1 cal amerykański lub 25,4 milimetra). Na przykład 595 842dla A4. Możesz to osadzić w skrypcie powłoki, który wyrzuca pusty plik PDF o dowolnym rozmiarze papieru; jedyną trudną częścią byłoby upewnienie się, że startxrefprzesunięcie pozostaje dokładne, nawet jeśli zmieni się rozmiar obiektu 3.

zwol
źródło
10
To może być zabawna aktywność dla codegolf.stackexchange.com
Nate Eldredge
5
Wysłałem do meta.codegolf, aby sprawdzić, czy coś takiego zostanie dobrze przyjęte: meta.codegolf.stackexchange.com/questions/8990/...
Nate Eldredge
Chociaż jest to dobre rozwiązanie, aby utworzyć prawidłowy dokument PDF z pustą stroną w edytorze tekstu , nie jest to dokładnie to, co uważam za rozwiązanie wiersza polecenia (o co poprosił PO).
Kurt Pfeifle
23

Jeśli masz convert(narzędzie ImageMagick) zainstalowane, możesz to zrobić:

touch a.txt && convert a.txt -page Letter a.pdf
mkc
źródło
1
convertma również -sizeopcję, za pomocą której można ustawić rozmiar wyjściowego pliku pdf.
mkc 20.04.16
21
Możesz także pisać convert xc:none -page Letter a.pdfbez tworzenia pustego pliku txt.
BartekChom 20.04.16
3
Metoda @ BartekChom wydaje się tworzyć jeszcze czystszą pustą stronę. Tworzy mniejszy plik, absolutnie nic do wyboru, i nie powoduje żadnych (null)błędów czcionek.
chbrown 20.04.16
1
@BartekChom Chcę to jako osobna odpowiedź, aby móc ją głosować.
Anko
1
Mam convert.im6: improper image header a.txt '@ error / txt.c / ReadTXTImage / 429. convert.im6: brak zdefiniowanych obrazówa.pdf' @ error/convert.c/ConvertImageCommand/3044.
Sigur
12

echo .bp | groff -T pdf > t.pdf

Dostarczone przez groff, najbardziej niedocenione oprogramowanie na świecie.

James K. Lowden
źródło
2
Dostaję groff: can't find `DESC' filewraz groff:fatal error: invalid device `pdf'z groff w wersji 1.22.2 na CentOS 7.2.
gla3dr 21.04.16
Ta sama wiadomość dla mnie za pomocą bash 4.1.2bieganiagroff 1.18.1.4
zundarz
2
@ gla3dr Zainstaluj pełny pakiet groff, a nie tylko groff-base.
Kapitan Giraffe
1
.bpoznacza po prostu „stronę podziału”, dlatego powstaje 2-stronicowy dokument. Aby utworzyć jednostronicowy dokument, zrób jeszcze prostsze echo | groff -T pdf > blank.pdf.
Faheem Mitha,
bardzo fajne rozwiązanie, ale echo .bprzeczywiście powinno zostać zastąpione echo, tak jak powiedział
@FaheemMitha
8

Możesz użyć pdfTeX:

echo '\shipout\hbox{}\end' | pdftex

co daje pustą pojedynczą stronę texput.pdfo wielkości około 900 bajtów, co stanowi połowę tego, co wykorzystuje ImageMagick.

To jednak stawia Cię na łasce domyślnego rozmiaru papieru w instalacji TeXa. Aby jawnie ustawić rozmiar, możesz zamiast tego przejść do LaTeX:

echo '\documentclass[letterpaper]{article}\usepackage[pass]{geometry}
      \begin{document}\shipout\hbox{}\end{document}' | pdflatex

Jeszcze inną opcją byłoby użycie sterownika PDF Ghostscript, choć przydatny ps2pdfskrypt:

echo showpage | ps2pdf -sPAPERSIZE=letter - blank.pdf

co jest znacznie cichsze niż TeX, ale daje mniej zwartą moc wyjściową (około 2300 bajtów).

Henning Makholm
źródło
1
Używam wariantu echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf. Jest to nieco mniejszy, ma 2200 bajtów.
Faheem Mitha
echo '\documentclass[letterpaper]{article}\usepackage[pass]{geometry} \begin{document}\shipout\hbox{}\end{document}' | pdflatextworzy article.pdf. Czy możliwe jest utworzenie go blank.pdfbezpośrednio?
Faheem Mitha
@FaheemMitha: Hmm, spodziewałbym się, że ps2pdf z pustym wejściem wygeneruje plik PDF zawierający zero stron - ale kiedy próbuję, rzeczywiście jest tam strona. Zastanawiam się, skąd to pochodzi ...
Henning Makholm
@Faheem: Przy pomocy Texlive możesz przynajmniej ustawić nazwę pliku wyjściowego -jobname <basename>w wierszu poleceń.
Henning Makholm
1
@FaheemMitha: Każda \shipout\hbox{}lub showpagetworzy jedną stronę. Zarówno TeX, jak i Postscript mają konstrukcje zapętlające, których można użyć, ale prawdopodobnie łatwiej jest użyć wybranego języka skryptowego do powielenia polecenia odpowiednią liczbę razy.
Henning Makholm
3

Prostym sposobem na utworzenie pliku PDF z pustą stroną jest użycie rst2pdf:

echo -e '.. raw:: pdf\n\n   PageBreak' | rst2pdf -o blank.pdf

po prostu echo w jednym miejscu nie zadziała, skończy się to plikiem PDF bez stron (co nie jest tym samym co pusty plik).

Anthon
źródło
2

W wierszu polecenia wpisz:

ps2pdf blank.pdf

polecenie ps2pdfsłuży do konwersji pliku PostScript na pdf

ps2pdf file.ps file.pdf
GAD3R
źródło
1
ps2pdf blank.pdfzwraca błąd, ponieważ oczekuje pliku Postscript jako argumentu. Drugie polecenie wymaga wcześniejszego istnienia file.pdf. Czy coś brakuje?
Faheem Mitha,
1
Spróbuj tego: 1 touch blank.ps.; 2 ps2pdf blank.ps blank.pdf.; 3.pdftk A=1.pdf B=blank.pdf cat A1-end B output 2.pdf
Victoria Stuart,
2

Na koniec, oto sposób Ghostscript na utworzenie pliku PDF pokazującego pustą stronę:

 gs -sDEVICE=pdfwrite -o empty.pdf -c showpage

Rozmiar strony najprawdopodobniej będzie wynosił Letter. Jeśli chcesz A4, użyj tego:

 gs -sDEVICE=pdfwrite -o empty.pdf -g5950x8420 -c showpage

Tło: po -cparametrze może być dowolny prawidłowy ciąg PostScript, który Ghostscript spróbuje zinterpretować. A pusta strona w PostScript jest reprezentowana przez ten krótki blok kodu:

%!PS
showpage
Kurt Pfeifle
źródło