]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/pdftotext.cc
2d293b461a9197b80288ef3e1c1a47ed4387595a
[evince.git] / pdf / xpdf / pdftotext.cc
1 //========================================================================
2 //
3 // pdftotext.cc
4 //
5 // Copyright 1997 Derek B. Noonburg
6 //
7 //========================================================================
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stddef.h>
12 #include <string.h>
13 #include "parseargs.h"
14 #include "GString.h"
15 #include "gmem.h"
16 #include "Object.h"
17 #include "Stream.h"
18 #include "Array.h"
19 #include "Dict.h"
20 #include "XRef.h"
21 #include "Catalog.h"
22 #include "Page.h"
23 #include "PDFDoc.h"
24 #include "TextOutputDev.h"
25 #include "Params.h"
26 #include "Error.h"
27 #include "config.h"
28
29 static int firstPage = 1;
30 static int lastPage = 0;
31 static GBool useASCII7 = gFalse;
32 static GBool useLatin2 = gFalse;
33 static GBool useLatin5 = gFalse;
34 #if JAPANESE_SUPPORT
35 static GBool useEUCJP = gFalse;
36 #endif
37 static GBool rawOrder = gFalse;
38 static char userPassword[33] = "";
39 static GBool printVersion = gFalse;
40 static GBool printHelp = gFalse;
41
42 static ArgDesc argDesc[] = {
43   {"-f",      argInt,      &firstPage,     0,
44    "first page to convert"},
45   {"-l",      argInt,      &lastPage,      0,
46    "last page to convert"},
47   {"-ascii7", argFlag,     &useASCII7,     0,
48    "convert to 7-bit ASCII (default is 8-bit ISO Latin-1)"},
49   {"-latin2", argFlag,     &useLatin2,     0,
50    "convert to ISO Latin-2 character set"},
51   {"-latin5", argFlag,     &useLatin5,     0,
52    "convert to ISO Latin-5 character set"},
53 #if JAPANESE_SUPPORT
54   {"-eucjp",  argFlag,     &useEUCJP,      0,
55    "convert Japanese text to EUC-JP"},
56 #endif
57   {"-raw",    argFlag,     &rawOrder,      0,
58    "keep strings in content stream order"},
59   {"-upw",    argString,   userPassword,   sizeof(userPassword),
60    "user password (for encrypted files)"},
61   {"-q",      argFlag,     &errQuiet,      0,
62    "don't print any messages or errors"},
63   {"-v",      argFlag,     &printVersion,  0,
64    "print copyright and version info"},
65   {"-h",      argFlag,     &printHelp,     0,
66    "print usage information"},
67   {"-help",   argFlag,     &printHelp,     0,
68    "print usage information"},
69   {NULL}
70 };
71
72 int main(int argc, char *argv[]) {
73   PDFDoc *doc;
74   GString *fileName;
75   GString *textFileName;
76   GString *userPW;
77   TextOutputDev *textOut;
78   TextOutputCharSet charSet;
79   GBool ok;
80   char *p;
81
82   // parse args
83   ok = parseArgs(argDesc, &argc, argv);
84   if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
85     fprintf(stderr, "pdftotext version %s\n", xpdfVersion);
86     fprintf(stderr, "%s\n", xpdfCopyright);
87     if (!printVersion) {
88       printUsage("pdftotext", "<PDF-file> [<text-file>]", argDesc);
89     }
90     exit(1);
91   }
92   fileName = new GString(argv[1]);
93
94   // init error file
95   errorInit();
96
97   // read config file
98   initParams(xpdfConfigFile);
99
100   // open PDF file
101   xref = NULL;
102   if (userPassword[0]) {
103     userPW = new GString(userPassword);
104   } else {
105     userPW = NULL;
106   }
107   doc = new PDFDoc(fileName, userPW);
108   if (userPW) {
109     delete userPW;
110   }
111   if (!doc->isOk()) {
112     goto err;
113   }
114
115   // check for copy permission
116   if (!doc->okToCopy()) {
117     error(-1, "Copying of text from this document is not allowed.");
118     goto err;
119   }
120
121   // construct text file name
122   if (argc == 3) {
123     textFileName = new GString(argv[2]);
124   } else {
125     p = fileName->getCString() + fileName->getLength() - 4;
126     if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
127       textFileName = new GString(fileName->getCString(),
128                                  fileName->getLength() - 4);
129     } else {
130       textFileName = fileName->copy();
131     }
132     textFileName->append(".txt");
133   }
134
135   // get page range
136   if (firstPage < 1) {
137     firstPage = 1;
138   }
139   if (lastPage < 1 || lastPage > doc->getNumPages()) {
140     lastPage = doc->getNumPages();
141   }
142
143   // write text file
144 #if JAPANESE_SUPPORT
145   useASCII7 |= useEUCJP;
146 #endif
147   charSet = textOutLatin1;
148   if (useASCII7) {
149     charSet = textOutASCII7;
150   } else if (useLatin2) {
151     charSet = textOutLatin2;
152   } else if (useLatin5) {
153     charSet = textOutLatin5;
154   }
155   textOut = new TextOutputDev(textFileName->getCString(), charSet, rawOrder);
156   if (textOut->isOk()) {
157     doc->displayPages(textOut, firstPage, lastPage, 72, 0, gFalse);
158   }
159   delete textOut;
160
161   // clean up
162   delete textFileName;
163  err:
164   delete doc;
165   freeParams();
166
167   // check for memory leaks
168   Object::memCheck(stderr);
169   gMemReport(stderr);
170
171   return 0;
172 }