# Technical Documentation: axa-group/Parsr

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/axa-group/Parsr)

### Overview (`README.md`)

<p align='center'>
  <img src="assets/logo.png" width="275"><br />
</p>

<h2 align="center"><i>Turn your documents into data!</i></h2>

<p align="center">
	<a href="https://cloud.drone.io/axa-group/Parsr"><img src="https://cloud.drone.io/api/badges/axa-group/Parsr/status.svg"></a>
</p>

<p align="center">
	<a href="README_fr.md">Français</a> |
  <a href="README_pt.md">Portuguese</a> |
  <a href="README_sp.md">Spanish</a> |
	<a href="README_zh-cn.md">中文</a>
</p>



> [!WARNING]
> **This project is no longer maintained.** Security patches are not being applied. Consider using an alternative such as [LiteParse](https://github.com/run-llama/liteparse) if you need a local, Apache 2.0–licensed parsing solution.


- **Parsr**, is a minimal-footprint document (**image, pdf, docx, eml**) cleaning, parsing and extraction toolchain which generates readily available, organized and usable data in **JSON, Markdown (MD), CSV/Pandas DF** or **TXT** formats.

- It provides analysts, data scientists and developers with clean structured and label-enriched information set for ready-to-use applications ranging from data entry and document analysts automation, archival, and many others.

- Currently, Parsr can perform: document cleaning, _hierarchy regeneration_ (words, lines, paragraphs), detection of _headings, tables, lists, table of contents, page numbers, headers/footers, links_, and others. Check out [all the features](server/src/processing/README.md#1-current-processing-modules).

# Table of Contents

- [Table of Contents](#table-of-contents)
- [Getting Started](#getting-started)
  - [Installation](#installation)
  - [Usage](#usage)
- [Documentation](#documentation)
- [Contribute](#contribute)
- [Third Party Licenses](#third-party-licenses)
- [License](#license)

# Getting Started

## Installation

_-- The advanced installation guide is available [here](docs/installation.md) --_

The quickest way to install and run the Parsr API is through the [docker image](https://hub.docker.com/r/axarev/parsr):

```sh
docker pull axarev/parsr
```

If you also wish to install the GUI for sending documents and visualising results:

```sh
docker pull axarev/parsr-ui-localhost
```

Note: Parsr can also be installed bare-metal (not via Docker containers), the procedure for which is documented in the [installation guide](docs/installation.md).

## Usage

_-- The advanced usage guide is available [here](docs/usage.md) --_

To run the [API](docs/api-guide.md), issue:

```sh
docker run -p 3001:3001 axarev/parsr
```

which will launch it on [http://localhost:3001](http://localhost:3001).  
Consult the documentation on the [usage of the API](docs/api-guide.md).

1. To access the **python** client to Parsr API, issue:

   ```sh
   pip install parsr-client
   ```

   To sample the **Jupyter Notebook**, using the python client, head over to the [jupyter demo](demo/parsr-jupyter-demo).

2) To use the GUI tool (the API needs to already be running), issue:
   ```sh
   docker run -t -p 8080:80 axarev/parsr-ui-localhost:latest
   ```
   Then, access it through [http://localhost:8080](http://localhost:8080).

Refer to the [Configuration documentation](docs/configuration.md) to interpret the configurable options in the GUI viewer.

The [API based usage](docs/usage.md#3-api) and the [command line usage](docs/usage.md#23-command-line-usage) are documented in the [advanced usage](docs/usage.md) guide.

# Documentation

All documentation files can be found [here](docs/README.md).

# Contribute

Please refer to the [contribution guidelines](CONTRIBUTING.md).

# Third Party Licenses

Third Party Libraries licenses for its [dependencies](docs/dependencies.md):

1. **QPDF**: Apache [http://qpdf.sourceforge.net](http://qpdf.sourceforge.net/)
2. **ImageMagick**: Apache 2.0 [https://imagemagick.org/script/license.php](https://imagemagick.org/script/license.php)
3. **Pdfminer.six**: MIT [https://github.com/pdfminer/pdfminer.six/blob/master/LICENSE](https://github.com/pdfminer/pdfminer.six/blob/master/LICENSE)
4. **PDF.js**: Apache 2.0 [https://github.com/mozilla/pdf.js](https://github.com/mozilla/pdf.js)
5. **Tesseract**: Apache 2.0 [https://github.com/tesseract-ocr/tesseract](https://github.com/tesseract-ocr/tesseract)
6. **Camelot**: MIT [https://github.com/camelot-dev/camelot](https://github.com/camelot-dev/camelot)
7. **MuPDF** (Optional dependency): AGPL [https://mupdf.com/license.html](https://mupdf.com/license.html)
8. **Pandoc** (Optional dependency): GPL [https://github.com/jgm/pandoc](https://github.com/jgm/pandoc)

# License

Copyright 2020 AXA Group Operations S.A.  
Licensed under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0) license (see the [LICENSE](LICENSE) file).

---

### Overview (`docs/README.md`)

# Parsr Documentation

1. [Installation Guide](installation.md)
2. [Usage Guide](usage.md)
3. [Configuration Guide](configuration.md)
4. [API Guide](api-guide.md)
5. [JSON Output](json-output.md)
6. [ABBYY FineReader](abbyy-finereader.md)
6. [Architecture](architecture.md)
7. [Dependencies](dependencies.md)
8. [Docker](docker.md)

---

### Overview (`parsr-fix-pdf-font/README.md`)

# Parsr - Fix PDF Font

**Parsr-fix-pdf-font** is a utility designed specifically to remedy broken unicode maps for PDF fonts. Issues with broken unicode maps can arise due to various reasons, including incomplete or corrupt font embedding, or issues during the PDF creation process. Such problems can render text in a PDF file unreadable or undecipherable.

This tool leverages Tesseract.js, an optical character recognition engine, to recognize the broken glyphs present in the PDF. Once these glyphs are identified, **Parsr-fix-pdf-font** rebuilds the unicode map, ensuring that the PDF becomes readable and retains its original design and layout.

## Features

- OCR Powered Correction: Uses Tesseract.js to perform Optical Character Recognition on the broken glyphs, ensuring accurate text representation.

- Rebuilding Unicode Maps: After identifying the incorrect mappings, the tool regenerates the correct unicode map, preserving the original design of the PDF.

- Easy-to-Use Command Line Interface: Simplified command line usage for quick fixes.

## Requirements

nodejs >18

ImageMagick Convert


## Usage
Use the command line interface to run the Parsr tool:

```sh
cd parsr-fix-pdf-font
node parsr-fix-pdf-font.js --input ./test/testPage.pdf --output pdf.pdf --lang eng
```

Parameters:

- --input <path-to-pdf>: Specifies the path to the source PDF file that needs to be fixed.
- --ouput <path-to-out-pdf>: Designates the path where the fixed PDF will be saved. If the specified file already exists, it will be overwritten.
- --lang eng: Sets the language for the OCR process. By default, it's set to English (eng). Tesseract supports multiple languages, so ensure you choose the appropriate one for your document.
 
## Troubleshooting
If you encounter any issues:

Inspect PDF: Ensure that the PDF isn't password protected or encrypted. If it is, decrypt it before running the tool.

Language Mismatch: If the OCR isn't accurate, ensure you've chosen the correct language setting for the document.

## Limits

Tesseract OCR is not really good on single Glyph, but at least the text is readable / understandable for an LLM.

We do not reconstruct the XREF table yet. Using a tool like ```mutools clean ``` will allow you to fix them if needed.

## Contribution
Parsr is an open-source tool. Contributions in the form of bug reports, feature requests, or code are always welcome. Check our GitHub repository for more details.

---

### Overview (`clients/python-client/README.md`)

# Parsr Client

Provides a python interface to the Parsr tool via its API.
Parsr transforms PDF, documents and images into enriched, structured data.

Find out all about Parsr (including download) at [https://github.com/axa-group/Parsr](https://github.com/axa-group/Parsr).

## 1 Installation

```sh
pip install parsr-client
```

## 2 Usage

_Make sure that the Parsr Server is already running. Let us suppose that the address is `localhost:3001`_

### 2.1 Connect to the Parsr server

```python
from parsr_client import ParsrClient
parsr = ParsrClient('localhost:3001')
```

### 2.2 Send the document

```python
parsr.send_document(
   file_path='README.pdf',
   config_path='defaultConfig.json',
   document_name='The Readme',
   save_request_id=True)
```

### 2.4 Retrieve results

1. Get everything as a JSON:

    ```python
    parsr.get_json()
    ```

2. As Markdown:

    ```python
    parsr.get_markdown()
    ```

3. As text:

    ```python
    parsr.get_text()
    ```

4. Get the first table on the first page:

    ```python
    parsr.get_table(
        page=1,
        table=1,
    )
    ```

5. Get all the versions of the document:

    ```python
    parsr.get_revisions('The Readme')
    ```

6. Get pretty diffs between each successive pair of a document's revisions:

    ```python
    parsr.compare_revisions('The Readme', pretty_html=True)
    ```

## 3 Interpreting the whole JSON output locally

The supplied `ParsrOutputInterpreter` class can be used to interpret the downloaded JSON output and generate higher level structures like the text body.

Here's an example to generate text body on the first page from the above example.

``` python
from parsr_client import ParsrOutputInterpreter

parsr_interpreter = ParsrOutputInterpreter(
    parsr.get_json()
)

t = parsr_interpreter.get_text(
    page_number=1
)
print(t)
```

---

### Overview (`demo/doc-versioning/README.md`)

# Doc Versioning

- Stores and displays document (PDF, Images, DOCx) revisions and diffs.
- Uses [Parsr](https://github.com/axa-group/Parsr) to perform the document data extraction.
- Based on Python 3

## Installation

Dependencies:
1. [Flask](https://flask.palletsprojects.com/en/1.1.x/installation/#install-flask)
2. [PyWebview](https://pywebview.flowrl.com/guide/installation.html#dependencies)
3. [Parsr-Client](https://pypi.org/project/parsr-client/) > v3.1.0
4. [markdown](https://python-markdown.github.io/install/)

## Usage

Once the dependencies have been set up, execute the following in the project folder:

``` sh
./run.py
```

---

### Overview (`demo/echo-module-py/README.md`)

# Demo Python Remote Module

This module is a demo on how you can create your own remote modules.

## Try it!

Run it with:

```
$ python3 echo-module.py
```

Then call it in your [configuration](../../docs/configuration.md):

```json
[
  "remote",
  {
    "url": "http://localhost:8888"
  }
]
```

---

### Overview (`demo/parsr-jupyter-demo/README.md`)

# Parsr - Jupyter Notebook

This folder includes a [jupyter notebook](./notebook.ipynb), which shows how a user can access the API using a python interface, showing the following functions:

1. Connecting to the Parsr API.
2. Sending a document (or a folder) to the Parsr API.
3. Retrieving the complete JSON output.
4. Retrieving other output formats such as Markdown, text, and tables (CSV and Pandas Dataframes).
5. Using the [parsr output interpreter class](../../clients/python-client/parsr_client/parsr_output_interpreter.py), which reconstructs usable elements from an already downloaded Parsr outputted JSON file.

## Installation

Install [pipenv](https://pipenv.readthedocs.io/en/latest/install/#installing-pipenv), then issue the following inside this folder (`demo/parsr-jupyter-demo`):

```sh
pipenv install
```

## Usage

To start the jupyter notebook, issue:

```sh
pipenv run jupyter lab notebook.ipynb
```

---

### Overview (`demo/vue-viewer/README.md`)

# vue-viewer

## Project setup

```
npm install
```

### Compiles and hot-reloads for development

```
npm run serve
```

### Compiles and minifies for production

```
npm run build
```

### Run your tests

```
npm run test
```

### Lints and fixes files

```
npm run lint
```

### Customize configuration

See [Configuration Reference](https://cli.vuejs.org/config/).

---

### Overview (`server/src/input/README.md`)

# Input Modules

The Input modules in Parsr perform the initial role of importing the raw data from the input files.
Each module performs on a particular type of input files, and generate different results.
Each module may or may not contain a set of configurable parameters, which (along with the usage documentation) can be consulted in the per-module documentation pages below.
Each module returns a valid `Document` object with an array of `Words` for each parsed `Page`.

## The Modules

1. [Pdfminer](pdfminer/README.md)
2. [PDF.js](pdf.js/README.md)
3. [Tesseract](tesseract/README.md)
4. [Google Vision](google-vision/README.md)
5. [Amazon Textract](amazon-textract/README.md)
6. [MS Cognitive Services](ms-cognitive-services/README.md)
7. [ABBYY](abbyy/README.md)
8. [JSON](json/README.md)
9. [MS Word](doc/README.md)
10. [Email](email/README.md)

## Supported input formats

Currently, the following file formats are available for Parsr:

<table>
  <tr>
    <th rowspan="2">Input format</th>
    <th colspan="8">Input modules</th>
  </tr>
  <tr>
    <td style="text-align:center; font-weight: bold">Pdfminer</td>
    <td style="text-align:center; font-weight: bold">pdf.js</td>
    <td style="text-align:center; font-weight: bold">ABBYY</td>
    <td style="text-align:center; font-weight: bold">Tesseract</td>
    <td style="text-align:center; font-weight: bold">JSON Extractor</td>
    <td style="text-align:center; font-weight: bold">Google Vision</td>
    <td style="text-align:center; font-weight: bold">Amazon Textract</td>
    <td style="text-align:center; font-weight: bold">MS Cognitive Services</td>
  </tr>
  <tr style="text-align: center; font-weight: bold">
    <td>.pdf</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
  </tr>
  <tr style="text-align: center; font-weight: bold">
    <td>.docx</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
  </tr>
  <tr style="text-align: center; font-weight: bold">
    <td>.eml</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
  </tr>
  <tr style="text-align: center; font-weight: bold">
    <td>.tiff</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
  </tr>
  <tr style="text-align: center; font-weight: bold">
    <td>.png</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
  </tr>
    <tr style="text-align: center; font-weight: bold">
    <td>.jpeg</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: lightgreen">✓</td>
  </tr>
    <tr style="text-align: center; font-weight: bold">
    <td>.json</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
  </tr>
    <tr style="text-align: center; font-weight: bold">
    <td>.xml</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: lightgreen">✓</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
    <td style="background: #FF4040">✗</td>
  </tr>
</table>

This means that for processing a pdf file, 4 extractors can be chosen: pdfminer, pdf.js, ABBYY or Tesseract.

**Note:** *not all extractors share the same functionality or return the same information, so one should check for the best extractor given the use case.*  

**Note:** *when using a json or xml file as input, extractor configuration will be ignored as there is currently only one extractor for each of this formats.*

---

### Overview (`server/src/output/README.md`)

# Output Modules

The output modules in Parsr perform a final role of generating the processed, enriched and structured output.
Each module generates a specific output file type, and represents a different granularity and type of data.
For more information, along with individual configuration options, consult the per-module documentation pages below:

## The Modules

1. [JSON](json/README.md)
2. [Simple JSON](simpleJson/README.md)
3. [Markdown](markdown/README.md)
4. [Text](text/README.md)
5. [CSV](csv/README.md)
6. [PDF](pdf/README.md)

---

### Overview (`server/src/processing/README.md`)

# Processing Modules

- [Processing Modules](#processing-modules)
	- [1. Current Processing Modules](#1-current-processing-modules)
	- [2. Create your own Processing Module](#2-create-your-own-processing-module)
		- [2.1. Creating and Naming your Typescript Module](#21-creating-and-naming-your-typescript-module)
		- [2.2. Add to Register](#22-add-to-register)
		- [2.3. Add it to the Configuration](#23-add-it-to-the-configuration)
		- [2.4. Run it!](#24-run-it)

The processing modules in Parsr perform a central role of cleaning and enriching the extracted raw output.
Each module performs a particular operation on a document representation, generates a new valid Document, and then passes it on to the next module for the next treatment.
Each module can contain a set of configurable parameters, which can be consulted in the per-module documentation pages below:

## 1. Current Processing Modules

1. [Drawing Detection](DrawingDetectionModule/README.md)
2. [Header and Footer Detection](HeaderFooterDetectionModule/README.md)
3. [Heading Detection](MLHeadingDetectionModule/README.md)
4. [Hierarchy Detection](HierarchyDetectionModule/README.md)
5. [Image Detection](ImageDetectionModule/README.md)
6. [Key-Value Pair Detection](KeyValueDetectionModule/README.md)
7. [Lines to Paragraph](LinesToParagraphModule/README.md)
8. [Link Detection](LinkDetectionModule/README.md)
9. [List Detection](ListDetectionModule/README.md)
10. [Number Correction](NumberCorrectionModule/README.md)
11. [Out of Page Removal](OutOfPageRemovalModule/README.md)
12. [Page Number Detection](PageNumberDetectionModule/README.md)
13. [Reading Order Detection](ReadingOrderDetectionModule/README.md)
14. [Redundancy Detection](RedundancyDetectionModule/README.md)
15. [Regex Matcher](RegexMatcherModule/README.md)
16. [Remote Module](RemoteModule/README.md)
17. [Separate Words](SeparateWordsModule/README.md)
18. [Table Detection](TableDetectionModule/README.md)
19. [Table of Contents Detection](TableOfContentsDetectionModule/README.md)
20. [Whitespace Removal](WhitespaceRemovalModule/README.md)
21. [Words To Line](WordsToLineModule/README.md)

## 2. Create your own Processing Module

Creating a custom module can be very useful to add some treatment on the document.

You have two ways to do it:

1. Use the [Remote Module](RemoteModule/README.md) that will send the JSON by HTTP and expect the modified JSON as an answer
2. Create a Typescript Module and add it to the pipeline

### 2.1. Creating and Naming your Typescript Module

The [template module folder](TemplateModule) shows how a module tree needs to be structured.
The folder name, the module's filename and the [class's name](https://github.com/axa-group/Parsr/blob/a92a254f7860bbfe51ec1f24171ef8d44c54ccac/server/src/processing/TemplateModule/TemplateModule.ts#L35) need to follow the [PascalCase naming convention](https://github.com/basarat/typescript-book/blob/master/docs/styleguide/styleguide.md#class).

You can copy the entire folder to help you having a boilerplate.
The template code also contains some handy comments to help you get started.

### 2.2. Add to Register

To add your newly created module to the register, simply open the [Cleaner file](../Cleaner.ts) `/server/src/Cleaner.ts` and add your module class to the `Cleaner.cleaningToolRegister` attribute.

### 2.3. Add it to the Configuration

If you want your module to run you need to enable it in your [configuration](../../../docs/configuration.md#3-Cleaner-Config).

Simply add a line in the `cleaner` array with the name of your module, and potential options.

### 2.4. Run it!

That's it! Your new awesome processing module should run and modify the document according to your needs!

---

### Overview (`server/src/input/abbyy/README.md`)

# ABBYY FineReader Server Input Module

The ABBYY FineReader is a high-precision OCR option provided to the users of the Parsr platform.

### Credentials

When ABBYY FineReader Server is chosen as the working OCR extraction solution, the following credentials need to be set on the host running Parsr:

1. `ABBYY_SERVER_URL` : The network address of the ABBYY FineReader Server.
2. `ABBYY_SERVER_VER` : The major version number of the ABBYY FineReader Server. For example: 14 for ABBYY FineReader Server 14.01.
3. `ABBYY_WORKFLOW` : The name of the server 's workflow to be called to process the file.

  ```json
  "extractor": {
    "pdf": "abbyy",
    "ocr": "abbyy",
    "credentials": {
      "ABBYY_SERVER_URL": "...",
      "ABBYY_SERVER_VER": "...",
      "ABBYY_WORKFLOW": "..."
    }
  },
  ```

### Essential Server Configuration

On the side of the ABBYY FineReader Server, make sure the XML output is configured for the selected workflow:

1. Double click on the workflow to be used.
2. In the tab titled 'output', make sure the list of file formats exported contains the XML format if not, add it with the 'New' button.
3. Make sure the following settings are enabled on the XML format 's settings:
   1. Character Attributes
   2. Extended Character Attributes
   3. Coordinates of the Original Image
   4. Character Formatting

---

### Overview (`server/src/input/amazon-textract/README.md`)

# Amazon Textract Input Module

Extractor module for OCR'ing image files.

### Credentials

To use the Amazon Textract input module, you need a valid set of access keys from AWS with "_AmazonTextractFullAccess_"
You can generate one for free following [this guide](https://docs.aws.amazon.com/textract/latest/dg/getting-started.html).

Once you have the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, make sure to set those in the `"credentials"` key in the config file.

  ```json
  "extractor": {
    "pdf": "...",
    "ocr": "amazon-textract",
    "credentials": {
      "AWS_ACCESS_KEY_ID": "...",
      "AWS_SECRET_ACCESS_KEY": "..."
    }
  },
  ```

---

### Overview (`server/src/input/doc/README.md`)

# MS Word Input Module

Extractor module that parses .docx files to build documents.
This module will transform the .docx into a single PDF file with A4 pages, and then run the selected PDF extractor on this file.

### Credentials

This module requires no credentials to work.

---

### Overview (`server/src/input/email/README.md`)

# Email Input Module

Extractor module that parses .eml files (downloaded e-mails) to build documents.
This module will transform the .eml (and all its PDF and Image attachments) into a single PDF file with A4 pages, and then run the selected PDF extractor on this file.

### Credentials

This module requires no credentials to work.

---

### Overview (`server/src/input/google-vision/README.md`)

# Google Vision Input Module

Extractor module for OCR'ing image files.

### Credentials

To use the Google Vision input module, follow these steps:

1. [Create a new Google Cloud Platform App](https://console.cloud.google.com/projectcreate)
2. [Activate the Google Vision API](https://console.cloud.google.com/apis/library/vision.googleapis.com)
3. [Create new credentials](https://console.cloud.google.com/apis/credentials/wizard) and download the JSON file containing your credentials.
4. Copy the contents of the downloaded JSON file and paste everything as `"credentials"` value:
    ```json
    "extractor": {
      "pdf": "...",
      "ocr": "google-vision",
      "credentials": {
        "type": "...",
        "project_id": "...",
        "private_key_id": "...",
        "private_key": "...",
        "client_email": "...",
        "client_id": "...",
        "auth_uri": "...",
        "token_uri": "...",
        "auth_provider_x509_cert_url": "...",
        "client_x509_cert_url": "..."
      }
    },
    ```
5. Change your configuration to use `google-vision` for OCR.

_NB: This module only works with images yet. To make it work with PDF and TIFF, we'll need to use Batch File Annotation and Google Cloud Storage. [See the official guide](https://cloud.google.com/vision/docs/file-batch)._

---

### Overview (`server/src/input/json/README.md`)

# JSON Input Module

Extractor module that uses Parsr JSON output files as input to reconstruct a document.

### Credentials

This module requires no credentials to work.

---

### Overview (`server/src/input/ms-cognitive-services/README.md`)

# Microsoft Cognitive Services Input Module

Extractor module for OCR'ing image files.

### Credentials

To use the Microsoft Cognitive Services input module, you need a Microsoft Cognitive Services APIKEY.  
You can generate one for free following [this link](https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.CognitiveServices%2Faccounts).

Once you have the key, make sure to set it in the `"credentials"` key in the config file.

  ```json
  "extractor": {
    "pdf": "...",
    "ocr": "ms-cognitive-services",
    "credentials": {
      "OCP_APIM_SUBSCRIPTION_KEY": "...",
      "OCP_APIM_ENDPOINT": ""
    }
  },
  ```

Optionally, you can change the region endpoint to the one that you want to use, via the `OCP_APIM_ENDPOINT` value. If omitted, the default value will be `https://westeurope.api.cognitive.microsoft.com/`.

A list with all available endpoint regions can be found [here](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/2afb498089f74080d7ef85eb).

---

### Overview (`server/src/input/pdf.js/README.md`)

# PDF.js Input Module

Extractor module for PDF files. 
This is the recommended module for very large documents as it's the fastest solution currently available.

### Credentials

This module requires no credentials to work.

---

### Overview (`server/src/input/pdfminer/README.md`)

# Pdfminer Input Module

Extractor module for PDF files. 

### Credentials

This module requires no credentials to work.

---

### Overview (`server/src/input/tesseract/README.md`)

# Tesseract Input Module

Extractor module for OCR'ing image files.

### Credentials

This module requires no credentials to work.

---

### Overview (`server/src/output/csv/README.md`)

# CSV Output Module

CSV exporter will generate a csv file with the contents of each table on the document.

Example from [foo.pdf](../../../../samples/foo.pdf) sample file:

```
Cycle Name;KI (1/km);Distance (mi);Percent Fuel Savings;;;;
;;;;Improved Speed;Decreased Accel;Eliminate Stops;Decreased Idle
2012_2;3.30;1.3;5.9%;9.5%;29.2%;17.4%;
2145_1;0.68;11.2;2.4%;0.1%;9.5%;2.7%;
4234_1;0.59;58.7;8.5%;1.3%;8.5%;3.3%;
2032_2;0.17;57.8;21.7%;0.3%;2.7%;1.2%;
4171_1;0.07;173.9;58.1%;1.6%;2.1%;0.5%;
```

*As you can see, this will not take into account col/row spans.*
*This module will only output Tables from the document*

---

### Overview (`server/src/output/json/README.md`)

# JSON Output Module

This module exports a json file with information about the contents and structure of the document.

Example from [foo.pdf](../../../../samples/foo.pdf) sample file:
```
/* Detailed source-code truncated for AI context efficiency. */
```
By default the level of granularity of the export will be "word". You can configure it to "character" in the config file. For more information, refer to [Output Config/Granularity.](../../../../docs/configuration.md#42-Granularity).

For information about the complete structure of the json file, refer to the [JSON output format.](../../../../docs/json-output.md).

---

### Overview (`server/src/output/markdown/README.md`)

# Markdown Output Module

This module will generate a markdown file based on the contents of the input file.

Example from [foo.pdf](../../../../samples/foo.pdf) sample file:

```
## Table 2-1. Simulated fuel savings from isolated cycle improvements

| **Cycle Name** | **KI (1/km)** | **Distance (mi)** | **Percent Fuel Savings** |<|<|<|  
|---|---|---|---|---|---|---|  
|^|^|^| **Improved Speed** | **Decreased Accel** | **Eliminate Stops** | **Decreased Idle** |  
| 2012\_2 | 3.30 | 1.3 | 5.9% | 9.5% | 29.2% | 17.4% |  
| 2145\_1 | 0.68 | 11.2 | 2.4% | 0.1% | 9.5% | 2.7% |  
| 4234\_1 | 0.59 | 58.7 | 8.5% | 1.3% | 8.5% | 3.3% |  
| 2032\_2 | 0.17 | 57.8 | 21.7% | 0.3% | 2.7% | 1.2% |  
| 4171\_1 | 0.07 | 173.9 | 58.1% | 1.6% | 2.1% | 0.5% |  

Figure 2-1 extends the analysis from eliminating stops for the five example cycles and examines the additional benefit from avoiding slow-and-go driving below various speed thresholds.
```

*As it can be seen, Markdown exporter can differentiate between Paragraphs, Headings and Tables. It can also export images, tables of content and lists.*

---

### Overview (`server/src/output/pdf/README.md`)

# PDF Output Module

Generates a PDF document given the input file.

*This exporter relies on Markdown exporter to convert the document to Markdown and then uses Pandoc to convert it to a PDF. So as long as the markdown result is good, the PDF output will be good.*

---

### Overview (`server/src/output/simpleJson/README.md`)

# Simple json

This module exports a simpler json file with ordered information about the contents of the document. Here we do not export information about the positions / structure inside the document.

Example from [foo.pdf](../../../../samples/foo.pdf) sample file:
```json
[
  {
    "type": "heading",
    "level": 2,
    "content": "2 Quantifying Fuel-Saving Opportunities from Specific Driving Behavior Changes"
  },
  {
    "type": "paragraph",
    "content": "2.1 Savings from Improving Individual Driving Profiles"
  },
  {
    "type": "heading",
    "level": 5,
    "content": "2.1.1 Drive Profile Subsample from Real-World Travel Survey"
  },
  {
    "type": "paragraph",
    "content": "The interim report (Gonder et al. 2010) included results from detailed analyses on five cycles selected from a large set of real-world global positioning system (GPS) travel data collected in 2006 as part of a study by the Texas Transportation Institute and the Texas Department of Transportation (Ojah and Pearson 2008). The cycles were selected to reflect a range of kinetic intensity (KI) values. (KI represents a ratio of characteristic acceleration to aerodynamic speed and has been shown to be a useful drive cycle classification parameter [O’Keefe et al. 2007].) To determine the maximum possible cycle improvement fuel savings, the real-world cycles were converted into equivalent “ideal” cycles using the following steps:"
  }
]
```

For more information about the complete structure of the json file, refer to the [Simple JSON output format.](../../../../docs/simple-json-output.md)

*SimpleJson exporter can export Headings, Paragraphs, Lists, Tables and Tables of Content.*

---

### Overview (`server/src/output/text/README.md`)

# Text Output Module

This module exports a .txt file including only the text contents of the processed document.

Example from [foo.pdf](../../../../samples/foo.pdf) sample file:
```
2 Quantifying Fuel-Saving Opportunities from Specific Driving Behavior Changes

2.1 Savings from Improving Individual Driving Profiles

2.1.1 Drive Profile Subsample from Real-World Travel Survey

The interim report (Gonder et al. 2010) included results from detailed analyses on five cycles selected from a large set of real-world global positioning system (GPS) travel data collected in 2006 as part of a study by the Texas Transportation Institute and the Texas Department of Transportation (Ojah and Pearson 2008). The cycles were selected to reflect a range of kinetic intensity (KI) values. (KI represents a ratio of characteristic acceleration to aerodynamic speed and has been shown to be a useful drive cycle classification parameter [O’Keefe et al. 2007].) To determine the maximum possible cycle improvement fuel savings, the real-world cycles were converted into equivalent “ideal” cycles using the following steps:
```

*This does not differentiate between Headings and Paragraphs. This exporter can output Paragraphs, Lists, Tables and Tables of Content.*

---

### Overview (`server/src/processing/DrawingDetectionModule/README.md`)

# Drawing Detection Module

## Purpose

Groups SvgShapes into Drawings

## What it does

Converts all SvgShapes given by the extractor to a group of Drawings. Each Drawing is a set of Shapes that are visually together.

The module only modifies the document defined in the `drawingsFile` property, and **not the original document**. This is because of a decision we took to move Drawings information away from the input document, as it can heavily increase the file size.

## Parameters

None

## Dependencies

The module will look for a json file in the `drawingsFile` property of the document, containing the required information to build the Drawings. This file must be created in the extraction step of the process. If this file is not found or contains an invalid JSON format, the module execution will finish and the drawings document will not be modified.

## How it works

It sweeps each document page with a vertical and a horizontal control line, finding separations between groups. 

## Accuracy

Very high.
The boundaries of each page and element however, need to be correctly specified by the extractor.

## Limitations

None

---

### Overview (`server/src/processing/HeaderFooterDetectionModule/README.md`)

# Header Footer Detection Module

## Purpose

Detect the header and footer areas in a document, and set the appropriate properties of all the elements contained within those areas.

## What it does

Sets the `isHeader` or `isFooter` property flags for each one of the elements detected as headers or footers respectively in the detected areas.

## Dependencies

[Lines To Paragraph Module](../LinesToParagraphModule/README.md)

## How it works

- It detects empty (or white) horizontal bands across the entire document (all pages), which do not contain an element.
- For the footer, the highest of these such bands, not exceeding the value L from the bottom is retained as the footer dividing line.
- For the header, the lowest of these bands is retained using the same algorithm, except that the distance is calculated form the top of the pages.
- The algorithm also detects page number mentions using regexp based matching inside the elements classified as headers or footers.

## Parameters

The following two parameters are available:

1. `maxMarginPercentage`: The percentage of the page up to which (both from the top and the bottom) the algorithm will search for header or footer classification.
2. `ignorePages`: The list of pages to be ignored in the header/footer search.
   This typically includes book titles, table of contents, preface, and other pages which do not typically have the same header/footer layout as the rest of the document.
3. `similaritySizePercentage`: The percentage represent the difference of size between pages. This allow to apply the maxMarginPercentage option within groups of pages of similar size. 

## Accuracy

Given a good `maxMarginPercentage`, very good.
The accuracy is directly proportional to the number of pages (samples) available to the algorithm.

## Limitations

- An omittance of non-useful pages (like the title page) in the `ignoredPages` list can produce a false negative.

---

### Overview (`server/src/processing/HierarchyDetectionModule/README.md`)

# Hierarchy Detection Module

## Purpose

Detects the Hierarchy within a document, respecting indentation of element blocks to create a hierarchical structure.

## What it does

Sets the 'childs' and 'parent' property of every element inside a hierarchical structure, like lists inside lists, paragraphs following headings, etc.

## Dependencies

[Lines To Paragraph Module](../LinesToParagraphModule/README.md)

## How it works

## Accuracy

## Limitations

---

### Overview (`server/src/processing/ImageDetectionModule/README.md`)

# Image Detection Module

## Purpose

The Image detection module detect images in a PDF document.

## What it does

It matches every image detected by the extractor to the correct image file and appends image URI to all image elements in the document.

## Dependencies

MuPDF: `mutool extract` is used to extract all image files from a PDF *when pdfminer is selected as pdf extractor*.

## Parameters

`ocrImages`: Allows to extract data from detected images using selected OCR. When `true`, all detected images will be replaced with data extracted by OCR.
`wordsImagesSource`: When `true`, all word extracted by OCR will have their propertie filled by the source of the original image.

## How it works

### with pdfminer:

1. It uses the name of every image (figure name) detected by PdfMiner and tries to match with a single image identifier extracted by 'dumppdf'.

```
//'Image17' will be used to match image XObject using dumppdf
<figure name="Image17" bbox="72.000,244.190,373.280,506.640">
<image width="301" height="262" />
</figure>
```

2. `dumppdf` dumps the internal contents of a PDF file in pseudo-XML format, using this data the module tries to match each figure name with an image file name.

```
<key>XObject</key>
<value><dict size="1">
<key>Image17</key>
<value><ref id="17" /></value> // '17' will be used to match a image file named 'img-0017' extracted by MuPDF
</dict></value>
```

### with pdfjs:

For the case of pdfjs extractor, the library used to extract texts from the document can also natively extract every image. So a re-execution of pdfjs extractor is done, but asking only for image data.

## Accuracy

Almost **perfect**.

## Limitations

- Images will not be reconstructed if an image detected by extractor (pdfMiner) is not extracted by Muttol extract command then
- Some PDF can use more than one image file (one alpha image with one background image) to generate one visual image in PDF, in that case the module will detect both images.
- The module depends on the selected pdf extractor to have any way of extracting images from the document.
- For now, only 'pdfminer' and 'pdfjs' can extract images information. So if you use another pdf extractor, the module will skip its execution and return an unmodified document.

---

### Overview (`server/src/processing/KeyValueDetectionModule/README.md`)

# Key-Value Detection Module

## Purpose

Detect pairs of key-value throughout each page of a document, depending on a certain number of key-value patterns passed onto the pipeline in the configuration.

## What it does

Generates new `metadata` instances for each match of a key-value pair which validate a match above a certain threshold.

## Dependencies

[Words to Line Module](../WordsToLineModule/README.md)

## How it works

1. All the Line elements of a page are searched for matches with a set of predefined keys in the module parameters using a string matching algorithm based on the Sørensen–Dice coefficient.
   Only the matches with a similarity score higher than a threshold are kept as candidates.
2. The resulting set of matched keys are kept as candidates, and a corresponding value is looked for in the vicinity of the found key (on the right of the separator character: ':' or ';' by default).
3. Each key with its corresponding value is saved as a KeyValueMetadata type and attached to the concerned elements.

## Parameters

The configuration of the module is where the key patterns are described.
Following is an example of the configuration of the key-value search module:

```json
[
  "key-value-detection",
  {
    "thresholdRatio": 0.8,
    "keyValueDividerChars": [":", ";"],
    "keyPatterns": {
      "Name": ["Name", "Fullname", "User"],
      "Date of admission": ["ADMISSION DATE & TIME", "Adm Date/Time", "Reg/Admit Date"]
    }
  }
]
```

Here, the `keyValueDividerChars` describes the sets of characters that are used in the input document to separate the keys from values in a key-pair description.
`keyPatterns` describe objects describing the key names and patterns on which these key names need to be matched.
`threshold` describes the minimum similarity score for candidate substrings matches to pass.

## Example

Imagine a document containing the following text:
```
.....
Name: John
Surnames: Doe
Residence: Fake Street 123
.....
```


with config: 
```json
{
  "thresholdRatio": 0.8,
  "keyValueDividerChars": [
    ":",
  ],
  "keyPatterns": {
    "First Name": [
      "Name", "First Name"
    ],
    "Surname": [
      "Surname", "Surnames", "Last Name"
    ],
    "Address": [
      "Address", "Domicile", "Residence"
    ]
  }
}
```

`document.metadata` property after execution of this module:
```json
[
  {
    "id": 1,
    "elements": [
      468,
      476
    ],
    "type": "key-value",
    "data": {
      "keyName": "First Name",
      "keyElements": [
        468
      ],
      "valueElements": [
        476
      ]
    }
  },
  {
    "id": 2,
    "elements": [
      487,
      498
    ],
    "type": "key-value",
    "data": {
      "keyName": "Surname",
      "keyElements": [
        487
      ],
      "valueElements": [
        498,
      ]
    }
  },
  {
    "id": 3,
    "elements": [
      399,
      431
    ],
    "type": "key-value",
    "data": {
      "keyName": "Address",
      "keyElements": [
        399
      ],
      "valueElements": [
        431
      ]
    }
  }
]
```

Here we can see that 3 matches have been found:
- **First Name**: Elements with IDs 468 and 476, corresponding to Words with contents "Name" and "John" respectively.
- **Surname**: Elements with IDs 487 and 498, corresponding to Words with contents "Surnames" and "Doe".
- **Address**: Elements with IDs 399 and 431, with contents "Residence" and "Fake Street 123"

Note that `keyElements` and `valueElements` properties are defined as an array, because more than one match can be found for that key-value pair.

## Accuracy

The accuracy is high.
There is a direct corelation with the quality of the readability of the input document, the OCR's output, as well as the threshold for acceptance of candidates.

## Limitations

The current implementation supposes that key value pairs are always arranged in a single line and in the form `key : value`.
This makes it applicable to only a few limited cases.

---

### Overview (`server/src/processing/LinesToParagraphModule/README.md`)

# Lines to Paragraph Module

## Purpose

Create paragraphs from a collection of lines.

## What it does

It creates new paragraph elements that contains arrays of line elements.

## Dependencies

- [Words to Lines](../WordsToLineModule/README.md)
- [Reading Order Module](../ReadingOrderDetectionModule/README.md)

## How it works

It simply takes every line one by one according to the reading order and stops and loops if the next line is on another paragraph.

## Parameters

1. `tolerance`: Ratio used when merging lines into paragraphs taking into account the line height and bottom distance to next line.

   **TIP**: If you see two lines in same paragraph that should be split into two paragraphs decrease tolerance value, if you see two lines in different paragraphs that should be part of same paragraph increase tolerance value.

- Tolerance 0.1
  

- Tolerance 0.25
  

## Accuracy

Almost perfect

## Limitations

- It depends on the reading order detection quality
- To detect the space between paragraphs, it's currently using an heuristics and doesn't detect automatically according the the interline. So if a paragraph have a large interline spacing, the algorithm may fail and create one paragraph per line. That said, this rarely occurs according to our experience.

---

### Overview (`server/src/processing/LinkDetectionModule/README.md`)

# Link Detection Module

## Purpose

The Link detection module detects URLs, GoTo and mailto links inside PDF metadata and it's text contents.

## What it does

It adds the property `targetURL` to the matching Words.

## Dependencies

None.

## How it works

1. It uses pdfminer's `dumppdf` utility and `xml-stream` library to process document metadata as XML and find links with their bounding boxes and page number.
2. Also for each word on document it uses two RegExp to match URL's or emails as strings and also set their `targetURL`

## Accuracy

All correctly detected links from the extractor are well preserved, and the accuracy can thus be reported to be _pretty good_.

## Limitations

- Any 'Action' type link inside metadata is ignored for now. (Can't match their respective bounding boxes).

---

### Overview (`server/src/processing/ListDetectionModule/README.md`)

# List Detection Module

## Purpose

Detects unordered and ordered lists in the text from paragraphs, using bullet points and numberings as indications.

## What it does

Creates new List typed elements in the document based on positively detected paragraphs.

## Dependencies

None

---

### Overview (`server/src/processing/MLHeadingDetectionModule/README.md`)

# ML Heading Detection Module

## Purpose

Create headings from a collection of paragraphs.

## What it does

It creates new heading elements by detecting headings lines from all lines contained in paragraphs.

## Dependencies

- [Lines to paragraph Module](../LinesToParagraphModule/README.md)

## How it works

It uses a series of Machine Learning methods to determine if a block of text is a Heading, based on properties like font styles, text color, number of words, etc.
Also, for all the detected Headings it calculates its level property based on font size, font weight, color, etc.

## Accuracy

Accuracy depends on the quality of the trained models.

Better trained models can be easily imported into this module by following the instruction in the [Training Module Guide](./train_model/README.md).

---

### Overview (`server/src/processing/NumberCorrectionModule/README.md`)

# Number Correction Module

## Purpose

Perform error detection and correction on financial numbers.

## What it does

It iterates on every lines and try to apply a correction on numbers such that:

- `13S` becomes `135`
- `o.oo` becomes `0.00`
- `1,802,86` becomes `1,802.86`
- `443 65` becomes `443.65`

This module has been made to perform error correction on scanned invoices.

## Dependencies

None

## How it works

It generates edits and use a scoring system to select the best candidate.  
It tries to match a regex that can be change via the module's options and can also take a whitelist of elements that should be accepted as is.

## Accuracy

Good

## Limitations

- Can have some false positive and correct things that are not errors on numbers.

---

### Overview (`server/src/processing/OutOfPageRemovalModule/README.md`)

# Out of Page Removal Module

## Purpose

Removes all the elements of the page whose bounding boxes are not physically inside the page.

## What it does

It filters out only the elements which are inside the bounding boxes described in the page's `box` property.

## Dependencies

None

## How it works

It is a simple filter that checks if all the contents of `page.elements` for each page are inside the limits of the page described by `page.box`.

## Accuracy

Very high.
The boundaries of each page and element however, need to be correctly specified by the extractor.

## Limitations

None

---

### Overview (`server/src/processing/PageNumberDetectionModule/README.md`)

# Page Number Detection Module

## Purpose

Detects the page number for each page in a document.

## What it does

Searches for "number" paragraphs outside the page margins, and sets the 'isPageNumber' property to each matched paragraph in the document.

## Dependencies

- [Header Footer Detection](../HeaderFooterDetectionModule/README.md)

## Limitations

This module relies on *accurate page margins* set by the Header Footer Detection Module.

---

### Overview (`server/src/processing/ReadingOrderDetectionModule/README.md`)

# Reading Order Module

## Purpose

Detect the reading order of the document.

## What it does

It adds the `order` property on every element of the page. Elements can then be sorted according to this property.

## Dependencies

None

## How it works

It's based on a XY-cut approach with some optimization.

First, the algorithm will try to find possible vertical cuts in the page between elements. Then, it will perform cuts and try to find possible horizontal cuts in the left part, then the right part. For horizontal cuts, the algorithm will re-assemble blocks if there's some common vertical cuts. This improvement has been made to avoid splitting two columns of text of every line.

## Accuracy

Good

## Limitations

- It sometimes fails if bounding boxes are too far from each others.
- It doesn't work for right to left languages, but can be readapted easily in the code by inverting some functions and sorts.
- It doesn't work when there's a column are in an L shape.

---

### Overview (`server/src/processing/RedundancyDetectionModule/README.md`)

# Redundancy Detection Module

## Purpose

Detects and remove duplicate textual elements on each page of the document.

## What it does

Removes all the elements which exist as duplicates in the document.
If an element **A** has the same content and bounding box as another element **B**, then one of them will be removed.

## Dependencies

None

## How it works

1. Creates groups of text based on location, by checking between each pairs of elements if they are aligned and overlap vertically.
2. For each group, check if the elements are really duplicates by checking the concurrency of their content and bounding boxes.
3. If yes, we keep only one of the elements in the group and remove the others from the collection.

## Accuracy

Good

## Limitations

If the contents and location of the two duplicates are not identical, the removal might not take place.
The accuracy in that case will depend on the delta.

---

### Overview (`server/src/processing/RegexMatcherModule/README.md`)

# Regex Matcher Module

## Purpose

Matches the text against a certain number of Regular Expressions, configurable in the configuration.

## What it does

Generates new metadata info with RegexMetadata object, containing info about the match result and label for the word.

## Example

with config: 
```json
{
  "isCaseSensitive": true,
  "isGlobal": true,
  "queries": [
    {
      "label": "Number",
      "regex": "[0-9]+"
    },
    {
      "label": "unit",
      "regex": "second|seconds|mph|kilometers|km"
    }
  ]
}
```

`document.metadata` property after execution of this module:
```json
[
  {
    "id": 1,
    "elements": [
      561
    ],
    "type": "regex",
    "data": {
      "name": "Number",
      "regex": "[0-9]+",
      "fullMatch": "2008",
      "groups": []
    }
  },
    {
    "id": 2,
    "elements": [
      684
    ],
    "type": "regex",
    "data": {
      "name": "unit",
      "regex": "second|seconds|mph|kilometers|km",
      "fullMatch": "mph",
      "groups": []
    }
  }
]
```
*Here we can see that 2 words had been matched, with element id 561 and 684. Information about the regexp is also included.*

## Dependencies

None 

## Accuracy

Results accuracy depends on the regular expressions sent in the configuration.

---

### Overview (`server/src/processing/RemoteModule/README.md`)

# Remote Module

## Purpose

This module is a bit different than others, because it doesn't change the document by itself.

It exports the document as [JSON](../../../../docs/json-output.md), call an API with it and expect a modified JSON back.

## How to use it

First of all, you need to have a small web server that will handle the API call.
You can use our [example of a remove module in python](../../../../demo/echo-module-py/README.md) as a start.

Your server needs to handle a HTTP `POST` request on the given URL, respond with the modified JSON.

## Dependencies

None

---

### Overview (`server/src/processing/SeparateWordsModule/README.md`)

# Separate Words Module Module

## Purpose

Separates words that are incorrectly joined by a punctuation mark.

## How it works

For every word in the document that is not in the dictionary, checks if it contains punctuation marks like . : , ; ! ?, etc and tries to find words that are separated by this marks.

## Dependencies

None

## Limitations

The module uses the words array of [an-array-of-english-words](https://www.npmjs.com/package/an-array-of-english-words) NPM package. So it can only work with documents written in english.

---

### Overview (`server/src/processing/TableDetection2Module/README.md`)

# Table Detection Module

## Purpose

Table extraction from the PDF file.

## What it does

Given a pdf it generates for each table detected a `table` element containing an array of `tableRows`.

## Dependencies

- Third-party python library [Tabula](https://pypi.org/project/tabula-py/)
- Third-party python library [Camelot](https://camelot-py.readthedocs.io/en/master/index.html)
- [Java JDK 8](https://www.oracle.com/java/technologies/javase-downloads.html)

---

### Overview (`server/src/processing/TableDetectionModule/README.md`)

# Table Detection Module

## Purpose

Table extraction from the PDF file.

## What it does

Given a pdf it generates for each table detected a `table` element containing an array of `tableRows`.

## Dependencies

- Third-party python library [Camelot](https://camelot-py.readthedocs.io/en/master/index.html)

## How it works

Given a table detected by Camelot this module fills `table` contents using and array of `tableRows` that are filled using an array of `tableCells` where each `tableCell` is filled by searching words in the document that are contained in cell bounds.

## Parameters

Following is an example of the configuration of the table-detection module:

```json
[
  "table-detection",
  {
        "checkDrawings": true,
        "runConfig": [
          {
            "pages": [1, 2, 3], // or [] for all pages
            "flavor": "lattice",
            "table_areas": []
          }
        ]
  }
]
```
- checkDrawings: Boolean value to specify if the module should look for table candidates using the previously detected Drawings. Default: true,
- runConfig: Array of different configurations for the doc
  - pages: List of numbers representing pages.
  - flavor: The parsing method to use ('lattice' or 'stream'). Lattice is used by default. For more information on each parsing method, [check this information](https://camelot-py.readthedocs.io/en/master/user/how-it-works.html).
  - table_areas: Array of coordinates forming a box to indicate the position of a table with no outlines or visible borders.
  Each table_area is a string of the form "x1,y1,x2,y2" where (x1, y1) -> top-left and (x2, y2) -> bottom-right in PDF coordinate space. In PDF coordinate space, the bottom-left corner of the page is the origin, with coordinates (0, 0).
  **This parameter is optional and only used with 'stream' flavor.**
  For more information on table_areas param, feel free to check [the camelot documentation](https://camelot-py.readthedocs.io/en/master/user/advanced.html#specify-table-areas).

## Accuracy

The accuracy is high.

## Limitations

- Only works with text-based PDFs and not scanned documents.

---

### Overview (`server/src/processing/TableOfContentsDetectionModule/README.md`)

# Table of Contents Detection Module

## Purpose

Detects and extracts tables of content from the PDF file.

## What it does

Given a pdf it generates a `TableOfContent` element containing an array of `TableOfContentItem`'s with info for each item.

## How it works

Searches for keywords and specific paragraph formats and then extracts the info from each detected paragraph with Regular Expressions

## Parameters

Following is an example of the configuration of the table-of-contents-detection module:

```json
[
  "table-of-contents-detection",
  {
    "pageKeywords": [
      "pag",
      "pagina",
      "page,
    ]
  }
]
```

- pageKeywords: Optional. Array of "page" string to prepend and search for TOC items with format "page X - Section A". 
  Defaults to "pag".

## Accuracy

The accuracy is high on one-column documents.

---

### Overview (`server/src/processing/TemplateModule/README.md`)

A template module showing how to make an easily integrable template into the Parsr pipeline.

---

### Overview (`server/src/processing/WhitespaceRemovalModule/README.md`)

# Whitespace Removal Module

## Purpose

Removes textual elements containing only whitespace as content.

## What it does

Removes (filters out) all the textual elements not containing any content at all.

## Dependencies

None

## Parameters

`minWidth`: The minimum width to see if an element is at least a certain size for it to be taken into consideration as a candidate for removal

## How it works

All whitespace textual elements are checked to see if their width is less than `minWidth`, then checked if they are overlapping with other text elements (a very common case), and then deleted.

## Accuracy

Good. The module treats the most common cases, but its completeness is based on observation. New edge-cases might appear and will be interesting to treat in the future.

---

### Overview (`server/src/processing/WordsToLineModule/README.md`)

# Words to Line Module

## Purpose

Create lines from a bunch of words, according to the reading order.

## What it does

It creates new line elements that contains arrays of word elements.

## Dependencies

[Reading Order Module](../ReadingOrderDetectionModule/README.md)

## How it works

It simply takes every word one by one according to the reading order and stops and loops if the next word is on another line.

## Accuracy

Almost perfect

## Limitations

- It depends on the reading order detection quality
- It sometimes fails if lines are close to each others and there's an exponent

---

### Overview (`server/src/processing/WordsToLineNewModule/README.md`)

# Words to Line New Module

## Purpose

Create lines from a bunch of words inside pages.

## What it does

It creates new line elements that contains arrays of word elements.

## Dependencies

No dependencie.

## How it works

It takes every word of the page one by one, then it is splitted into line depending of vertical alignement, finaly each line can be splitted when a space between two words is big enough according to the average space and common space between words.

## Accuracy

Almost perfect.

## Limitations

If on specific case it is not working, you can tune up by incrementing / decrementing value of average and common space detected between words.

---

### Overview (`server/src/processing/MlHeadingDetectionModule/train_model/README.md`)

## Required dependencies
`python3 -m pip install spacy`
`python3 -m pip install markdown`
`python3 -m pip install imblearn`
`python3 -m pip install sklearn_porter`
`python3 -m pip install scikit-learn==0.22.2`
`python3 -m spacy download en_core_web_sm`
`pip3 install beautifulsoup4`

## Building the Dataset (this step is optional)

To build the dataset used to train the model run `python3 build_dataset.py <markdown folder> <json folder> <output folder>`.

**markdown folder:**\
It contains markdown files corresponding to the annotated documents. The headings are used to generate the training labels for heading detection.

**json folder:**\
It contains json files as produced by Parsr. Each file must correspond to a file in the markdown folder. It must have the same name but use the .json extension instead of .md.

**output:**\
For each document, the script generates a corresponding csv in the output folder. The csv contains the following columns:
1. line: the line as extracted by Parsr. It should correspond to a line in the pdf document.
2. is_different_style: indicates whether the line has a different font weight compare to the most common font in the document.
3. is_font_bigger: indicates whether the line has a bigger font size compare to the most common font in the document.
4. different_color: indicates whether the line has a different color compare to the most common font in the document.
5. is_font_unique: indicates whether the line has only one font.
6. text_case: text case of the line (upper case, lower case, title case or none of them)
7. word_count: number of words in the line 
8. is_number: indicates whether the line is constituted by a number
9. nb_verbs: number of verbs in the line
10. nb_nouns: number of nouns in the line
11. nb_cardinal_numbers: number of cardinal numbers in the line
12. font_size: the font size of the line
13. is_bold: whether the line is bold or not
14. level: the level of the headings (= 0 if it is not a heading)
15. label: "paragraph" or "heading"

```
usage: build_dataset.py [-h] md_dir json_dir out_dir

Extracts features to csv from .json files using .md files as labels

positional arguments:
  md_dir      folder containing the .md files (labels)
  json_dir    folder containing the .json files (data)
  out_dir     folder in which to save the .csv files

optional arguments:
  -h, --help  show this help message and exit
```

## Training the models

To train the model that detects headings and the one that computes their levels run `python3 train.py.py <csv folder> <output folder>`.

**Fast usage (without building the dataset):** `python3 train.py <training_set> <output folder>`

Where `training_set` is the folder containing the csv files and they are selected to obtain better performances, the folder is available on AXA-Parsr-Benchmark.

**csv folder**:\
It contains the csv generated by `build_dataset.py` and must contain csv files formatted as described previously.

**output**:\
The script generates the files `model.js` and `model_level.js` containing the executable models. This script should be placed in `server/src/processing/MlHeadingDetectionModule/train_model`.
It also generates the files `levels_model.pkl` and `headings_model.pkl` which are automatically saved in `server/assets`.

```
usage: train.py [-h] dataset_dir out_dir

Train a random forest model to recognize headings and a decision tree model to compute their levels.

positional arguments:
  dataset_dir  folder containing the .csv files generated by build_dataset.py
  output_dir      folder in which to save the trained models

optional arguments:
  -h, --help   show this help message and exit
```

---

### Abbyy Finereader (`docs/abbyy-finereader.md`)

# ABBYY FineReader Server

The ABBYY FineReader is a high-precision OCR option provided to the users of the Parsr platform.
It is to be noted that it is completely optional, and that the default OCR solution supported under Parsr is tesseract, which is a dependency of the solution.

## Essential Server Configuration

When ABBYY FineReader Server is chosen as the working OCR extraction solution, the following environment variables need to be set on the host running Parsr:

1. `ABBYY_SERVER_URL` : The network address of the ABBYY FineReader Server.
2. `ABBYY_SERVER_VER` : The major version number of the ABBYY FineReader Server. For example: 14 for ABBYY FineReader Server 14.01.
3. `ABBYY_WORKFLOW` : The name of the server 's workflow to be called to process the file.

On the side of the ABBYY FineReader Server, make sure the XML output is configured for the selected workflow:

1. Double click on the workflow to be used.
2. In the tab titled 'output', make sure the list of file formats exported contains the XML format if not, add it with the 'New' button.
3. Make sure the following settings are enabled on the XML format 's settings:
   1. Character Attributes
   2. Extended Character Attributes
   3. Coordinates of the Original Image
   4. Character Formatting

## Usage

One simply has to use the `abbyy` keyword in the [configuration file](configuration.md#21-extractor-tools) in the input section to use it.

---

### Api Guide (`docs/api-guide.md`)

# API Guide

This page is a guide on how to use the API.

- [0. Introduction](#0-introduction)
- [1. Send Your Document: POST /document](#1-send-your-document-post-document)
  - [`curl` command](#curl-command)
  - [Status: 202 - Accepted](#status-202---accepted)
  - [Status: 415 - Unsupported Media Type](#status-415---unsupported-media-type)
- [2. Get the queue status: GET /queue/{id}](#2-get-the-queue-status-get-queueid)
  - [`curl` command](#curl-command-1)
  - [Status: 200 - OK](#status-200---ok)
  - [Status: 201 - Created](#status-201---created)
  - [Status: 404 - Not Found](#status-404---not-found)
  - [Status: 500 - Internal Server Error](#status-500---internal-server-error)
- [3. Get the results](#3-get-the-results)
  - [3.1. JSON, Markdown and Text results](#31-json-markdown-and-text-results)
    - [`curl` command](#curl-command-2)
    - [Status: 200 - OK](#status-200---ok-1)
    - [Status: 404 - Not Found](#status-404---not-found-1)
  - [3.2. CSV List of Files: GET /csv/{id}](#32-csv-list-of-files-get-csvid)
    - [`curl` command](#curl-command-3)
    - [Status: 200 - OK](#status-200---ok-2)
    - [Status: 404 - Not Found](#status-404---not-found-2)
  - [3.3. CSV File: GET /csv/{id}/{page}/{table}](#33-csv-file-get-csvidpagetable)
    - [`curl` command](#curl-command-4)
    - [Status: 200 - OK](#status-200---ok-3)
    - [Status: 404 - Not Found](#status-404---not-found-3)
  - [3.4. Download Results](#34-download-results)
- [4. Server Configuration Access](#4-server-configuration-access)
  - [4.1. Default Configuration](#41-default-configuration)
  - [4.2. List of Modules](#42-list-of-modules)
  - [4.3. Module Configuration](#43-module-configuration)
  - [4.4. Checking Installed Dependencies](#44-checking-installed-dependencies)

## 0. Introduction

First of all there is a few things to know:

- **The API is RESTful:** The API is over HTTP and follow REST standards.
- **The API is asynchronous:** There is a simple queue system and every job is managed by the API server.

The API has an endpoint prefix `/api` and then, optionally, the version number `/v1.0`. That mean every request must be send to:

- `/api/v1.0`: will use the API version 1.0
- `/api/v1`: will use the latest API version 1.x
- `/api`: will use the latest API version

## 1. Send Your Document: `POST /document`

First of all, you need to do a POST request to send the document to Parsr. Along that, you can send the configuration file to tell Parsr what kind of processing it must perform on the file. If you don't provide a config file, the default config file will be used.

**Regarding the configuration file, please refer to the [configuration file documentation](configuration.md).** (**Tip**: You can also obtain the default configuration on the server via the endpoint: `/api/v1/default-config`. See [Section 4](#4-server-configuration-access).)

### `curl` command

```sh
curl -X POST \
  http://localhost:3001/api/v1/document \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@/path/to/file.pdf;type=application/pdf' \
  -F 'config=@/path/to/config.json;type=application/json'
```

**Windows tip:** Use double quotes `"` instead of single quote `'`

```sh
curl -X POST \
  http://localhost:3001/api/v1/document \
  -H "Content-Type: multipart/form-data" \
  -F "file=@/path/to/file.pdf;type=application/pdf" \
  -F "config=@/path/to/config.json;type=application/json"
```

### Status: 202 - Accepted

```
00cafe4463b9c12aac145b3ee8f00d
```

The document you sent has been accepted and is being processed. The body contains the unique **queue ID**. You need to keep it somewhere for later, to know what's the queue status and get the results.

### Status: 415 - Unsupported Media Type

This error means the file format you sent is not supported by the platform.

## 2. Get the queue status: `GET /queue/{id}`

This request allows you to get the status of the queued document being processed. You need to give it the **queue ID** that was return in the previous request.

### `curl` command

```sh
curl -X GET \
  http://localhost:3001/api/v1/queue/00cafe4463b9c12aac145b3ee8f00d
```

### Status: 200 - OK

```json
{
  "estimated-remaining-time": 30,
  "progress-percentage": 10,
  "start-date": "2018-12-31T12:34:56.789Z",
  "status": "Detecting reading order..."
}
```

This status means the document is still being processed.

The `estimated-remaining-time` is expressed in seconds.

_**NB:** `estimated-remaining-time` and `progress-percentage` are not working yet and are placeholder for future usage._

### Status: 201 - Created

```json
{
  "id": "00cafe4463b9c12aac145b3ee8f00d",
  "json": "/api/v1/json/00cafe4463b9c12aac145b3ee8f00d",
  "csv": "/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d",
  "text": "/api/v1/text/00cafe4463b9c12aac145b3ee8f00d",
  "markdown": "/api/v1/markdown/00cafe4463b9c12aac145b3ee8f00d"
}
```

This status is sent when the processing is done. It returns links to the generated resources and the ID of the document for convenience.

### Status: 404 - Not Found

This error means the queue ID doesn't refer to any known processing queue.

### Status: 500 - Internal Server Error

This error means that something went terribly wrong on the backend, probably an error coming from Parsr.

## 3. Get the results

You can have results in different formats:

- JSON: `GET /json/{id}`
- Markdown: `GET /markdown/{id}`
- Raw text: `GET /text/{id}`
- CSV: `GET /csv/{id}`

These requests allow you to get the results of the processed document. You need to give it the **queue ID** that was return in a previous request.

### 3.1. JSON, Markdown and Text results

The queries for JSON, Markdown and raw text are all working in the same way. CSV is a bit different and is described in the next section.

#### `curl` command

```sh
curl -X GET \
  http://localhost:3001/api/v1/json/00cafe4463b9c12aac145b3ee8f00d
```

#### Status: 200 - OK

```js
{
	"metadata": [/* ... */],
	"fonts": [/* ... */],
	"pages": [/* ... */],
}
```

For more information on the JSON format, please [refer to the specific guide](json-output.md).

#### Status: 404 - Not Found

This error means that the result file doesn't exist. Maybe it wasn't asked to be outputted in the config you sent in the first request.

### 3.2. CSV List of Files: `GET /csv/{id}`

Since you can have multiple tables per page, you need to query them in two steps:

First of all, get the list of every CSV files' paths:

#### `curl` command

```sh
curl -X GET \
  http://localhost:3001/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d
```

#### Status: 200 - OK

```json
[
  "/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d/1/1",
  "/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d/2/1",
  "/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d/2/2",
  "/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d/3/1"
]
```

#### Status: 404 - Not Found

This error means that the result file doesn't exist. Maybe it wasn't asked to be outputted in the config you sent in the first request.

### 3.3. CSV File: `GET /csv/{id}/{page}/{table}`

Then, we can get the CSV files one by one with the following parameters:

- `{id}` is the ID of the document
- `{page}` is the page number
- `{table}` is the table number

#### `curl` command

```sh
curl -X GET \
  http://localhost:3001/api/v1/csv/00cafe4463b9c12aac145b3ee8f00d/1/1
```

#### Status: 200 - OK

```csv
3x4 table;Empty column;Numbers
;;
Item A;;3.14
"Item B
on two lines";;1,234.56
```

This CSV output example contains multiline cells and an empty column.

#### Status: 404 - Not Found

This error means that the result file doesn't exist. Maybe `{page}` and `{table}` parameters doesn't refer to an or it wasn't asked to be outputted in the config you sent in the first request.

### 3.4. Download Results

You can download any of the available output formats:

- JSON: `GET /json/{id}?download=1`
- Markdown: `GET /markdown/{id}?download=1`
- Raw text: `GET /text/{id}?download=1`
- CSV: `GET /csv/{id}?download=1`

Being `{id}` the same **queue ID** obtained in [Section 3 - Get the results](#3-get-the-results).

For JSON and Raw Text, a `json` or `txt` file will start downloading.
For Markdown, if the document has any embedded assets like images, a `zip` file will start downloading, including the markdown and a folder with all required assets. If it does not contain any images, a single `md` file will be downloaded.
For CSV option, a `zip` will be downloaded, containing one `csv` file per each table in the document.

## 4. Server Configuration Access

The API can also be queried to gain access to the following server assets:

### 4.1. Default Configuration

The server's default configuration can be queried (at `/api/v1/default-config`) using:

    curl -X GET \
    http://localhost:3001/api/v1/default-config

### 4.2. List of Modules

The list of all usable modules can be queried from the server (at `/api/v1/modules`) using:

    curl -X GET \
    http://localhost:3001/api/v1/modules

### 4.3. Module Configuration

A module's configuration file, which includes name, description and each module parameter's default value and range can be queried (at `/api/v1/module-config/<module_name>`) using:

    curl -X GET \
    http://localhost:3001/api/v1/module-config/table-detection

... which will fetch the configuration file for the table-detection module.

### 4.4. Checking Installed Dependencies

If you run into troubles running Parsr, a good first way to check if every required dependency is installed is by going to:

    http://localhost:3001/api/v1/check-installation



A table will be displayed, showing every required (and optional) dependency, and it's path in your system. If you find that your system is missing a dependency, refer to the [installation guide](installation.md) to fix the problem.

---

### Configuration (`docs/configuration.md`)

# Parsr Configuration

- [Parsr Configuration](#parsr-configuration)

  - [1. Structure](#1-structure)
  - [2. Extractor Config](#2-extractor-config)
    - [2.1. Extractor Tools](#21-extractor-tools)
    - [2.2. Language](#22-language)
  - [3. Cleaner Config](#3-cleaner-config)
  - [4. Output Config](#4-output-config)
    - [4.1. Output Format](#41-output-format)
    - [4.2. Granularity](#42-granularity)
    - [4.3. Include Marginals](#43-include-marginals)
    - [4.4. Include Drawings](#44-include-drawings)
  - [5. Exempli gratia](#5-exempli-gratia)

To configure the pipeline and choose what modules will be called and with what parameters, you have to provide a JSON file.
There is only a few required keys:

- `version` `[Number]` is the version number of the API.
- `extractor` `[Object]` is a bunch of parameters about the extraction.
- `cleaner` `[Array]` is a list of every cleaning tools that will be called.
- `output` `[Object]` contains the list of formats to export and some other details.

Cleaning tools have default parameters that work pretty well, but you can override the parameters by providing them in the config.

The cleaner array may appear unconventional but is really easy to use. Every item can be of type:

- `String`: it's the name of the cleaning tool you want to call.
- `Object`: it's the parameters for the cleaning tool below.

## 1. Structure

```
/* Detailed source-code truncated for AI context efficiency. */
```

_This means the module called `module-name-1` will be called, then `module-name-2`, then `module-name-3` with some special parameters, etc._

## 2. Extractor Config

### 2.1. Extractor Tools

Different extractors are available for each input file format.

- **PDF files:** four extractors are currently available for PDF files:

  - `pdfminer`, which is an advanced python based extractor capable of extracting low and high level textual structures (from characters to paragraphs),
  - `pdfjs`, Mozilla's free solution for parsing documents. This is the recommended extractor to parse large documents (200+ pages).
  - `abbyy`, uses ABBYY Finereader service to extract contents from a PDF.

  If none is specified, `pdfminer` is the default one.

- **Images:** five OCR extractors are supported for images:

  - `tesseract` which is an Open Source OCR software,
  - `abbyy`, that relies on ABBYY Finereader, a paid solution for OCR on documents and images,
  - `google-vision`, which uses the [Google Vision](https://cloud.google.com/vision/) API to detect the contents of an image (see the [google vision documentation for more](../server/src/input/google-vision/README.md)),
  - `ms-cognitive-services`, that uses [Microsoft Cognitive Services](https://azure.microsoft.com/es-es/services/cognitive-services/) OCR to detect and process text inside an image.
  - `amazon-textract`, that uses [Amazon Textract](https://us-east-2.console.aws.amazon.com/textract/home) service to detect and process text inside an image.

  If none is specified, `tesseract` is the default one.

*Other supported file formats:*
- **XML:** if an XML file is used as input, it will be interpreted with ABBYY.
- **JSON:** JSON files extractor will expect the structure defined in [Parsr JSON output](json-output.md)
- **EML:** .eml files will be converted into a PDF with A4 size pages, and then processed with the selected PDF extractor.
- **DOCX:** .docx files will be converted into a PDF with A4 size pages, and then processed with the selected PDF extractor.

### 2.2. Language

The language parameter is an option that will be pass to Tesseract when using it. It must be in the [Tesseract language format](https://github.com/tesseract-ocr/tesseract/blob/master/doc/tesseract.1.asc#languages), which is an equivalent of [ISO 639-2/T](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).

### 2.3 Credentials

Each input module may require some credentials to work properly.
For example, `ms-cognitive-services` extractor requires two values:

```json
{
  "OCP_APIM_SUBSCRIPTION_KEY": "<SUBSCRIPTION_KEY>",
  "OCP_APIM_ENDPOINT": "https://westeurope.api.cognitive.microsoft.com/"
}
```

`OCP_APIM_SUBSCRIPTION_KEY` has to be obtained through Azure web console.
`OCP_APIM_ENDPOINT` is required, but has a default value set.

Default credential values for each module can be found in each `credentials.json` file.

The recommended way to set credentials is to add them to the extractor config:

```json
  "extractor": {
    "pdf": "pdfminer",
    "ocr": "ms-cognitive-services",
    "credentials": {
      "OCP_APIM_SUBSCRIPTION_KEY": "<API_KEY>",
      "OCP_APIM_ENDPOINT": "<API_ENDPOINT>" //as OCP_APIM_ENDPOINT is already defined in credentials.json, this key can be omitted.
    }
  },
```

For more information about input modules and their required credentials, you can check the [Input Modules Documentation](../server/src/input/README.md).

## 3. Cleaner Config

The pipeline is defined by every module names and their options. Modules will then be run one by one in the same order as in the configuration.

Module can be called in the full form:

```json
[
	"module",
	{
		"option-1": 100,
		"option-2": true
	}
],
```

Or just with there default options:

```json
[
	"module"
],
```

Or just with there default options in the condensed format:

```json
"module",
```

_Note: some modules have dependencies that need to be called before in the pipeline._

## 4. Output Config

### 4.1. Output Format

The platform can export the following formats:

- `json`, structure defined in [Parsr JSON output](json-output.md).
- `simpleJson`, structure defined in [Parsr simpleJSON output](simple-json-output.md).
- `markdown`,
- `text`,
- `csv`,
- `pdf` (pandoc required)

### 4.2. Granularity

The `granularity` parameter can be either `word` or `character` and defines at what level of granularity the export will be.

If the level is not specified, `word` is the default one.

_Warning: exporting with a character granularity will result on very big Json files (probably more than 10Mo)._

### 4.3. Include Marginals

The `includeMarginals: boolean` parameter allows to chose whether the output will include headers and footers.

### 4.4. Include Drawings

The `includeDrawings: boolean` parameter specifies if json output should contain information about Drawings.

*Warning: including Drawings information could greatly increase json output size.*

## 5. Exempli gratia

```json
{
  "version": 0.9,
  "extractor": {
    "pdf": "pdfminer",
    "ocr": "tesseract",
    "language": ["eng", "fra"]
  },
  "cleaner": [
    "out-of-page-removal",
    "whitespace-removal",
    "redundancy-detection",
    "table-detection",
    ["header-footer-detection", { "maxMarginPercentage": 15 }],
    ["reading-order-detection", { "minColumnWidthInPagePercent": 15 }],
    "link-detection",
    ["words-to-line-new", { "maximumSpaceBetweenWords": 100 }],
    "lines-to-paragraph",
    "page-number-detection",
    "hierarchy-detection",
    [
      "regex-matcher",
      {
        "queries": [
          {
            "label": "Car",
            "regex": "([A-Z]{2}\\-[\\d]{3}\\-[A-Z]{2})"
          },
          {
            "label": "Age",
            "regex": "(\\d+)[ -]*(ans|jarige)"
          },
          {
            "label": "Percent",
            "regex": "([\\-]?(\\d)+[\\.\\,]*(\\d)*)[ ]*(%|per|percent|pourcent|procent)"
          }
        ]
      }
    ]
  ],
  "output": {
    "granularity": "word",
    "includeMarginals": false,
    "includeDrawings": false,
    "formats": {
      "json": true,
      "text": true,
      "csv": true,
      "markdown": true,
      "pdf": false
    }
  }
}
```

---

### Dependencies (`docs/dependencies.md`)

# Parsr Dependencies

This page lists all of the dependencies of Parsr and what they are used for.

- [Parsr Dependencies](#parsr-dependencies)
  - [1. Base Dependencies](#1-base-dependencies)
  - [2. Extraction Dependencies](#2-extraction-dependencies)
  - [3. Optional Dependencies](#3-optional-dependencies)
  
## 1. Base Dependencies

The following _required_ dependencies need to be installed for Parsr to work properly:

1. `node.js` : The underlying framework upon which the platform is built.
2. `qpdf` : For reading password-protected PDFs.
3. `imagemagick` : For converting between file formats.

## 2. Extraction Dependencies

Depending upon the type of documents to be treated by the platform, one or multiple of the following dependencies should be installed.

If simple PDFs containing digital (or _selectable_) textual elements are to be fed into the system, the **`pdfminer`** library needs to be installed.

If images (`jpg`, `png`, `tiff`, etc.) are to be used with the tool, then the tool also supports the use of the following two OCR based solutions as an underlying extraction module:

1. **`tesseract`** : Open source, support for over ~100 languages, Google's Tesseract is a free, on premise OCR solution. However, text formatting, or tabular data is not detected.
2. **`ABBYY FineReader Server`** : Proprietary OCR solution with extremely high recognition accuracy, formatting recognition and tabular data extraction. It is an optional dependency.

## 3. Optional Dependencies

The following _optional_ dependencies may to be installed:

1. `mupdf-tools`: For error-correcting corrupt PDFs at input.
2. `pandoc`: Generate PDF files from an intermediate Markdown output after the cleaning operation in the pipeline.

---

### Docker (`docs/docker.md`)

# Docker

- [Docker](#docker)
  - [1. Run Parsr](#1-run-parsr)
  - [2. Build Parsr](#2-build-parsr)

## 1. Run Parsr

In the root of the repository, launch:

```
docker-compose up
```

This will start 2 containers :

- one for the API listening on http://localhost:3001
- the second one for the demo UI listening on http://localhost:8080

Note: a docker volume will be created at first launch so that the data will be kept at containers restart.

## 2. Build Parsr

If you want to build parsr by yourself, at the root of the project, launch:

```
docker-compose -f docker-compose-build.yml build
```

This will build Parsr, along with its dependencies.

---

### Gui Guide (`docs/gui-guide.md`)

# GUI Guide

The Parsr GUI is intended for a quick visualization of the most used Parsr output formats: **json**, **markdown**, **raw text** and **csv**. Please note that **there are more output formats available**.

- [1. Upload a Document](#1-upload-a-document)
  - [1.1. Configuration](#11-configuration)
- [2. Visualize results](#2-visualize-results)
  - [2.1. JSON](#21-json)
    - [2.1.1. Visibility filters](#211-visibility-filters)
    - [2.1.2. Font inspector](#212-font-inspector)
    - [2.1.3. Element inspector](#213-element-inspector)
  - [2.2. Markdown](#22-markdown)
  - [2.3. Raw Text](#23-raw-text)
  - [2.4. CSV](#24-csv)
- [3. Download results](#3-download-results)

## 1. Upload a Document

To upload a document and start Parsr process, simply go to http://localhost:8080/ or click on the `Upload` tab if already there. Here you will be able to select an input file and the modules you want to execute.



### 1.1. Configuration

The available parameters on this screen are taken from the [default configuration file](../server/defaultConfig.json). 

Once you are ready, you can click on the `SUBMIT` button at the bottom of the page. Parsr process will start executing and a progress pop-up will be shown. Once it finishes, you will be redirected to the [JSON results](#21-json) tab.

**Note**: *Here you will be able to select an extractor for the file, as well to enable/disable modules and changing their default parameters. If you want to configure anything else, you will need to manually edit the configuration file and reload the page for the changes to be applied.*

## 2. Visualize results

The GUI has 4 output formats available for inspection, described below:

### 2.1. JSON

The most rich format, here you will find information about `words`, `lines`, `paragraphs`, `tables`, etc., its position relative to top-left corner of the page, a hierarchical structure of the blocks and more.
The JSON Parsr output will be interpreted and shown in a user-friendly way.



#### 2.1.1. Visibility filters

With the visibility filters you can enable/disable the containing bounding boxes of the elements. In the example figure, `headings` are marked on fuchsia, `paragraphs` are marked on red and `tables` are marked with light-blue.



#### 2.1.2. Font inspector

On the font inspector you will see information about every `font` on the document, with its properties and usage ratios.



#### 2.1.3. Element inspector

You can click on every word inside the document. It will turn red and information about that element will be shown on the element inspector. Here you can move between elements of the same type by clicking on the next / previous buttons. Also you will font font information, contents of that element and properties of the element bounding box.
On the "Word hierarchy" section, you can click on the hierarchical parent of the selected element, and it will be highlighted on the page.



### 2.2. Markdown

Markdown result is a rich text document that defines `headings` and their level, `paragraphs`, `tables`, `lists`, `images`, etc. Block hierarchy can be partially reconstructed with this output. 



### 2.3. Raw Text

Plain-text version of the document containing no formats or bounding box information.



### 2.4. CSV

On the csv section, you will see a CSV (semicolon separated values) table with a unique identifier for each of the tables in the document.



## 3. Download results

If you want, you can also save this four output formats with the download button located on the top-right corner of the window.

---

### Installation (`docs/installation.md`)

# Parsr Installation Guide

- [Parsr Installation Guide](#parsr-installation-guide)
  - [1. Docker Installation](#1-docker-installation)
  - [2. Automatic Installation](#2-automatic-installation)
  - [3. Bare-Metal Installation](#3-bare-metal-installation)
    - [3.1. Installing Dependencies under Linux](#31-installing-dependencies-under-linux)
    - [3.2. Installing Dependencies under MacOS](#32-installing-dependencies-under-macos)
    - [3.3. Installing Dependencies under Windows](#33-installing-dependencies-under-windows)
  - [4. Optional Dependencies](#4-optional-dependencies)
    - [4.1. MuPDF](#41-mupdf)
    - [4.2. Pandoc](#42-pandoc)
    - [4.3. ABBYY FineReader](#43-abbyy-finereader)
  - [5. Node.js Dependencies](#5-nodejs-dependencies) 
  - [6. Checking Installation](#6-checking-installation) 

This document will guide you through the installation process.

You can install Parsr either using [Docker containers](#1-docker-installation), or directly on your machine with an [automatic script](#2-automatic-installation) or [manually](#3-bare-metal-installation). You don't need to do everything!

## 1. Docker Installation

Containers are already available on [Docker Hub](https://hub.docker.com/u/axarev).

The documentation to build and run Docker containers is [here](docker.md).

## 2. Automatic Installation

You can install Parsr locally via a Node.js script:

1. [Download and install **`node.js`**](https://nodejs.org/en/download)
2. In the root of Parsr directory, open a terminal and run `npm run install:pre`.
  This command will install every required and optional dependency.  

For Windows platforms, this script requires **TLS 1.2 or newer** enabled.

## 3. Bare-Metal Installation

*Note: Currently, table detection requires Python 3.7 and below, as a vital dependency, `camelot-py` has not been ported yet to Python 3.8.*

If the automatic install script is not available for your platform, you can always do a manual installation following this steps:

### 3.1. Installing Dependencies under Linux

Under a **Debian** based distribution:

```sh
sudo add-apt-repository ppa:ubuntuhandbook1/apps
sudo apt-get update
sudo apt-get install nodejs npm qpdf imagemagick tesseract-ocr libtesseract-dev python3-tk ghostscript python3-pip
pip install camelot-py[cv] numpy pillow scikit-image PyPDF2 pdfminer.six sklearn
```

Under **Arch** Linux:

```sh
pacman -S nodejs npm qpdf imagemagick python-pdfminer tesseract python-pip
pip install camelot-py[cv] numpy pillow scikit-image PyPDF2 pdfminer.six sklearn
```

Note: if camelot-py[cv] generates an error in console, you might want to try replacing it with camelot-py\\[cv\\].

### 3.2. Installing Dependencies under MacOS

The package manager we suggest using under MacOS is [homebrew](https://brew.sh/).
To install it, launch the following in a terminal

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

Next, install the required dependencies:

```sh
brew install node python qpdf imagemagick tesseract tesseract-lang tcl-tk ghostscript
```

Next, upgrade python:

```sh
brew upgrade python
```

To install the python3 based dependencies (pdfminer and camelot), install, first install `pip3`:

```sh
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
```

and then the dependencies:

```sh
pip3 install pdfminer.six
pip3 install camelot-py[cv]
pip3 install numpy pillow scikit-image
python2.7 -m pip install PyPDF2
```

To install the python2 based dependencies (pdfminer and camelot), install, first install `pip`:

```sh
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
```

and then the dependencies:

```sh
python2.7 -m pip install PyPDF2
```

### 3.3. Installing Dependencies under Windows

The installation procedure for Parsr requires the command `where.exe` to be in the path.  
Try typing `where` in the command prompt. If the command cannot be found, execute the following to add its location to PATH:

```sh
setx PATH "\$env:PATH;C:\Windows\System32" -m
```

Then,

1. We recommend using [Chocolatey](https://chocolatey.org) as the package manager for installing dependencies under Windows. To install Chocolatey, [follow these instructions](https://chocolatey.org/install#installing-chocolatey).
2. [Download and install **`node.js`**](https://nodejs.org/en/download)
3. For the **pdfminer** extractor for pdfs, [follow these steps](https://github.com/pdfminer/pdfminer.six#how-to-install).
4. Install **`qpdf`** and **`imagemagick`** using Powershell (Run as Administrator):

   ```sh
   choco install qpdf imagemagick
   ```

5. For table detection, install [**camelot**](https://camelot-py.readthedocs.io/en/master/user/install.html#install).

6. For **`tesseract`** you can download and install, or check out other available formats on [the wiki](https://github.com/UB-Mannheim/tesseract/wiki).
Then, you need to add tesseract.exe to your PATH:
If you have install it in `C:\Program Files (x86)\Tesseract-OCR`, you can either add it [using the user interface](https://docs.alfresco.com/4.2/tasks/fot-addpath.html) execute the following command in Powershell (Run as Administrator):
    ```sh
    setx PATH "\$env:PATH;C:\Program Files (x86)\Tesseract-OCR" -m
    ```
7. For PDF manipulation, install [PyPDF2](https://pypi.org/project/PyPDF2). *Note: If camelot is installed, PyPDF2 will be already available.*

## 4. Optional Dependencies

The following dependencies are **completely optional**, and their exclusion does not hinder the proper functioning of the Parsr pipeline.

The functions of each, as well as the installation process are are explained below:

### 4.1. MuPDF

MuPDF, in the Parsr platform is Used to fix certain error-prone or corrupt PDF files on input.

To install MuPDF, follow the steps corresponding to your environment:

- Under a **Debian** based distribution:

  ```sh
  sudo apt-get install mupdf mupdf-tools
  ```

- Under **Arch** Linux:

  ```sh
  pacman -S mupdf-tools
  ```

- Under MacOS:

  ```sh
  brew install mupdf-tools
  ```

- Under Windows:

  ```sh
  choco install mupdf
  ```

If MuPDF is not installed, a corrupt/unreadable PDF file at input will be left untreated.
A message of such an occurrence will be logged.

### 4.2. Pandoc

Pandoc is a document format conversion program, used under Parsr to generate PDF files from an intermediate Markdown output after the cleaning operation in the pipeline.

To install Pandoc, follow the steps corresponding to your environment:

- Under a **Debian** based distribution:

  ```sh
  sudo apt-get install pandoc
  ```

- Under **Arch** Linux:

  ```sh
  pacman -S pandoc
  ```

- Under MacOS:

  ```sh
  brew install pandoc
  ```

- Under Windows:

  ```sh
  choco install pandoc
  ```

If Pandoc is not installed, the user will not be able to generate PDF files on output.
Any configuration requiring a PDF file output will be ignored.

### 4.3. ABBYY FineReader

ABBYY FineReader is a proprietary high precision OCR solution for generating rich text from images.
One can obtain the ABBYY FineReader Server from [here](https://www.abbyy.com/en-us/finereader-server/).

ABBYY FineReader is an **optional dependency**, and it's absence should in no way hinder the everyday usage of Parsr's default OCR solution, tesseract.

## 5. Node.js Dependencies

To install every Node dependency, just open a terminal at the root directory of Parsr and type:

```sh
npm install
```

## 6. Checking Installation

To verify that you have everything correctly installed, you can follow this steps:

- Run the test suite:
  ```sh
  npm run test
  ```

- Start the API:
  ```sh
  npm run start:api
  ```

- Open the following URL on your browser:
  
  http://127.0.0.1:3001/api/check-installation

  
If all test passed and every required dependency is found, then you're good to go!

---

### Json Output (`docs/json-output.md`)

# JSON Output

This page describes the components of the JSON output file in detail.

- [JSON Output](#json-output)
  - [0. Introduction](#0-introduction)
  - [1. `pages` component](#1-pages-component)
    - [1.1. Bounding Boxes](#11-bounding-boxes)
    - [1.2. Element types](#12-element-types)
      - [1.2.1. Text type](#121-text-type)
      - [1.2.2. Table type](#122-table-type)
      - [1.2.3. List type](#123-list-type)
      - [1.2.4. Barcode type](#124-barcode-type)
      - [1.2.5. Image type](#125-image-type)
      - [1.2.6. Drawing type](#126-drawing-type)
    - [1.3. Properties of an Element](#13-properties-of-an-element)
  - [2. `fonts` component](#2-fonts-component)
  - [3. `metadata` component](#3-metadata-component)
    - [3.1. Key-Value pair metadata](#31-key-value-pair-metadata)
    - [3.2. Regex metadata](#32-regex-metadata)

## 0. Introduction

The output JSON file is composed of the following overall structure:

```js
{
  "metadata": [/* ... */],
  "fonts": [/* ... */],
  "pages": [/* ... */],
}
```

This file represents the generated output from each of the extraction, cleaning and enrichment modules.

## 1. `pages` component

`pages` contains an array representing a single page of the document. It contains the following structure:

```js
"pages" : [
  0: {
    "box": {/* ... */},            // Bounding box of the page, see Section 1.1
    "pageNumber": "1",             // The page's page number
    "elements": [                  // The elements (contents) on the page.
      0: {                         // The first element.
        "box": {/* ... */},        // Bounding box for this particular element.
        "type": "heading",         // The type of the element; see Section 1.2
        "properties": [/* ... */], // Properties of the element; see Section 1.3
        "metadata": [/* ... */],   // Indices of all the metadatas associated with this element.
        "content": [/* ... */],    // List of contents inside the high level element.
      },
      1: {/* ... */},
      2: {/* ... */}
    ],
  },
  1: {
    "box": {/* ... */},
    "pageNumber": "2",
    "elements": [
      0: {
        "box": {/* ... */},
        "type": "table",
        "properties": [/* ... */],
        "metadata": [/* ... */],
        "content": [/* ... */],
      },
      1: {/* ... */},
    ],
  },
]
```

Each page element contains data relative to the contents of the page in the `elements` section (described in further detail in the Section 1.2), as well as general information pertaining to the properties of that page.
Each element also features a bounding box, which describes its position and size on a given page.

### 1.1. Bounding Boxes

A bounding box is represented by the following object in the output json:

```js
{
  "t": 10,                         // top
  "l": 10,                         // left
  "w": 640,                        // width
  "h": 480,                        // height
}
```

### 1.2. Element types

An element is a dinstinguishable block of content inside a page of a document.
All elements contain a Bounding Box object, which is described in the section 1.1.
The list of metadatas attached to an element are listed under the key 'metadata'.
We categorise each content element as one of the following:

#### 1.2.1. Text type

The text element type is of multiple levels of subtypes:

- **Paragraph**: The paragraph type contains a list of Lines as elements under the key 'content'.
  ```js
  {
    "id": 1024,
    "box": {/* ... */},
    "type": "paragraph",
    "content": [/* ... */],        // strictly Line type elements
    "properties": [/* ... */],
    "metadata": [/* ... */],
  }
  ```
- **Line**: The line type contains a list of words as elements under the key 'content'.
  ```js
  {
    "id": 1025,
    "box": {/* ... */},
    "type": "line",
    "content": [/* ... */],        // strictly Word type elements
    "properties": [/* ... */],
    "metadata": [/* ... */],
  }
  ```
- **Word**: The word type contains either a list of character type objects or a string under the key 'content'.
  ```js
  {
    "id": 1028,
    "box": {/* ... */},
    "type": "word",
    "font": 4,
    "content": [/* ... */],        // strictly Character or string type elements
    "properties": [/* ... */],
    "metadata": [/* ... */],
  }
  ```
- **Character**: The character type contains a single character as the content.
  ```js
  {
    "id": 1029,
    "box": {/* ... */},
    "type": "character",
    "content": "p",                // strictly single character string element
    "properties": [/* ... */],
    "metadata": [/* ... */],
  }
  ```
- **Heading**: The heading type is like a paragraph type but with a heading level.
  ```js
  {
    "id": 1024,
    "box": {/* ... */},
    "type": "heading",
    "content": [/* ... */],        // strictly Line type elements
    "level": 2                     // this is a level 2 heading
    "properties": [/* ... */],
    "metadata": [/* ... */],
  }
  ```

#### 1.2.2. Table type

The following structure defines a table with a single row, single column containing a single cell with a paragraph of text as the cell content.

```js
{
  "id": 4758,
  "type": "table",
  "properties": ,
  "order": 15,
  "metadata": [/* ... */],
  "box": {
    "l": 416,
    "t": 2411,
    "w": 4182,
    "h": 3560,
  }
  "content": [
    "0": {
      "id": 2704,
      "type": "table-row",
      "properties": {/* ... */},
      "metadata": [/* ... */],
      "box": {/* ... */},
      "content": [
        "0": {
          "id": 2604,
          "type": "table-cell",
          "properties": {/* ... */},
          "metadata": [/* ... */],
          "box": {/* ... */},
          "rowspan": 1,
          "colspan": 1,
          "content": [
            "0": {
              "id": 2603,
              "type": "paragraph",
              "properties": {/* ... */},
              "metadata": [/* ... */],
              "box": {/* ... */},
              "content": [/* ... */],
            }
          ]
        }
      ]
    }
  ]
}
```

#### 1.2.3. List type

The content of a list is a set of paragraphs.
A list of both types bulleted and numbered can be represented by this object.
The distinction between the two can be noted by the boolean value 'isOrdered'.

```js
{
  "id": 169,
  "type": "list",
  "properties": {/* ... */},
  "metadata": [/* ... */],
  "box": {/* ... */},
  "isOrdered": false,            // distinguishes bullet points from numbered lists
  "content": [
    "0": {
      "id": 168,
      "type": "paragraph",
      "properties": {/* ... */},
      "metadata": [/* ... */],
      "box": {/* ... */},
      "content": [/* ... */],
    },
   "1": {
      "id": 169,
      "type": "paragraph",
      "properties": {/* ... */},
      "metadata": [/* ... */],
      "box": {/* ... */},
      "content": [/* ... */],
    }
  ]
}
```

#### 1.2.4. Barcode type

A barcode type element represents a barcode element, including the barcode type, as well as the scanned value.

```js
{
  "id": 166,
  "type": "barcode",
  "properties": {/* ... */},
  "metadata": [/* ... */],
  "box": {/* ... */},
  "codeType": "CODE128",
  "codeValue": "0000703082\n"
}
```

#### 1.2.5. Image type

An image is a component representing an image found on the source document, which can (or cannot, depending on its extractability) contain a location on where an extracted version can be found.
An image also contains location and embedded size information.

```js
{
  "id": 146,
  "type": "image",
  "properties": {/* ... */},
  "metadata": [/* ... */],
  "box": {/* ... */},
  "src": "/tmp/imageFile.jpg"   // location of the image
}
```

#### 1.2.6. Drawing type

A drawing is an SVG element, which for now, can be of subtype 'svg-line'.
An SVG-line represents a line in 2D space with a thickness.

```js
{
  "id": 166,
  "type": "drawing",
  "properties": {/* ... */},
  "metadata": [/* ... */],
  "box": {/* ... */},
  "content": [
    0: {
    "id": 167,
    "type": "svg-line",
    "properties": {/* ... */},
    "metadata": [/* ... */],
    "box": {/* ... */},
    "fromX": "12",
    "fromY": "12",
    "toX": "1558",
    "toY": "1570",
    "thickness": "7"
    }
  ]
}
```

### 1.3. Properties of an Element

The properties of an element describe boolean states related to an element. Following provides an example of all the possible values of an element:

```js
"properties": {
  "order": 7,
  "isRedundant": true,
  "isHeader": true,
  "isFooter": true,
  "isPageNumber": true,
  "bulletList": true,
  "titleScores": {
    "size": 1.16,
    "weight": 0,
    "color": 0,
    "name": 0,
    "italic": 0,
    "underline": 0,
  },
}
```

## 2. `fonts` component

`fonts` contains an array representing each font formatting in the document. Each formatting style is represented uniquely; for example: Arial 10pt and Arial 10pt Bold will be represented as two seperate elements.

```js
"fonts" : [
  0: {
    "id": 1,
    "name": "Arial",
    "size": 10,
    "weight": "medium",
    "isItalic": false,
    "isUnderline": false,
    "color": "000000",
  },
  1: {
    "id": 2,
    "name": "Arial",
    "size": 10,
    "weight": "bold",
    "isItalic": false,
    "isUnderline": false,
    "color": "000000",
  }
]
```

## 3. `metadata` component

`metadata` elements represent an outer layer of supplementary information lying on top of the content layer of the document.
Following are the two types of metadatas:

### 3.1. Key-Value pair metadata

A key-value pair is a group of data labelled as a key-value pair, more precisely divided into two categories: key and value.
The metadata that define elements as key-value pairs group elements defined over two fields.
The key-value pair metadata is generated according to the key-value configuration passed to the pipeline.

```js
{
  "id": 4,
  "type": "key-value",
  "keyName": "Policy Number",
  "elements": {
    "0": 286,
    "1": 289,
  },
  "data": {
    "keyElements": {
      "0": 286,
    },
    "valueElements": {
      "0": 289,
    }
  }
}
```

### 3.2. Regex metadata

A regex metadata represents a regex match, and provides information on the pattern used for the matching, the name of the match, the value found, and the elements on which it was found.

```js
{
  "id": 89,
  "type": "regex",
  "elements": [
    842
  ],
  "data": {
    "name": "Age",
    "regex": "(\\d+)[ -]*(ans|jarige)",
    "fullMatch": "24 ans",
    "groups": [
      "24",
      "ans"
    ]
  }
}
```

`fullMatch` shows the match instance to which the entire query was matched, while `groups` lists instances of individual matches.

---

### Simple Json Output (`docs/simple-json-output.md`)

# Simple JSON Output

This page describes the components of the simple JSON output file in detail.
Block examples are obtained using the [foo.pdf](../samples/foo.pdf) sample file:


- [JSON Output](#simple-json-output)
  - [0. Introduction](#0-introduction)
  - [1. Element types](#1-element-types)
    - [1.1. Paragraphs](#11-paragraphs)
    - [1.2. Headings](#12-headings)
    - [1.3. Tables](#13-tables)
    - [1.4. Lists](#14-lists)
    - [1.5. Tables of Content](#15-table-of-contents)

## 0. Introduction

The output for simple JSON file is composed of the following overall structure:

```json
[
  {
    "type": "heading" | "paragraph" | "list" | "table" | "tableOfContent",
    "level": 1,
    "content": "..."
  },
  ...
]
```


This file represents the generated output from each of the extraction, cleaning and enrichment modules.

### 1. Element types

Each element in the array can be a *Paragraph, Heading, List, Table or Table of Contents*.

#### 1.1. Paragraphs

The paragraph type contains the text contents of that paragraph under the key 'content'.
  ```js
  {
    "type": "paragraph",
    "content": "Figure 2-1 extends the analysis from eliminating stops for the five example cycles and examines the additional benefit from avoiding slow-and-go driving below various speed thresholds."
  }
  ```
#### 1.2. Headings

The heading type contains the text contents of that heading under the key 'content', and also the Heading level under the key 'level'.
  ```js
  {
    "type": "heading",
    "level": 2,
    "content": "2 Quantifying Fuel-Saving Opportunities from Specific Driving Behavior Changes"
  }
  ```
  *This means that the element is a Level 2 Heading with the text specified in 'content' key.*  


#### 1.3. Tables

The following structure defines a table with three rows, seven columns and multiple cell spans (indicated with the '**^**' and '**<**' characters).

Each element inside the 'content' array is a TableRow, and each element inside the TableRow is a TableCell.

```json
{
    "type": "table",
    "content": [
      [
        "**Cycle Name**",
        "**KI (1/km)**",
        "**Distance (mi)**",
        "**Percent Fuel Savings**",
        "<",
        "<",
        "<"
      ],
      [
        "^",
        "^",
        "^",
        "**Improved Speed**",
        "**Decreased Accel**",
        "**Eliminate Stops**",
        "**Decreased Idle**"
      ],
      [
        "4171\\_1",
        "0.07",
        "173.9",
        "58.1%",
        "1.6%",
        "2.1%",
        "0.5%",
      ]
    ]
  }
```

#### 1.4. Lists

For lists, the content key is set with the string contents of every ListItem on the List, like the following:

```json
  {
    "type": "list",
    "content": "1. Calculate the trip distance of each sample trip.\n2. Eliminate stop-and-go and idling within each trip.\n3. Set the acceleration rate to 3 mph/s.\n4. Set the cruising speed to 40 mph.\n5. Continue cruising at 40 mph until the trip distance is reached."
  },
```

#### 1.5. Table of Contents

Table of Contents 'content' key is an array containing the texts of every item, on the ToC:

```json
  {
    "type": "tableOfContent",
    "content": [
      "Introduction - 3",
      "Get Sarted - 5",
      "First Use - 7",
      "Settings - 25",
    ]
  },
```

---

### Usage (`docs/usage.md`)

# Parsr Usage Guide

- [Parsr Usage Guide](#parsr-usage-guide)
  - [1. Install npm packages](#1-install-npm-packages)
  - [2. Run](#2-run)
    - [2.1. Configuration](#21-configuration)
    - [2.2. Demo: Web Viewer](#22-demo-web-viewer)
      - [2.2.1. Under Linux/MacOS](#221-under-linuxmacos)
      - [2.2.2. Under Windows](#222-under-windows)
      - [2.2.3. GUI Usage](#223-gui-usage)
    - [2.3. Command Line Usage](#23-command-line-usage)
      - [2.3.1. Available Parameters](#231-available-parameters)
      - [2.3.2. Usage examples](#232-usage-examples)
  - [3. API](#3-api)
  - [4. Test](#4-test)

You can use Parsr in different ways:

- Using the command line
- Using the API
- Using the demo web viewer

## 1. Install npm packages

Inside the Parsr folder (where it has been installed), launch:

```sh
npm install
```

## 2. Run

### 2.1. Configuration

The tool contains a pipeline of modules that process the document step by step and is highly configurable. To change it's default configuration, please refer to the [configuration file documentation](configuration.md).

### 2.2. Demo: Web Viewer

To start the web viewer demo, simply run:

#### 2.2.1. Under Linux/MacOS:

```sh
npm run start:web:vue
```

#### 2.2.2. Under Windows:

In two different terminals, first:

```sh
npm run start:api
```

then in the other one:

```sh
cd demo/vue-viewer && npm install && npm run serve
```

Open [localhost:8080](http://localhost:8080) with your favorite browser to use the GUI.

#### 2.2.3. GUI Usage

For an explanation on how to use the web viewer demo, refer to the [GUI Usage Guide](gui-guide.md).

### 2.3. Command Line Usage

#### 2.3.1. Available Parameters

````
-f, --input-file <filename>       // Input file to be processed.
-o, --output-folder <foldername>  // Location of the folder where the output will be stored.
-n, --document-name <name>        // Name of the document.
-c, --config <filename>           // The file's path from which the application's parameters will be loaded.
-l, --log-level <verbosity>       // Verbosity level: debug, info (default), warn, error.
-p, --pretty-logs                 // Make logs look pretty but unreadable for a machine.
````

#### 2.3.2. Usage examples

Under Mac OS X, Linux:

```sh
npm run run:debug -- --input-file samples/t1.pdf --output-folder dist/ --document-name example --config server/defaultConfig.json --pretty-logs
```

Under Windows:

```sh
cmd /C "npm run run:debug -- --input-file samples/t1.pdf --output-folder samples --document-name example --config server/defaultConfig.json --pretty-logs"
```

## 3. API

Install the API server with:

```sh
npm run install:api
```

And then start the API server with:

```sh
npm run start:api
```

You can then call endpoints on [localhost:3001](http://localhost:3001).

The documentation for the API can be found [here](api-guide.md).

## 4. Test

```sh
npm run test
```

---

--- METRICS ---
- Files Extracted: 62
- Estimated Token Budget: ~28531 tokens
- Canonical Reference: https://codewiki.google/github.com/axa-group/Parsr
