Add margin to PDF file when merging using PDFTK or similar - linux

I have a large collection of half-page sized PDF cut-sheets that are held in a folder on my Linux server. A user to the site will want to create a booklet from a subset of these. The booklet will be bound therefore the even pages of the collection will want more margin on the right side and the odd pages will want more margin on the left side. There can be up to 200 pages in a collection out of a universe of 500 pages so I don't want to regenerate each page to set the margin of it. It would take too much of the servers time to run the content through the DOMPDF. Just building the document using PDFTK is fast.
I'd like to merge the document with PDFTK from a centered PDF file and add the appropriate margin for the odd or even page.
If not PDFTK then is there another tool that might do the job?

If you use ubuntu, you can install pdfcrop:
sudo apt-get install -y pdfcrop
Despite its name, pdfcrop has the option to add margins:
pdfcrop --margin '29 0 29 0' input.pdf output.pdf
(Note: the unit is bp. 72 bp = 1 inch. 29 bp is approximately 1 cm.)
Then, use pdfjam to do the offset trick for the right and left pages.
pdfjam --twoside --offset '1cm 0cm' file.pdf
Note: pdfcrop does have problems with some pdf files. (!!! Error: Ghostscript exited with error code 139!).

If you are still interested in this, you should have a look at pdfjam which allows you to offset and clip pdfs. With respect to your particular question you might do something like
pdfjam --twoside --offset '2cm 0cm' file.pdf
This shifts the even pages 2cm to the right and the odd one to the left.
pdfjam is a front end to the pdfpages package of pdflatex.

Even if it is a bit late, but it might help someone. In response to #ElkeSpaak comment, it's the package texlive-extra-utils:
dpkg-query -S /usr/bin/pdfcrop
texlive-extra-utils: /usr/bin/pdfcrop

Related

how to merge pdf as a table with pdftk or convert

How can one use convert or pdftk to merge several pdfs organized as a table?
For example, given 4 files: file1.pdf, file2.pdf, file3.pdf, file4.pdf, each of a single page, I would like to have a single-page pdf like
file1.pdf file2.pdf
file3.pdf file4.pdf
That is, the files are arranged like an array.
By far the easiest way to convert 4 PDF pages to 1 page on any OS is by N-Up imposition/printing with output to a virtual PDF printer such as Ghostscript. For the most basic 4-Up command line usage see https://stackoverflow.com/a/72850245/10802527
Thus to combine 4 pages (others such as 2 6 9 or 16 are possible) using here in a gui I can very easily set the order.
On Linux or MacOS you can use, along with other options, the CUPS command
lp -o number-up=4 filename
see https://www.cups.org/doc/options.html
The major advantage over using tools such as PDFtk with convert is that it resolves both scaling and preserving most PDF structures without degrading to inferior down-scaled imagery by NOT passing in and out of images before calling Ghostscript.
If you have single pdfs then you can merge before print using PDFtk (uses Ghostscript) instead of poppler pdfunite. Note that with either the Original PDF format is preserved.
If you want to convert to half size images and stitch them together, then reprint to one pdf page, then that can easily be done using imagemagik convert and other commands to call Ghostscript to suit your requirements direct. However, the results will in many ways be degraded by translation to image output.
Since all of the above pass through GS it makes sense, where possible, to install GS as a PDF printer driver.
If you want to avoid installing GhostScript printing then you can use cross platform Coherent cpdf (it only uses GS if the files need repairs)
Note these are "windows double quoted names" adjust as required and is based on the 4 sequential pages in one file are then to be placed 4 at a time on each new page, thus can be used with any multiple of pages in the input.pdf
cpdf -twoup "input.pdf" -o "in-2-Up-tmp.pdf"
cpdf "in-2-Up-tmp.pdf" -rotate 90 -o "out-2-Up.pdf"
cpdf -twoup "out-2-Up.pdf" -o "out-4-Up-tmp.pdf"
cpdf "out-4-Up-tmp.pdf" -rotate 90 -o "out-4-Up.pdf"

Barcodes too wide in a GoDEX printer with CUPS in Linux

