fmjl 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fmjl-0.5.0/LICENSE +21 -0
- fmjl-0.5.0/PKG-INFO +40 -0
- fmjl-0.5.0/README.md +211 -0
- fmjl-0.5.0/fmjl.egg-info/PKG-INFO +40 -0
- fmjl-0.5.0/fmjl.egg-info/SOURCES.txt +12 -0
- fmjl-0.5.0/fmjl.egg-info/dependency_links.txt +1 -0
- fmjl-0.5.0/fmjl.egg-info/entry_points.txt +2 -0
- fmjl-0.5.0/fmjl.egg-info/requires.txt +4 -0
- fmjl-0.5.0/fmjl.egg-info/top_level.txt +3 -0
- fmjl-0.5.0/fmjl.py +1863 -0
- fmjl-0.5.0/fmjl_docx.py +715 -0
- fmjl-0.5.0/fmjl_pdf.py +592 -0
- fmjl-0.5.0/pyproject.toml +52 -0
- fmjl-0.5.0/setup.cfg +4 -0
fmjl-0.5.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rupak Kumar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
fmjl-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fmjl
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: FMJL (.fmjl): one document, two forms. JSON Lines container, Markdown text, LaTeX formulas, HTML merged-cell tables, built for RAG. Converter, checker, PDF and Word importers, retriever chunks.
|
|
5
|
+
Author: Rupak Kumar
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rupakkumar-76319/fmjl
|
|
8
|
+
Project-URL: Rulebook, https://github.com/rupakkumar-76319/fmjl/blob/main/rulebook/fmjl_rulebook_v0.5.md
|
|
9
|
+
Project-URL: Issues, https://github.com/rupakkumar-76319/fmjl/issues
|
|
10
|
+
Keywords: fmjl,jsonl,markdown,rag,document,pdf,docx,retrieval
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: jsonschema>=4
|
|
21
|
+
Provides-Extra: pdf
|
|
22
|
+
Requires-Dist: pymupdf>=1.24; extra == "pdf"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# FMJL
|
|
26
|
+
|
|
27
|
+
FMJL, short for Format, Markdown, JSON Lines, stores a document as one JSON object per line: one element (heading, paragraph, table, formula, image, caption...) with a stable id, a content hash, its page and position, and who may read it. People write and edit the same document as normal Markdown; the tool converts both ways without renumbering anything.
|
|
28
|
+
|
|
29
|
+
pip install fmjl # converter, checker, Word importer, chunks
|
|
30
|
+
pip install fmjl[pdf] # adds the PDF importer (PyMuPDF)
|
|
31
|
+
|
|
32
|
+
fmjl notes.md # Markdown -> notes.fmjl, then checks it
|
|
33
|
+
fmjl notes.fmjl # .fmjl -> notes.md, ids kept
|
|
34
|
+
fmjl report.pdf # PDF -> report.fmjl, report.md, images/
|
|
35
|
+
fmjl report.docx # Word -> the same
|
|
36
|
+
fmjl chunks report.fmjl # retriever-ready chunks as JSON Lines
|
|
37
|
+
|
|
38
|
+
From Python: `import fmjl`; `fmjl.load`, `fmjl.chunks`, `fmjl.changed_chunks`, `fmjl.check`.
|
|
39
|
+
|
|
40
|
+
Rulebook, examples, benchmark and the VS Code extension: https://github.com/rupakkumar-76319/fmjl
|
fmjl-0.5.0/README.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
fmjl: "0.5"
|
|
3
|
+
doc: readme
|
|
4
|
+
lang: en
|
|
5
|
+
access: ["all"]
|
|
6
|
+
source: README.md
|
|
7
|
+
sha256: 0afdb86ddae8de9cd5d5b8c778609ee6d35a3553b9fc143c1890856764b01045
|
|
8
|
+
protection: none
|
|
9
|
+
signed: false
|
|
10
|
+
converter: fmjl 0.5
|
|
11
|
+
created: 2026-09-28T20:11:27Z
|
|
12
|
+
last_id: 25
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<!-- e1 -->
|
|
16
|
+
# FMJL
|
|
17
|
+
|
|
18
|
+
<!-- e2 -->
|
|
19
|
+
FMJL, short for Format, Markdown, JSON Lines, is a document format that combines four
|
|
20
|
+
languages, each doing the one job it is best at:
|
|
21
|
+
|
|
22
|
+
<!-- e3 -->
|
|
23
|
+
| Language | Job in FMJL | Why that one |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| JSON Lines | The container: one element per line, with its id, hash, page, position and permissions | Every programming language reads JSON; one line per element means a file can be streamed, searched and cut without a parser |
|
|
26
|
+
| Markdown | All readable text: headings, paragraphs, lists, simple tables, image descriptions | People can read and write it directly; it is the language of GitHub, VS Code and every editor |
|
|
27
|
+
| LaTeX | Math formulas | The only language that writes every formula exactly |
|
|
28
|
+
| HTML | Tables with merged cells or multi-level headers | Markdown tables cannot merge cells; HTML can |
|
|
29
|
+
|
|
30
|
+
<!-- e4 -->
|
|
31
|
+
No single format does this on its own. Markdown cannot carry an image's page and position,
|
|
32
|
+
cannot tie a caption to its image, and cannot say who may read a paragraph. JSON can hold
|
|
33
|
+
those facts but nobody wants to write or read a document as JSON. LaTeX writes formulas
|
|
34
|
+
perfectly but is slow to parse and hard for most people to write. HTML has the tables but
|
|
35
|
+
is heavy everywhere else. FMJL takes the strength of each and leaves the rest out.
|
|
36
|
+
|
|
37
|
+
<!-- e5 -->
|
|
38
|
+
A document becomes a list of small parts called elements: headings, paragraphs, lists,
|
|
39
|
+
tables, formulas, code, images, captions, footnotes, form fields, stamps, watermarks and
|
|
40
|
+
more. Every element has a stable id, a content hash, a page and position, and a permission
|
|
41
|
+
list. That is what RAG systems and search engines need, and it is why FMJL reads a document
|
|
42
|
+
in about a tenth of a millisecond (see `benchmark/`).
|
|
43
|
+
|
|
44
|
+
<!-- e6 -->
|
|
45
|
+
One document has two forms that hold the same information:
|
|
46
|
+
|
|
47
|
+
<!-- e7 -->
|
|
48
|
+
| Form | File | Made for |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| Storage | `name.fmjl` | Machines: search, RAG, databases |
|
|
51
|
+
| Authoring | `name.md` | People: reading, writing, reviewing |
|
|
52
|
+
|
|
53
|
+
<!-- e8 -->
|
|
54
|
+
## Folder layout
|
|
55
|
+
|
|
56
|
+
<!-- e9 -->
|
|
57
|
+
```text
|
|
58
|
+
fmjl.py the reference tool (needs Python 3.9+ and: pip install jsonschema)
|
|
59
|
+
fmjl_pdf.py the PDF importer (needs: pip install pymupdf)
|
|
60
|
+
fmjl_docx.py the Word importer (needs nothing else)
|
|
61
|
+
rulebook/ the specification, version 0.5, in both forms
|
|
62
|
+
examples/ sample documents (Markdown, PDF, Word) with their images/, and rag_demo.py
|
|
63
|
+
fmjl-vscode/ the VS Code extension: convert, syntax coloring and live checking
|
|
64
|
+
benchmark/ the same document in FMJL, Markdown, JSON and LaTeX, and the scores
|
|
65
|
+
archive/ older versions (0.1, 0.2), the evaluation, and the first converter
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
<!-- e10 -->
|
|
69
|
+
## Everyday use
|
|
70
|
+
|
|
71
|
+
<!-- e11 -->
|
|
72
|
+
Write a normal Markdown file, then turn it into the storage form. The command is
|
|
73
|
+
`fmjl <input> <output>`; the file extensions tell the tool which way to convert:
|
|
74
|
+
|
|
75
|
+
<!-- e12 -->
|
|
76
|
+
```powershell
|
|
77
|
+
fmjl notes.md store\notes.fmjl # Markdown to storage form, then checks it
|
|
78
|
+
fmjl store\notes.fmjl notes.md # storage form back to Markdown; ids are kept
|
|
79
|
+
fmjl notes.md # output left out: notes.fmjl next to the input
|
|
80
|
+
fmjl notes.fmjl # same shortcut the other way
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
<!-- e13 -->
|
|
84
|
+
`fmjl` is the small `fmjl.cmd` file in this folder. Add the folder to your PATH once and
|
|
85
|
+
the word works from anywhere. Without it, write `python fmjl.py new notes.md`.
|
|
86
|
+
|
|
87
|
+
## From a PDF or a Word file
|
|
88
|
+
|
|
89
|
+
```powershell
|
|
90
|
+
fmjl report.pdf # writes report.fmjl, report.md and images/, then checks
|
|
91
|
+
fmjl report.docx # the same from Word
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The importer reads the text layer of the PDF and turns it into elements: headings by
|
|
95
|
+
font size, paragraphs, lists, tables (with or without ruling lines), images with their
|
|
96
|
+
captions linked by `reference`, and repeated headers, footers and page numbers marked as
|
|
97
|
+
`noise`. Every element carries `page` (counted from 0) and `bbox` (0 to 1000), so a RAG
|
|
98
|
+
system can cite the exact place on the page. A paragraph that runs over a page break is
|
|
99
|
+
linked to its first half with `continues`. Open the `.md` afterwards, fix what the
|
|
100
|
+
importer got wrong, and run `fmjl report.md`; the ids stay.
|
|
101
|
+
|
|
102
|
+
Pages without a text layer (scans) need OCR. Install Tesseract and the importer uses it;
|
|
103
|
+
without it, the page is reported and skipped. `examples/solar_report.pdf` is a sample
|
|
104
|
+
with its imported `.fmjl` and `.md`.
|
|
105
|
+
|
|
106
|
+
A Word file already knows its structure, so the Word importer reads it directly: headings
|
|
107
|
+
from the Heading styles, bullet and numbered lists, tables with merged cells, images with
|
|
108
|
+
captions, footnotes, Word formulas as LaTeX, the header and footer as `noise`, and page
|
|
109
|
+
numbers from the page breaks Word recorded. `examples/maintenance_guide.docx` is a sample.
|
|
110
|
+
|
|
111
|
+
Merged cells never need HTML by hand. In a Markdown table a cell holding only `^` joins
|
|
112
|
+
the cell above it and a cell holding only `<` joins the cell to its left; the tool writes
|
|
113
|
+
the HTML with `rowspan` and `colspan` for you, and shows the same shortcut when you
|
|
114
|
+
convert back:
|
|
115
|
+
|
|
116
|
+
```markdown
|
|
117
|
+
| Name | Score | < |
|
|
118
|
+
| --- | --- | --- |
|
|
119
|
+
| ^ | Math | AI |
|
|
120
|
+
| Rupak Kumar | 9 | 10 |
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
<!-- e14 -->
|
|
124
|
+
All commands:
|
|
125
|
+
|
|
126
|
+
<!-- e15 -->
|
|
127
|
+
| Command | What it does |
|
|
128
|
+
| --- | --- |
|
|
129
|
+
| `python fmjl.py new notes.md` | Authoring form to storage form |
|
|
130
|
+
| `python fmjl.py md notes.fmjl` | Storage form to authoring form |
|
|
131
|
+
| `python fmjl.py fill notes.fmjl` | Fills in `id`, `hash`, `characters` and `parent`; makes `md` canonical |
|
|
132
|
+
| `python fmjl.py check notes.fmjl` | Checks every rule of the rulebook |
|
|
133
|
+
| `python fmjl.py view notes.fmjl` | Prints the document as clean Markdown |
|
|
134
|
+
| `python fmjl.py info notes.fmjl` | Prints the title, element counts and an outline |
|
|
135
|
+
| `python fmjl.py upgrade old.fmjl` | Turns a version 0.1 to 0.4 file into 0.5 |
|
|
136
|
+
| `python fmjl.py pdf report.pdf` | PDF to storage form, authoring form and `images/` |
|
|
137
|
+
| `python fmjl.py docx report.docx` | Word to storage form, authoring form and `images/` |
|
|
138
|
+
| `python fmjl.py chunks report.fmjl` | Retriever-ready chunks as JSON Lines |
|
|
139
|
+
|
|
140
|
+
<!-- e16 -->
|
|
141
|
+
## In a RAG pipeline
|
|
142
|
+
|
|
143
|
+
```powershell
|
|
144
|
+
fmjl chunks report.fmjl # one chunk per element, as JSON Lines
|
|
145
|
+
fmjl chunks report.fmjl --by section # one chunk per heading and what is under it
|
|
146
|
+
fmjl chunks new.fmjl --since old.fmjl # only the chunks that changed: re-embed just those
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Every chunk carries `id`, `text` (the headings above it, then the content), `page`, `bbox`,
|
|
150
|
+
`hash`, `access` and `path`. Noise, tables of contents and redactions are never included.
|
|
151
|
+
The same is available from Python:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
import fmjl
|
|
155
|
+
rows = fmjl.load("report.fmjl")
|
|
156
|
+
for c in fmjl.chunks(rows):
|
|
157
|
+
embed(c["text"], metadata={"id": c["id"], "page": c["page"], "access": c["access"]})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`examples/rag_demo.py` is the whole pipeline in one file with nothing to install: it loads
|
|
161
|
+
every `.fmjl` in a folder, scores the chunks against a question, prints the best ones with
|
|
162
|
+
their citation (document, page, element id), and, when the `anthropic` package and a key
|
|
163
|
+
are present, asks Claude to answer from those chunks only:
|
|
164
|
+
|
|
165
|
+
```powershell
|
|
166
|
+
python examples\rag_demo.py "How much did electricity bills fall?"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## What the benchmark shows
|
|
170
|
+
|
|
171
|
+
<!-- e17 -->
|
|
172
|
+
The same 75-sentence report with two formulas, a table, an image and a caption was written
|
|
173
|
+
in FMJL, Markdown, JSON and LaTeX, then read back and scored (`benchmark/results.json`):
|
|
174
|
+
|
|
175
|
+
<!-- e18 -->
|
|
176
|
+
| | FMJL | Markdown | JSON | LaTeX |
|
|
177
|
+
| --- | --- | --- | --- | --- |
|
|
178
|
+
| Page number of every element | 23/23 | 0/23 | 23/23 | 0/23 |
|
|
179
|
+
| Caption linked to its image | yes | no | yes | yes |
|
|
180
|
+
| Elements keeping their id after an edit | 23/23 | 0/23 | 21/23 | 5/23 |
|
|
181
|
+
| Detects a silently changed letter | yes | no | no | no |
|
|
182
|
+
| Read one document | 0.11 ms | 3.85 ms | 0.07 ms | 29.32 ms |
|
|
183
|
+
|
|
184
|
+
<!-- e19 -->
|
|
185
|
+
## VS Code
|
|
186
|
+
|
|
187
|
+
<!-- e20 -->
|
|
188
|
+
Search for **FMJL** in the Extensions view and install it (publisher rupakkumar). It needs
|
|
189
|
+
no Python. Right-click a `.md` file for **FMJL: Convert Markdown to .fmjl**, or a `.fmjl`
|
|
190
|
+
file for **FMJL: Convert .fmjl to Markdown**. Any `.fmjl` file gets coloring, red
|
|
191
|
+
underlines for rule violations, and the command **FMJL: Check current file**.
|
|
192
|
+
|
|
193
|
+
<!-- e21 -->
|
|
194
|
+
The extension's converter is a JavaScript port of `fmjl.py`. Running
|
|
195
|
+
`node fmjl-vscode/test/roundtrip.js` proves the two give byte-identical output on every
|
|
196
|
+
document in this repository.
|
|
197
|
+
|
|
198
|
+
<!-- e22 -->
|
|
199
|
+
## Status
|
|
200
|
+
|
|
201
|
+
<!-- e23 -->
|
|
202
|
+
Draft, version 0.5. The rulebook is the authority; if `fmjl.py` and the rulebook
|
|
203
|
+
disagree, the tool has a bug.
|
|
204
|
+
|
|
205
|
+
<!-- e24 -->
|
|
206
|
+
## Author and license
|
|
207
|
+
|
|
208
|
+
<!-- e25 -->
|
|
209
|
+
Created by Rupak Kumar. Released under the MIT License (see `LICENSE`): use it freely,
|
|
210
|
+
keep the copyright line. Suggestions and bug reports go to
|
|
211
|
+
https://github.com/rupakkumar-76319/fmjl/issues.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fmjl
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: FMJL (.fmjl): one document, two forms. JSON Lines container, Markdown text, LaTeX formulas, HTML merged-cell tables, built for RAG. Converter, checker, PDF and Word importers, retriever chunks.
|
|
5
|
+
Author: Rupak Kumar
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rupakkumar-76319/fmjl
|
|
8
|
+
Project-URL: Rulebook, https://github.com/rupakkumar-76319/fmjl/blob/main/rulebook/fmjl_rulebook_v0.5.md
|
|
9
|
+
Project-URL: Issues, https://github.com/rupakkumar-76319/fmjl/issues
|
|
10
|
+
Keywords: fmjl,jsonl,markdown,rag,document,pdf,docx,retrieval
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: jsonschema>=4
|
|
21
|
+
Provides-Extra: pdf
|
|
22
|
+
Requires-Dist: pymupdf>=1.24; extra == "pdf"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# FMJL
|
|
26
|
+
|
|
27
|
+
FMJL, short for Format, Markdown, JSON Lines, stores a document as one JSON object per line: one element (heading, paragraph, table, formula, image, caption...) with a stable id, a content hash, its page and position, and who may read it. People write and edit the same document as normal Markdown; the tool converts both ways without renumbering anything.
|
|
28
|
+
|
|
29
|
+
pip install fmjl # converter, checker, Word importer, chunks
|
|
30
|
+
pip install fmjl[pdf] # adds the PDF importer (PyMuPDF)
|
|
31
|
+
|
|
32
|
+
fmjl notes.md # Markdown -> notes.fmjl, then checks it
|
|
33
|
+
fmjl notes.fmjl # .fmjl -> notes.md, ids kept
|
|
34
|
+
fmjl report.pdf # PDF -> report.fmjl, report.md, images/
|
|
35
|
+
fmjl report.docx # Word -> the same
|
|
36
|
+
fmjl chunks report.fmjl # retriever-ready chunks as JSON Lines
|
|
37
|
+
|
|
38
|
+
From Python: `import fmjl`; `fmjl.load`, `fmjl.chunks`, `fmjl.changed_chunks`, `fmjl.check`.
|
|
39
|
+
|
|
40
|
+
Rulebook, examples, benchmark and the VS Code extension: https://github.com/rupakkumar-76319/fmjl
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
fmjl.py
|
|
4
|
+
fmjl_docx.py
|
|
5
|
+
fmjl_pdf.py
|
|
6
|
+
pyproject.toml
|
|
7
|
+
fmjl.egg-info/PKG-INFO
|
|
8
|
+
fmjl.egg-info/SOURCES.txt
|
|
9
|
+
fmjl.egg-info/dependency_links.txt
|
|
10
|
+
fmjl.egg-info/entry_points.txt
|
|
11
|
+
fmjl.egg-info/requires.txt
|
|
12
|
+
fmjl.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|