Automatically annotates research PDFs with citations and abbreviation expansions.
Project description
glosser
Automatically annotate research PDFs with citation titles and abbreviation expansions, right in the margins.
🤔 What is Glosser?
Ever read a dense research paper and had to constantly flip to the references section just to see what [17] is? Or wondered what LSTM stands for on page 8?
Glosser solves this. It reads your PDF, identifies every citation marker (like [1], [2], …) and every uppercase abbreviation, then writes their full titles and expansions directly into the page margins, producing a new, self-contained PDF you can read without jumping around.
Before → After
| Without Glosser | With Glosser |
|---|---|
...as shown in [14]... |
...as shown in [14]... ← margin: "Attention Is All You Need (2017)" |
...using the BERT model... |
...using the BERT model... ← margin: "Bidirectional Encoder Representations from Transformers" |
✨ Features
- 📄 Citation Annotations: Extracts titles and years from the references section using LLM and writes them next to each
[n]marker in the margins. - 🔤 Abbreviation Expansion: Finds uppercase abbreviations (3–5 chars), looks up their full forms via RAG + LLM, and annotates them in the margins.
- 🎨 Color-Coded: Green for context-extracted definitions, red for LLM-inferred ones, so you know the confidence level at a glance.
- 🔑 API Key Saved Locally: Enter your Groq API key once; it's stored at
~/.glosser_configfor future runs.
🚀 Installation
pip install -q glosser
Note: The
-qflag keeps the install output clean. Glosser has ML dependencies (PyTorch, Transformers, FAISS) so the first install may take a few minutes.
Requirements
- Python ≥ 3.9
- A free Groq API key
📖 Usage
CLI (recommended)
Simply run:
glosser
As a Python Library
import asyncio
from glosser.main import annotate
async def main():
out_path, count = await annotate(
path="paper.pdf",
GROQ_API_KEY="gsk_...",
scaling=1.2, # margin width multiplier (default: 1.2)
find_references=True, # annotate [n] citations
find_abbreviation=True, # annotate abbreviations
)
print(f"Saved {count} annotations to {out_path}")
asyncio.run(main())
⚙️ How It Works
PDF Input
│
├─ 1. Scale pages horizontally to create side margins
│
├─ 2. Extract references section → LLM extracts title + year for each [n]
│
├─ 3. Find all [n] markers in body text → write citation info in nearest margin
│
├─ 4. Find all uppercase abbreviations (≥2 occurrences)
│
├─ 5. RAG pipeline: chunk PDF → embed with MiniLM → FAISS similarity search
│ └─ LLM resolves full form from retrieved context
│
└─ 6. Write abbreviation expansions in margins → save new PDF
Tech stack: PyMuPDF · LangChain · Groq (Kimi K2) · HuggingFace Embeddings (MiniLM-L6-v2) · FAISS
🛠️ Configuration
| Option | Default | Description |
|---|---|---|
scaling |
1.2 |
How much to widen pages for margins (1.0 = no extra margin) |
find_references |
True |
Annotate [n] citation markers |
find_abbreviation |
True |
Annotate uppercase abbreviations |
Your Groq API key is stored locally at ~/.glosser_config after the first run.
To reset it, simply delete that file.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file glosser-0.0.1.tar.gz.
File metadata
- Download URL: glosser-0.0.1.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b6ad0d2f524285ff9a0602dddc01833ff9852d64b5f6486d2cde3d102dc191a
|
|
| MD5 |
ee46e920f18356070fda5c1f702354ae
|
|
| BLAKE2b-256 |
9c64b84efb01443fcc26e3efa0ed66bf04ed5dadf0c80aa95988ec20697af7ae
|
File details
Details for the file glosser-0.0.1-py3-none-any.whl.
File metadata
- Download URL: glosser-0.0.1-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de0e95e26a5c16ad1fa26686d6d9e1cf8099999b631ad5391bdc34d63bcee670
|
|
| MD5 |
65d74e0ee307c9b532c3319ff25a9491
|
|
| BLAKE2b-256 |
64eb66b9f140c220111ed9c8a0f9330ab62cf122d950e505d79b9c89199aa225
|