I have a GoDEX RT700i printer (203 DPI) and I want to print barcodes in Linux (Ubuntu 16.04)
The barcodes I have are in PDF format. There is a 8 digit number below the barcode.
In Windows, there is no problem with GoDEX drivers. The barcodes and the number are printed perfectly.
Note: If I print the PDF from google chrome it looks fine, but if I print the PDF from Adobe Acrobat Reader, it looks like in Linux.
In Linux, when I print the barcode, the digits of the number are okay, same as Windows, and the height of the bars is okay too, but the width of every bar is bigger than the displayed in the pdf.
How can I fix this?
Here a photo of the printed barcodes
The left one has printed in Linux and the right one has printed in Windows.
There is some additional information:
For Linux I have compiled and installed the GoDEX driver for CUPS and then I have added the printer via AppSocket/HP JetDirect with the IP and Port (9100).
Then, I select the PPD file godex-rt-700i.ppd
These two lines are in the ppd file. Maybe they are related with the problem:
TTRasterizer: Type42
*cupsFilter: "application/vnd.cups-raster 50 rastertoezpl"
When I send the print order, I realized that there are 3 filters for the job:
pdftopdf (application/pdf to application/vnd.cups-pdf, cost 66)
gstoraster (application/vnd.cups-pdf to application/vnd.cups-raster, cost 99)
rastertoezpl (application/vnd.cups-raster to printer/GODEX-RT700i, cost 50)
In the rastertoezpl.c file I saw that there is a function (GDXCompress) that compress the output lines for Godex printer. I thought that maybe the compression affects somehow to the barcode and I tried to deactivate that function (CompBuffer = NULL) and recompile the driver, but that didn't fix anything.
These are the outputs of every filter:
All files (original and intermediate outputs)
When I send the original PDF file to print, these 2 files are generated by cups in /var/spool/cups/:
d00122-001 (pdf)
c00122 (unknown)
1. pdftopdf (/usr/lib/cups/filter/pdftopdf):
/usr/lib/cups/daemon/cups-exec -g 7 -n 0 -u 7 none /usr/lib/cups/filter/pdftopdf MY_PRINTER 122 my_user 00000378 1 "PageSize=Custom.56.69x65.20 Collate ColorModel=Grayscale Duplex=None job-uuid=urn:uuid:7f84fc46-1965-35d2-6a72-e2e73ab0264b job-originating-host-name=localhost date-time-at-creation= date-time-at-processing= time-at-creation=1488464765 time-at-processing=1488464765" /var/spool/cups/d00122-001 > output_pdf2pdf.pdf
output_pdf2pdf.pdf (pdf)
2.gstoraster (/usr/lib/cups/filter/gstoraster):
/usr/lib/cups/daemon/cups-exec -g 7 -n 0 -u 7 none /usr/lib/cups/filter/gstoraster MY_PRINTER 122 my_user 00000378 1 "PageSize=Custom.56.69x65.20 Collate ColorModel=Grayscale Duplex=None job-uuid=urn:uuid:7f84fc46-1965-35d2-6a72-e2e73ab0264b job-originating-host-name=localhost date-time-at-creation= date-time-at-processing= time-at-creation=1488464765 time-at-processing=1488464765"
output_gstoraster.ras (ras)
This file can be opened by rasterview program
3.rastertoezpl (/usr/lib/cups/filter/rastertoezpl):
/usr/lib/cups/daemon/cups-exec -g 7 -n 0 -u 7 none /usr/lib/cups/filter/rastertoezpl MY_PRINTER 122 my_user 00000378 1 "PageSize=Custom.56.69x65.20 Collate ColorModel=Grayscale Duplex=None job-uuid=urn:uuid:7f84fc46-1965-35d2-6a72-e2e73ab0264b job-originating-host-name=localhost date-time-at-creation= date-time-at-processing= time-at-creation=1488464765 time-at-processing=1488464765"
It doesn't create any file. It sends the printer orders directly to the printer
Versions:
Ghostscript = GPL Ghostscript 9.18 Artifex Software
cups = 2.1.3-4
pdftopdf = cups-filters 1.8.3-2ubuntu3.1
Which versions of the various components are you using (CUPS, pdftpdf and Ghostscript) ?
Have you checked the intermediate file produced from pdftopdf to see what that PDF file looks like ?
Have you examined the CUPS raster produced from gstoraster to see if it is correct ?
Exactly how big a difference are we discussing ? A pixel, an inch ? Bear in mind that this is apparently a 203 dpi device, so a pixel is quite a lot.
Given that there are 3 stages in the pipeline the first thing you should do is attempt to isolate which step is causing your problem. First capture the output at every stage; the PDF resulting from pdftopdf, then the CUPS raster file resulting from gstoraster. You can examine each of these individually to see if they show your problem. If they do not then the problem must arise from the final step 'rastertoezpl' and you'll need someone who knows that code. Otherwise you'll be able to decide whether the problem is the pdftopdf step, or the gstoraster step. In any event you can then ask for specific help.
Its most unlikely that the content of the PPD file has any impact here (other than specifying the final filter required to drive the printer). Of course, without seeing the original file, its hard to tell, possibly the barcode is a TrueType font.....
[edit]
Well I still can't see a Ghostscript command line in your question. I'm not able to run CUPS and I can't build RasterView either since it requires a bunch of dependencies I simply don't have.
However, I can run it to TIFF. The result is the same as your photo when the resolution is low enough.
Your problem is the one described in comments 17 and 18 in the bug thread I posted in my comment below. The PostScript (and PDF) imaging model says that when any part of a pixel is touched, that whole pixel is rendered to the output.
Your PDF draws the barcodes as a series of (vector) rectanlges, using co-ordinates and sizes which are not precisely aligned on the underlying pixels of the device.
If you use Adobe Acrobat and 'save as' TIFF you will see exactly the same problem there (you need to set the resolution of the output to 203 dpi using the 'Settings' button on the 'save as' dialog).
There is a long discussion on the bug thread about this, there are a number of possible solutions;
Write the PostScript (or PDF) so that the co-ordinates are precisely clamped to the device grid. This may be difficult to do, especially if you run the file through pdf2pdf.
Draw the bars by first drawing a big rectangle, then draw the spaces between bars as white.that might make the bars 'skinny' but they won't merge. If the printer is thermal then the thermal spread will reduce the effect.
Generate the barcode as an image instead of vectors. Images don't follow the 'any part of pixel rule', they use 'centre of pixel' instead, which may give (at least slightly) better results.
Use a barcode font. Fonts also use a different method for drawing, because if you reduce the font size it quickly turns into a series of black blobs if you use any part of pixel.
Basically, you are trying to draw shapes to a tolerance which simply isn't possible on a low-resolution device like this, when using PostScript/PDF.

