.github/workflows | ||
nix | ||
src | ||
static | ||
.gitignore | ||
CHANGELOG.md | ||
CONTRIBUTORS.md | ||
default.nix | ||
fermatslastmargin.cabal | ||
haskell.yml | ||
LICENSE | ||
Main.hs | ||
Migrate.hs | ||
README.md | ||
Setup.hs | ||
shell.nix |
Fermat's Last Margin
A tool for annotating research papers (and more) and sharing those annotations (via git for starters)
Fermat's Last Theorem was captioned "I have a truly marvelous demonstration of this proposition which this margin is too narrow to contain."
This tool intends to be an infinite margin.
WHY WOULD I USE THIS?
Do you read many research papers or PhD theses? If yes, you might want to use this tool!
I like to write in the margins of my books and printed research papers. I want to read what other people have to say about a paper after I write down my own notes. I want to be able to search my notes. I want to be able to share my notes! I want to be able to remember why I downloaded a paper years later.
Why are notes separate from the paper itself?
Distributing PDFs will get you sued for lots of money ( https://en.wikipedia.org/wiki/Sci-Hub#United_States ). I don't want to get sued.
Getting Started
- install poppler-utils, or more specifically, make sure the pdftocairo binary from poppler-utils is in your
$PATH
- git clone this repository
- run this from cabal
cabal run
(optionally:nix-shell --run "cabal run"
) - point your web browser to
localhost:3000
All of the annotations are saved in a local directory~/.fermatslastmargin/localuser
and your friend's annotations are saved in~/.fermatslastmargin/friends/<github_name_of_friend>
Features
- add paper info
- read/write annotations
- load page images
- render 'uploaded' PDF to page images
- push to github repo
- pull from friends' github repo
- switch notes view to see github friends' notes
- setup new user (ask for github OAuth and username, set git remote correctly)
- search crossref.org by title to get DOI
- update PDF when viewing paper
- plugin system to download paper (as PDF) when given unique ID (DOI for now)
- search arxiv by title to get DOI
- swap to github v4 graphql API so pulling friend repos doesn't get rate limited
Dependencies
- git
- poppler-utils (apt install poppler-utils)
- zlib (apt install zlib1g-dev)
Dependencies when building from source
- cabal 2.4 - if you get "cabal: fermatslastmargin.cabal:14: Parse of field 'build-depends' failed." you need to upgrade with "cabal install Cabal"
- GHC 8.6 (at least, that's all I've tried)
Mac
- brew install poppler
- brew install zlib
Project Implementation
Scotty is used to handle a bunch of HTTP endpoints.
All state is saved in ~/.fermatslastmargin/
. For the user viewing the papers, their state will be in ~/.fermatslastmargin/localuser
.
The notes for each paper will be in ~/.fermatslastmargin/localuser/$DOI/paper.json
.
For example, Conor McBride's paper "Everybody's Got to be Somewhere" has a DOI of 10.4204/EPTCS.275.6
.
Once that paper is added, the notes will be saved into ~/.fermatslastmargin/localuser/10.4204/EPTCS.275.6/paper.json
Notes written by users followed by this user will be in ~/.fermatslastmargin/friends/<github_name_of_friend>
When a PDF is uploaded to create a new paper, the PDF is saved into ~/.fermatslastmargin/pageimages/$DOI/paper.pdf
.
Next, page images are generated by poppler-utils into ~/.fermatslastmargin/pageimages/$DOI/page-1.png
up to however many pages in the PDF.
Front End code
The front end uses jquery in a thoroughly haphazard manner.
The state is mostly passed around as GET parameters for DOI, page number, and friend name.
For example, http://localhost:3000/index.html?pagenum=1&uid=10.2168/LMCS-10(3:19)2014&friendview=chazzam
The front end javascript calls HTTP endpoints defined in Main.hs.
- page images are fetched from the filesystem via a static endpoint
- local and friend notes are fetched by GET'ing from
/getannotate
- a new or updated note is saved by posting to
/annotate
- friends are found by GET'ing the DOI from
/friends?paperuid=DOI
- pushing local notes to github GETs
/gitpush
- pulling remote notes from github GETs
/gitpull
- creating a new paper POSTs to
/paper
- creating a new user will hit
/newuser
Migrate!
If you created a local repository and annotated papers before January 2020, you'll need to do cabal run migrate
to get your repository in the new format!