1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2 /* libstaroffice
3 * Version: MPL 2.0 / LGPLv2+
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 2.0 (the "License"); you may not use this file except in compliance with
7 * the License or as specified alternatively below. You may obtain a copy of
8 * the License at http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * Major Contributor(s):
16 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
17 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
18 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
19 * Copyright (C) 2006, 2007 Andrew Ziem
20 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
21 *
22 *
23 * All Rights Reserved.
24 *
25 * For minor contributions see the git repository.
26 *
27 * Alternatively, the contents of this file may be used under the terms of
28 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
29 * in which case the provisions of the LGPLv2+ are applicable
30 * instead of those above.
31 */
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36
37 #include <librevenge/librevenge.h>
38 #include <librevenge-generators/librevenge-generators.h>
39 #include <librevenge-stream/librevenge-stream.h>
40
41 #include <libstaroffice/libstaroffice.hxx>
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #ifndef VERSION
48 #define VERSION "UNKNOWN VERSION"
49 #endif
50
51 #define TOOLNAME "sd2text"
52
printUsage()53 static int printUsage()
54 {
55 printf("`" TOOLNAME "' converts StarOffice documents to plain text.\n");
56 printf("\n");
57 printf("Usage: " TOOLNAME " [OPTION] INPUT\n");
58 printf("\n");
59 printf("Options:\n");
60 printf("\t-i show document metadata instead of the text\n");
61 printf("\t-h show this help message\n");
62 printf("\t-o OUTPUT write ouput to OUTPUT\n");
63 printf("\t-p PASSWORD set password to open the file\n");
64 printf("\t-v show version information\n");
65 printf("\n");
66 printf("Report bugs to <https://github.com/fosnola/libstaroffice/issues>.\n");
67 return 0;
68 }
69
printVersion()70 static int printVersion()
71 {
72 printf("%s %s\n", TOOLNAME, VERSION);
73 return 0;
74 }
75
main(int argc,char * argv[])76 int main(int argc, char *argv[])
77 {
78 if (argc < 2)
79 return printUsage();
80
81 char const *output = nullptr;
82 char const *password=nullptr;
83 bool isInfo = false;
84 bool printHelp=false;
85 int ch;
86
87 while ((ch = getopt(argc, argv, "hio:p:v")) != -1) {
88 switch (ch) {
89 case 'i':
90 isInfo=true;
91 break;
92 case 'o':
93 output=optarg;
94 break;
95 case 'p':
96 password=optarg;
97 break;
98 case 'v':
99 printVersion();
100 return 0;
101 default:
102 case 'h':
103 printHelp = true;
104 break;
105 }
106 }
107
108 if (argc != 1+optind || printHelp) {
109 printUsage();
110 return -1;
111 }
112 librevenge::RVNGFileStream input(argv[optind]);
113
114 STOFFDocument::Kind kind;
115 auto confidence = STOFFDocument::STOFF_C_NONE;
116 try {
117 confidence=STOFFDocument::isFileFormatSupported(&input, kind);
118 }
119 catch (...) {
120 confidence = STOFFDocument::STOFF_C_NONE;
121 }
122
123 if (confidence != STOFFDocument::STOFF_C_EXCELLENT && confidence != STOFFDocument::STOFF_C_SUPPORTED_ENCRYPTION) {
124 printf("ERROR: Unsupported file format!\n");
125 return 1;
126 }
127
128 librevenge::RVNGString document;
129 librevenge::RVNGStringVector pages;
130 bool useStringVector=false;
131 auto error = STOFFDocument::STOFF_R_OK;
132 try {
133 if (kind == STOFFDocument::STOFF_K_DRAW || kind == STOFFDocument::STOFF_K_GRAPHIC) {
134 if (isInfo) {
135 printf("ERROR: can not print info concerning a graphic document!\n");
136 return 1;
137 }
138 librevenge::RVNGTextDrawingGenerator documentGenerator(pages);
139 error=STOFFDocument::parse(&input, &documentGenerator, password);
140 if (error == STOFFDocument::STOFF_R_OK && !pages.size()) {
141 printf("ERROR: find no graphics!\n");
142 return 1;
143 }
144 useStringVector=true;
145 }
146 else if (kind == STOFFDocument::STOFF_K_SPREADSHEET || kind == STOFFDocument::STOFF_K_DATABASE) {
147 librevenge::RVNGTextSpreadsheetGenerator documentGenerator(pages, isInfo);
148 error=STOFFDocument::parse(&input, &documentGenerator, password);
149 if (error == STOFFDocument::STOFF_R_OK && !pages.size()) {
150 printf("ERROR: find no sheets!\n");
151 return 1;
152 }
153 useStringVector=true;
154 }
155 else if (kind == STOFFDocument::STOFF_K_PRESENTATION) {
156 if (isInfo) {
157 printf("ERROR: can not print info concerning a presentation document!\n");
158 return 1;
159 }
160 librevenge::RVNGTextPresentationGenerator documentGenerator(pages);
161 error=STOFFDocument::parse(&input, &documentGenerator, password);
162 if (error == STOFFDocument::STOFF_R_OK && !pages.size()) {
163 printf("ERROR: find no slides!\n");
164 return 1;
165 }
166 useStringVector=true;
167 }
168 else {
169 librevenge::RVNGTextTextGenerator documentGenerator(document, isInfo);
170 error=STOFFDocument::parse(&input, &documentGenerator, password);
171 }
172 }
173 catch (STOFFDocument::Result const &err) {
174 error=err;
175 }
176 catch (...) {
177 error = STOFFDocument::STOFF_R_UNKNOWN_ERROR;
178 }
179
180 if (error == STOFFDocument::STOFF_R_FILE_ACCESS_ERROR)
181 fprintf(stderr, "ERROR: File Exception!\n");
182 else if (error == STOFFDocument::STOFF_R_PARSE_ERROR)
183 fprintf(stderr, "ERROR: Parse Exception!\n");
184 else if (error == STOFFDocument::STOFF_R_OLE_ERROR)
185 fprintf(stderr, "ERROR: File is an OLE document!\n");
186 else if (error == STOFFDocument::STOFF_R_PASSWORD_MISSMATCH_ERROR)
187 fprintf(stderr, "ERROR: Bad password!\n");
188 else if (error != STOFFDocument::STOFF_R_OK)
189 fprintf(stderr, "ERROR: Unknown Error!\n");
190
191 if (error != STOFFDocument::STOFF_R_OK)
192 return 1;
193
194 if (!output) {
195 if (!useStringVector)
196 printf("%s", document.cstr());
197 else {
198 for (unsigned i=0; i < pages.size(); ++i)
199 printf("%s\n", pages[i].cstr());
200 }
201 }
202 else {
203 FILE *out=fopen(output, "wb");
204 if (!out) {
205 fprintf(stderr, "ERROR: can not open file %s!\n", output);
206 return 1;
207 }
208 if (!useStringVector)
209 fprintf(out, "%s", document.cstr());
210 else {
211 for (unsigned i=0; i < pages.size(); ++i)
212 fprintf(out, "%s\n", pages[i].cstr());
213 }
214 fclose(out);
215 }
216
217 return 0;
218 }
219 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
220