Pulling elements from an SVG file apart

I am using http://www.jasondavies.com/wordcloud to generate a word cloud in SVG format. Unfortunately the generator deletes all \ characters, which is bad since I want to 'wordcloudize' a list of TeX primitives.
I'd like to increase the spacing between the elements of the SVG automatically to be able to add \ manually in the SVG file. Is there any SVG-transformation which moves the elements away from the center while leaving the size of the elements as they are?
The much simpler solution is to download the page and its scripts to your local machine. Open the local page and check that it still works.
Then open the cloud.js file and comment out the line:
word = word.replace(punctuation, "");
I think that should work.

How do you programmatically - or from CLI - rotate a PDF?

What I need to be able to do is to rotate a PDF clockwise or counter clockwise either programmatically or from the CLI.
I have spent considerable time researching and attempting to rotate PDFs with GhostScript (as GS is already installed for other reasons) to no avail, nothing seems result in any rotation.
I have looked into using pdftk but it requires java libraries, and I would rather not have java installed on the system.
We've even looked at modifying the PDF file ourselves, and we have had some success with this, but we haven't come across a reliable method that works for all PDFs.
So my #1 preference would be to achieve this with existing resources on the system.
My #2 preference would be to do a little modification to the existing system as possible to achieve this.
The server in question is using Linux (OpenSuse 11) with PHP 5.2 and I have Ghostscript 9.0 installed.
Any advice would be much appreciated.
You can use pdfpages LaTeX package
\documentclass{article}
\usepackage{pdfpages}
\begin{document}
\includepdf[angle=45]{document.pdf}
\end{document}
The LaTeX document above, compiled via pdflatex, produces a document rotated 45 degrees.
There are also tools (wrappers of pdfpages) like pdfjam that can be used directly from command line:
$ pdfjam --suffix rotated45 --angle 45 --fitpaper true document.pdf
There is a way to do this with ImageMagick, if that's available to you.
Example:
$ convert originalfile.pdf -rotate <cw_angle_degrees> newfile.pdf
Note, however, that since this is a raster-based rotation, there will (generally) be a noticeable loss of quality AND increase in filesize.
You haven't said how you are trying to do this with Ghostscript, but if you want to use the pdfwrite device you will need to set /AutoRotatePages=/None or it will rotate the final page so that the majorty of any real text is horizontal.

