fix(libreoffice): use separate input/output filters and add Calc category
LibreOffice Writer has no CSV export filter. The shared filter map used Text for csv in both directions, which made any Writer-category conversion to csv fail with: no export filter for <file>.csv found, aborting. Root cause: getFilters() looked up the same filters map for the infilter and the outfilter. Text is a valid *input* filter for reading delimiter- separated files in Writer but is not accepted as an *output* filter for the .csv extension. Fix: - Split into separate inputFilters / outputFilters maps so csv can remain readable by the text (Writer) category without offering it as a write target there. - Remove csv from properties.to.text so the UI/router no longer exposes the unsupported Writer → CSV path. - Populate the previously-empty filters.calc with correct LibreOffice Calc filter names and add spreadsheet formats to properties.from.calc / properties.to.calc, enabling conversions such as xlsx → csv, csv → xlsx, ods → xlsx, etc. via the Calc module. Fixes #561 Signed-off-by: Radhakrishnan Pachyappan <gingeekrishna@gmail.com>
This commit is contained in:
parent
0965928949
commit
089105fd09
2 changed files with 150 additions and 7 deletions
|
|
@ -46,10 +46,29 @@ export const properties = {
|
||||||
"xml",
|
"xml",
|
||||||
"zabw",
|
"zabw",
|
||||||
],
|
],
|
||||||
|
calc: [
|
||||||
|
"csv",
|
||||||
|
"dbf",
|
||||||
|
"dif",
|
||||||
|
"fods",
|
||||||
|
"ods",
|
||||||
|
"ots",
|
||||||
|
"sxc",
|
||||||
|
"stc",
|
||||||
|
"sylk",
|
||||||
|
"tab",
|
||||||
|
"tsv",
|
||||||
|
"xls",
|
||||||
|
"xlsb",
|
||||||
|
"xlsm",
|
||||||
|
"xlsx",
|
||||||
|
"xlt",
|
||||||
|
"xltm",
|
||||||
|
"xltx",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
to: {
|
to: {
|
||||||
text: [
|
text: [
|
||||||
"csv",
|
|
||||||
"doc",
|
"doc",
|
||||||
"docm",
|
"docm",
|
||||||
"docx",
|
"docx",
|
||||||
|
|
@ -72,12 +91,25 @@ export const properties = {
|
||||||
"xhtml",
|
"xhtml",
|
||||||
"xml",
|
"xml",
|
||||||
],
|
],
|
||||||
|
calc: [
|
||||||
|
"csv",
|
||||||
|
"fods",
|
||||||
|
"html",
|
||||||
|
"ods",
|
||||||
|
"ots",
|
||||||
|
"xls",
|
||||||
|
"xlsx",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type FileCategories = "text" | "calc";
|
type FileCategories = "text" | "calc";
|
||||||
|
|
||||||
const filters: Record<FileCategories, Record<string, string>> = {
|
// Separate input and output filter maps because some formats (e.g. csv) are
|
||||||
|
// readable by LibreOffice Writer but cannot be exported by it — Writer has no
|
||||||
|
// CSV export filter. Using a unified map caused "no export filter found" when
|
||||||
|
// converting any Writer document to CSV (issue #561).
|
||||||
|
const inputFilters: Record<FileCategories, Record<string, string>> = {
|
||||||
text: {
|
text: {
|
||||||
"602": "T602Document",
|
"602": "T602Document",
|
||||||
abw: "AbiWord",
|
abw: "AbiWord",
|
||||||
|
|
@ -120,16 +152,71 @@ const filters: Record<FileCategories, Record<string, string>> = {
|
||||||
xml: "OpenDocument Text Flat XML",
|
xml: "OpenDocument Text Flat XML",
|
||||||
zabw: "AbiWord",
|
zabw: "AbiWord",
|
||||||
},
|
},
|
||||||
calc: {},
|
calc: {
|
||||||
|
csv: "Text - txt - csv (StarCalc)",
|
||||||
|
dbf: "dBase",
|
||||||
|
dif: "DIF",
|
||||||
|
fods: "OpenDocument Spreadsheet Flat XML",
|
||||||
|
html: "HTML (StarCalc)",
|
||||||
|
ods: "calc8",
|
||||||
|
ots: "calc8_template",
|
||||||
|
sxc: "StarOffice XML (Calc)",
|
||||||
|
stc: "calc_StarOffice_XML_Calc_Template",
|
||||||
|
sylk: "SYLK",
|
||||||
|
tab: "Text - txt - csv (StarCalc)",
|
||||||
|
tsv: "Text - txt - csv (StarCalc)",
|
||||||
|
xls: "MS Excel 97",
|
||||||
|
xlsb: "Calc MS Excel 2007 Binary",
|
||||||
|
xlsm: "Calc MS Excel 2007 VBA XML",
|
||||||
|
xlsx: "Calc MS Excel 2007 XML",
|
||||||
|
xlt: "MS Excel 97 Vorlage/Template",
|
||||||
|
xltm: "Calc MS Excel 2007 VBA XML Template",
|
||||||
|
xltx: "Calc MS Excel 2007 XML Template",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const outputFilters: Record<FileCategories, Record<string, string>> = {
|
||||||
|
text: {
|
||||||
|
// csv intentionally absent: LibreOffice Writer has no CSV export filter
|
||||||
|
doc: "MS Word 97",
|
||||||
|
docm: "MS Word 2007 XML VBA",
|
||||||
|
docx: "MS Word 2007 XML",
|
||||||
|
dot: "MS Word 97 Vorlage",
|
||||||
|
dotx: "MS Word 2007 XML Template",
|
||||||
|
dotm: "MS Word 2007 XML Template",
|
||||||
|
epub: "EPUB",
|
||||||
|
fodt: "OpenDocument Text Flat XML",
|
||||||
|
htm: "HTML (StarWriter)",
|
||||||
|
html: "HTML (StarWriter)",
|
||||||
|
odt: "writer8",
|
||||||
|
ott: "writer8_template",
|
||||||
|
rtf: "Rich Text Format",
|
||||||
|
tab: "Text",
|
||||||
|
tsv: "Text",
|
||||||
|
txt: "Text",
|
||||||
|
wps: "MS Word 97",
|
||||||
|
wpt: "MS Word 97 Vorlage",
|
||||||
|
xhtml: "HTML (StarWriter)",
|
||||||
|
xml: "OpenDocument Text Flat XML",
|
||||||
|
},
|
||||||
|
calc: {
|
||||||
|
csv: "Text - txt - csv (StarCalc)",
|
||||||
|
fods: "OpenDocument Spreadsheet Flat XML",
|
||||||
|
html: "HTML (StarCalc)",
|
||||||
|
ods: "calc8",
|
||||||
|
ots: "calc8_template",
|
||||||
|
xls: "MS Excel 97",
|
||||||
|
xlsx: "Calc MS Excel 2007 XML",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFilters = (fileType: string, converto: string) => {
|
const getFilters = (fileType: string, converto: string) => {
|
||||||
if (converto === "pdf") {
|
if (converto === "pdf") {
|
||||||
return [null, null];
|
return [null, null];
|
||||||
} else if (fileType in filters.text && converto in filters.text) {
|
} else if (fileType in inputFilters.text && converto in outputFilters.text) {
|
||||||
return [filters.text[fileType], filters.text[converto]];
|
return [inputFilters.text[fileType], outputFilters.text[converto]];
|
||||||
} else if (fileType in filters.calc && converto in filters.calc) {
|
} else if (fileType in inputFilters.calc && converto in outputFilters.calc) {
|
||||||
return [filters.calc[fileType], filters.calc[converto]];
|
return [inputFilters.calc[fileType], outputFilters.calc[converto]];
|
||||||
}
|
}
|
||||||
return [null, null];
|
return [null, null];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -166,3 +166,59 @@ test("logs stderr on exec error as well", async () => {
|
||||||
// The callback still provided stderr; your implementation logs it before settling
|
// The callback still provided stderr; your implementation logs it before settling
|
||||||
expect(errors).toContain("stderr: EPIPE");
|
expect(errors).toContain("stderr: EPIPE");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- calc (spreadsheet) category --------------------------------------------
|
||||||
|
test("uses Calc infilter and outfilter for xlsx -> csv (regression for issue #561)", async () => {
|
||||||
|
await convert("in.xlsx", "xlsx", "csv", "out/out.csv", undefined, mockExecFile);
|
||||||
|
|
||||||
|
const { args } = requireDefined(calls[0], "Expected at least one execFile call");
|
||||||
|
expect(args).toEqual([
|
||||||
|
"--headless",
|
||||||
|
"--infilter=Calc MS Excel 2007 XML",
|
||||||
|
"--convert-to",
|
||||||
|
"csv:Text - txt - csv (StarCalc)",
|
||||||
|
"--outdir",
|
||||||
|
"out",
|
||||||
|
"in.xlsx",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("uses Calc infilter and outfilter for csv -> xlsx", async () => {
|
||||||
|
await convert("in.csv", "csv", "xlsx", "out/out.xlsx", undefined, mockExecFile);
|
||||||
|
|
||||||
|
const { args } = requireDefined(calls[0], "Expected at least one execFile call");
|
||||||
|
expect(args).toEqual([
|
||||||
|
"--headless",
|
||||||
|
"--infilter=Text - txt - csv (StarCalc)",
|
||||||
|
"--convert-to",
|
||||||
|
"xlsx:Calc MS Excel 2007 XML",
|
||||||
|
"--outdir",
|
||||||
|
"out",
|
||||||
|
"in.csv",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("uses Calc infilter and outfilter for ods -> xlsx", async () => {
|
||||||
|
await convert("in.ods", "ods", "xlsx", "out/out.xlsx", undefined, mockExecFile);
|
||||||
|
|
||||||
|
const { args } = requireDefined(calls[0], "Expected at least one execFile call");
|
||||||
|
expect(args).toEqual([
|
||||||
|
"--headless",
|
||||||
|
"--infilter=calc8",
|
||||||
|
"--convert-to",
|
||||||
|
"xlsx:Calc MS Excel 2007 XML",
|
||||||
|
"--outdir",
|
||||||
|
"out",
|
||||||
|
"in.ods",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("pdf -> csv produces no filters (cross-category: not supported via LibreOffice Writer)", async () => {
|
||||||
|
await convert("in.pdf", "pdf", "csv", "out/out.csv", undefined, mockExecFile);
|
||||||
|
|
||||||
|
const { args } = requireDefined(calls[0], "Expected at least one execFile call");
|
||||||
|
// pdf is Writer-category; csv output requires Calc — no valid cross-category
|
||||||
|
// filter exists, so soffice is invoked without explicit filters and will fail
|
||||||
|
// gracefully. The properties list no longer exposes this combination.
|
||||||
|
expect(args).toEqual(["--headless", "--convert-to", "csv", "--outdir", "out", "in.pdf"]);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue