Skip to content

Commit ecbccdd

Browse files
tballisonCopilot
andauthored
TIKA-4747 -- improve pdf and ocr/imagemagick docs. Make sure to include default-parser (#2862)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 363378f commit ecbccdd

9 files changed

Lines changed: 145 additions & 21 deletions

File tree

docs/modules/ROOT/pages/configuration/index.adoc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,32 @@ Per-section documentation:
6565
`plugin-roots` — see xref:pipes/configuration.adoc[Pipes Configuration]
6666
and xref:pipes/index.adoc[Tika Pipes].
6767

68+
== The `parsers` list and `default-parser`
69+
70+
Tika configuration files are JSON, with optional support for `//` and `/* */` comments.
71+
72+
A `parsers` list loads *only* the parsers it names — every other parser is dropped.
73+
To customize one parser while keeping all the others, add a `default-parser` entry:
74+
75+
[source,json]
76+
----
77+
{
78+
"parsers": [
79+
{ "pdf-parser": { "sortByPosition": true } },
80+
{ "default-parser": {} }
81+
]
82+
}
83+
----
84+
85+
Configuring a parser automatically excludes its default copy, so there is no duplication.
86+
Omit `default-parser` only when you want a Tika limited to the parsers you listed.
87+
88+
== Windows file paths
89+
90+
JSON uses the backslash as an escape character, so path options (e.g. `tesseractPath`,
91+
`imageMagickPath`) must use forward slashes (`C:/Tools/...`) or escaped backslashes
92+
(`C:\\Tools\\...`). A single backslash is a JSON parse error.
93+
6894
== Topics
6995

7096
=== Parser Configuration

docs/modules/ROOT/pages/configuration/parsers/pdf-parser.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ icon:github[] https://github.com/apache/tika/blob/main/tika-parsers/tika-parsers
2929

3030
== Full Configuration
3131

32-
The following example shows all available configuration options with their default values.
33-
Comments indicate the available options for enum fields.
32+
The example below lists every option with its default value and an inline comment describing
33+
it. It also includes a `default-parser` entry so the config works as-is; see
34+
xref:configuration/index.adoc[Configuration] for why that entry matters.
3435

3536
[source,json]
3637
----

docs/modules/ROOT/pages/configuration/parsers/tesseract-ocr-parser.adoc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ icon:github[] https://github.com/apache/tika/blob/main/tika-parsers/tika-parsers
2929

3030
== Full Configuration
3131

32-
The following example shows all available configuration options with their default values.
33-
Comments indicate the available options for enum fields.
32+
The example below lists every option with its default value and an inline comment describing
33+
it. It also includes a `default-parser` entry so the config works as-is; see
34+
xref:configuration/index.adoc[Configuration] for why that entry matters. ImageMagick is
35+
optional — it is only used when `enableImagePreprocessing` or `applyRotation` is true.
3436

3537
[source,json]
3638
----

docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,18 @@ The converter currently supports:
9494
"sortByPosition": true,
9595
"maxMainMemoryBytes": 1000000
9696
}
97+
},
98+
{
99+
"default-parser": {}
97100
}
98101
]
99102
}
100103
----
101104

102-
NOTE: When you configure a parser with specific settings in JSON, the loader automatically
103-
excludes it from SPI loading. The parser (e.g., `pdf-parser`) is not even instantiated in
104-
`default-parser` if there's a definition for it in the tika-config.json. Explicit `exclude`
105-
directives are only needed when you want to disable a parser entirely without providing
106-
custom configuration.
105+
NOTE: A `parsers` list loads *only* the parsers it names. The `default-parser` entry above
106+
restores all the other parsers (it is the JSON equivalent of the 3.x `DefaultParser`).
107+
Configuring a parser automatically excludes its default copy, so there is no duplication;
108+
explicit `exclude` directives are only needed to disable a parser without replacing it.
107109

108110
=== Key Differences
109111

tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/resources/config-examples/pdf-parser-basic.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
"extractInlineImages": true,
66
"sortByPosition": true
77
}
8+
},
9+
{
10+
// Keep Tika's other default parsers. Without this, this config is PDF-only.
11+
"default-parser": {}
812
}
913
]
1014
}
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,104 @@
11
{
2+
// A "parsers" list loads ONLY the parsers it names; the "default-parser" entry at
3+
// the bottom keeps all the others. Windows paths in JSON need forward slashes or
4+
// escaped backslashes.
25
"parsers": [
36
{
47
"pdf-parser": {
8+
// Enforce the PDF's access permissions. DONT_CHECK ignores them.
59
// Options: DONT_CHECK, ALLOW_EXTRACTION_FOR_ACCESSIBILITY, IGNORE_ACCESSIBILITY_ALLOWANCE
610
"accessCheckMode": "DONT_CHECK",
11+
// Character-width tolerance for inserting spaces (PDFBox).
712
"averageCharTolerance": 0.3,
13+
// Collect per-stream IOExceptions in metadata and rethrow after parsing.
814
"catchIntermediateIOExceptions": true,
15+
// Detect and correct rotated (angled) text runs within a page.
916
"detectAngles": false,
17+
// Line-height multiple that starts a new paragraph (PDFBox).
1018
"dropThreshold": 2.5,
19+
// Estimate where spaces belong between words (most PDFs lack explicit spaces).
1120
"enableAutoSpace": true,
21+
// Extract AcroForm field content.
1222
"extractAcroFormContent": true,
23+
// Extract PDF actions; JavaScript macros become embedded documents.
1324
"extractActions": false,
25+
// Extract annotation text (comments, form-field captions).
1426
"extractAnnotationText": true,
27+
// Extract outline / bookmark text.
1528
"extractBookmarksText": true,
29+
// Record font names in metadata.
1630
"extractFontNames": false,
31+
// Record metadata about incremental updates (whether present, how many).
1732
"extractIncrementalUpdateInfo": true,
33+
// Record inline-image metadata only, without rendering (faster than extractInlineImages).
1834
"extractInlineImageMetadataOnly": false,
35+
// Render and extract inline images from content streams.
1936
"extractInlineImages": false,
37+
// Extract marked-content / structure tags, falling back to plain text.
2038
"extractMarkedContent": false,
39+
// Emit each unique inline image (by object id) only once.
2140
"extractUniqueInlineImagesOnly": true,
41+
// If the PDF has an XFA form, process only it.
2242
"ifXFAExtractOnlyXFA": false,
43+
// Ignore content-stream space glyphs; rely on the spacing algorithm (PDFBOX-3774).
2344
"ignoreContentStreamSpaceGlyphs": false,
45+
// EXPERT: replace the inline-image factory; give a class implementing
46+
// ImageGraphicsEngineFactory, e.g.:
47+
// "imageGraphicsEngineFactoryClass": "com.example.MyImageGraphicsEngineFactory"
48+
// How to render page images; NONE renders nothing.
2449
// Options: NONE, RAW_IMAGES, RENDER_PAGES_BEFORE_PARSE, RENDER_PAGES_AT_PAGE_END
2550
"imageStrategy": "NONE",
51+
// Max incremental updates to parse when parseIncrementalUpdates is true.
2652
"maxIncrementalUpdates": 10,
53+
// Max memory to load a PDF before buffering to a temp file (default 512MB).
2754
"maxMainMemoryBytes": 536870912,
55+
// Max pages to process; -1 = no limit.
2856
"maxPages": -1,
57+
// OCR settings. Requires an OCR engine (e.g. Tesseract) installed.
2958
"ocr": {
59+
// Render resolution (dpi) for OCR.
3060
"dpi": 300,
61+
// Image format sent to the OCR engine.
3162
// Options: PNG, TIFF, JPEG
3263
"imageFormat": "PNG",
64+
// Image quality (0.0-1.0) for lossy formats.
3365
"imageQuality": 1.0,
66+
// Rendered-image color model.
3467
// Options: RGB, GRAY
3568
"imageType": "GRAY",
69+
// Skip OCR for rendered pages larger than this area (w x h); -1 = no limit.
70+
"maxImagePixels": 100000000,
71+
// Max pages to OCR per document; -1 = no limit.
72+
"maxPagesToOcr": -1,
73+
// Which page content to render for OCR.
3674
// Options: NO_TEXT, TEXT_ONLY, VECTOR_GRAPHICS_ONLY, ALL
3775
"renderingStrategy": "ALL",
76+
// When to run OCR; AUTO runs it only on text-poor pages.
3877
// Options: AUTO, NO_OCR, OCR_ONLY, OCR_AND_TEXT_EXTRACTION
3978
"strategy": "AUTO",
79+
// Per-page character thresholds that trigger AUTO OCR.
4080
"strategyAuto": {
4181
"totalCharsPerPage": 10,
4282
"unmappedUnicodeCharsPerPage": 10
4383
}
4484
},
85+
// Parse prior incremental-update versions as embedded documents.
4586
"parseIncrementalUpdates": false,
87+
// EXPERT: set the Sun KCMS color-management system property. Default false.
4688
"setKCMS": false,
89+
// Sort text by x/y position; helps some PDFs, can interleave columns in others.
4790
"sortByPosition": false,
91+
// Space-width tolerance for inserting spaces (PDFBox).
4892
"spacingTolerance": 0.5,
93+
// Remove text drawn twice over the same region (faked bold); can be slow.
4994
"suppressDuplicateOverlappingText": false,
95+
// Throw on an encrypted payload instead of skipping it.
5096
"throwOnEncryptedPayload": false
5197
}
98+
},
99+
{
100+
// Keep Tika's other default parsers. Without this, this config is PDF-only.
101+
"default-parser": {}
52102
}
53103
]
54104
}

tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/resources/config-examples/tesseract-basic.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
"language": "eng",
66
"timeoutSeconds": 120
77
}
8+
},
9+
{
10+
// Keep Tika's other default parsers. Without this, only image files are OCR'd.
11+
"default-parser": {}
812
}
913
]
1014
}
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,65 @@
11
{
2+
// A "parsers" list loads ONLY the parsers it names; the "default-parser" entry at
3+
// the bottom keeps all the others (needed so PDFs/Office docs still reach OCR).
4+
// Windows paths in JSON need forward slashes or escaped backslashes.
25
"parsers": [
36
{
47
"tesseract-ocr-parser": {
8+
// Calculate skew and rotate (via ImageMagick) before OCR. Needs ImageMagick.
59
"applyRotation": false,
10+
// Colorspace of the preprocessed image (preprocessing only).
611
"colorspace": "gray",
12+
// Resolution (dpi) of the preprocessed image.
713
"density": 300,
14+
// Bits per color sample in the preprocessed image.
815
"depth": 4,
16+
// Run ImageMagick preprocessing (density/depth/colorspace/filter/resize) before OCR.
917
"enableImagePreprocessing": false,
18+
// ImageMagick resize filter.
1019
"filter": "triangle",
20+
// Directory holding the ImageMagick program (empty = on PATH). ImageMagick is
21+
// OPTIONAL -- used only when enableImagePreprocessing or applyRotation is true.
1122
"imageMagickPath": "",
23+
// Write OCR output from embedded images inline into the parent document.
1224
"inlineContent": false,
25+
// Tesseract language(s); join multiple with '+', e.g. "eng+fra".
1326
"language": "eng",
27+
// Skip OCR for files larger than this many bytes.
1428
"maxFileSizeToOcr": 2147483647,
29+
// Skip OCR for files smaller than this many bytes.
1530
"minFileSizeToOcr": 0,
16-
// Additional Tesseract configuration parameters as key-value pairs
31+
// Additional raw Tesseract config variables (key-value).
1732
"otherTesseractConfig": {
1833
"preserve_interword_spaces": "1",
1934
"textord_initialx_ile": "0.75",
2035
"textord_noise_hfract": "0.15625"
2136
},
37+
// Tesseract output format.
2238
// Options: TXT, HOCR
2339
"outputType": "TXT",
40+
// Inserted between OCR'd pages (empty overrides Tesseract 4's form-feed).
2441
"pageSeparator": "",
42+
// Page segmentation mode (0-13); 1 = auto with orientation/script detection.
2543
"pageSegMode": "1",
44+
// Load Tesseract language data at startup instead of on first use.
2645
"preloadLangs": false,
46+
// Preserve interword spacing in the output.
2747
"preserveInterwordSpacing": false,
48+
// Scale percent (100-900) applied during preprocessing.
2849
"resize": 200,
50+
// Runtime kill-switch to disable OCR.
2951
"skipOcr": false,
52+
// Directory with tessdata language files (empty = Tesseract default).
3053
"tessdataPath": "",
54+
// Directory with the tesseract binary (empty = on PATH).
3155
"tesseractPath": "",
56+
// Max seconds to wait for the OCR process.
3257
"timeoutSeconds": 120
3358
}
59+
},
60+
{
61+
// Keep Tika's other default parsers. Without this, only image files are OCR'd.
62+
"default-parser": {}
3463
}
3564
]
3665
}

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/ImagePreprocessor.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535

3636
import org.apache.tika.metadata.Metadata;
3737
import org.apache.tika.parser.ocr.tess4j.ImageDeskew;
38-
import org.apache.tika.utils.SystemUtils;
3938

4039
class ImagePreprocessor implements Serializable {
4140

@@ -58,10 +57,17 @@ void process(Path sourceFile, Path targFile, Metadata metadata, TesseractOCRConf
5857

5958
if (config.isEnableImagePreprocessing() || (config.isApplyRotation() && angle != 0)) {
6059
// process the image - parameter values can be set in TesseractOCRConfig.properties
60+
//
61+
// On Windows TesseractOCRParser.getImageMagickProg() returns "magick", i.e. the
62+
// ImageMagick 7 program. IM7's native command form is
63+
// magick [read settings] input [operators] output
64+
// We intentionally do NOT prepend the legacy "convert" subcommand: "magick convert"
65+
// runs IM7 in deprecated IM6-compatibility mode and emits a deprecation warning.
66+
// Operators (-depth, -colorspace, -filter, -resize, -rotate) must follow the input
67+
// image; only read-time settings such as -density may precede it. This ordering is
68+
// also accepted by the legacy "convert" program used on non-Windows systems, so a
69+
// single argument layout works on every platform.
6170
CommandLine commandLine = new CommandLine(fullImageMagickPath);
62-
if (SystemUtils.IS_OS_WINDOWS) {
63-
commandLine.addArgument("convert");
64-
}
6571

6672
// Arguments for ImageMagick
6773
final List<String> density =
@@ -79,19 +85,19 @@ void process(Path sourceFile, Path targFile, Metadata metadata, TesseractOCRConf
7985
Stream<List<String>> stream = Stream.empty();
8086
if (angle == 0) {
8187
if (config.isEnableImagePreprocessing()) {
82-
// Do pre-processing, but don't do any rotation
83-
stream = Stream.of(density, depth, colorspace, filter, resize, sourceFileArg,
88+
// Pre-processing, no rotation. -density precedes the input; the image
89+
// operators follow it.
90+
stream = Stream.of(density, sourceFileArg, depth, colorspace, filter, resize,
8491
targFileArg);
8592
}
8693
} else if (config.isEnableImagePreprocessing()) {
87-
// Do pre-processing with rotation
88-
stream =
89-
Stream.of(density, depth, colorspace, filter, resize, rotate, sourceFileArg,
90-
targFileArg);
94+
// Pre-processing with rotation
95+
stream = Stream.of(density, sourceFileArg, depth, colorspace, filter, resize, rotate,
96+
targFileArg);
9197

9298
} else if (config.isApplyRotation()) {
9399
// Just rotation
94-
stream = Stream.of(rotate, sourceFileArg, targFileArg);
100+
stream = Stream.of(sourceFileArg, rotate, targFileArg);
95101
}
96102
final String[] args = stream.flatMap(Collection::stream).toArray(String[]::new);
97103
commandLine.addArguments(args, true);

0 commit comments

Comments
 (0)