print a big, landscape PDF drawing to a3 LaserJet4 (portrait) using ghostscript 9.0

We want to print big drawings (up to A0 and some times longer) to A3 printers using ghostscript:
gs -o - -sDEVICE=pdfwrite -r1200x1200 -sPAPERSIZE=a3 -f
/S/tmp/SamplePDFnewStamp.pdf | gs -o resized.pcl -sDEVICE=ljet4
-g7012x4961 -dPDFFitPage -
I get A4 landscape on an A3 portrait Paper. I also tried to rotate:
gs -sOutputFile="-" -sDEVICE=pdfwrite -r1200x1200 -sPAPERSIZE=a3 -d
-dBATCH -dNOPAUSE -dAutoRotatePages=/None -dPDFFitPage -c "<</Orientation 1>> setpagedevice 90 rotate 0 -595 translate" -f
/S/tmp/SamplePDFnewStamp.pdf -c quit | gs -o resized.pcl
-sDEVICE=ljet4 -g7012x4961 -dPDFFitPage -
getting the same result.
Its not really possible to comment without seeing a PDF file, but a number of the command line options you are using there don't make sense in the combination you have.
The first thing I would do is stop piping the commands like that, at least while investigating the problem. Do it as 2 stages, that will allow you (and others) to look at the intermediate PDF file.
Secondly, I don't believe you can do what you seem to be trying to do. It looks like you are trying to pipe the PDF produced by the first invocation of gs through the second invocation. I don't see any way that will work, the pdfwrite device needs to seek around the file in order to create the xref table, it cannot use stdout, at least in the current version. What version of Ghostscript are you using ?
I also can't see the point of this, why take a PDF, make a new PDF from it, and then render the second PDF ? Why not just render the original ?
None of the media size switches you are specifying will have any effect, because you haven't told Ghostscript that the media size is fixed (using -dFIXEDMEDIA). As a result the PDF interpreter will set the media size to be the same as the MediaBox in the PDF file. Similar problems apply with sending PostScript and expecting it to alter the behaviour of Ghostscript when rendering a PDF file.
Setting the resolution for pdfwrite is not a good idea, and will in general have no effect. Even if it does have an effect, you probably don't want to set it to be the resolution of the device (and the -g values seem to suggest this is not a 1200 dpi device either). The only effect the resolution has is when objects have to be rendered to images because the can't be represented in PDF. You don't want to create images at the printer resolution, somewhere between one quarter and one half the resolution is usually sufficient.
If you'd care to share an example PDF file, I may be able to tell you how to solve your orientation problem. You will need to explain why you are running it through pdfwrite before going to PCL though, I can't see any reason for that.
This:
gs -sDEVICE=pdfwrite -sOutputFile=\temp\out.pdf -dDEVICEHEIGHTPOINTS=2386.08 -dDEVICEWIDTHPOINTS=1685.7600 -dFIXEDMEDIA -dPDFFitPage SamplePDFnewStamp.pdf
Will take your original PDF file and produce a PDF file rotated by 90 degrees. If I then do:
gs -sDEVICE=ljet4 -sOutputFile=\temp\out.pcl \temp\out.pdf
I get a PCL file that, when processed by GhostPDL with appropriate media size, seems to do what you want.
I haven't tried it, due to lack of an actual device to print on, but I would expect that:
gs -sDEVICE=ljet4 -sOutputFile=\temp\out.pcl -dDEVICEHEIGHTPOINTS=2386.08 -dDEVICEWIDTHPOINTS=1685.7600 -dFIXEDMEDIA -dPDFFitPage SamplePDFnewStamp.pdf
would produce the same file in one step.
I found a solution:
gs -q -sDEVICE=ljet4 -sOutputFile=out.pcl -dFIXEDMEDIA -dPDFFitPage -sPAPERSIZE=a3 \-c "<</Install {-1 -1 scale -843 -1192 translate}>> setpagedevice" -f SamplePDFnewStamp.pdf -c quit

Resources