{"id":26423706,"url":"https://github.com/shapr/fermatslastmargin","last_synced_at":"2025-08-25T05:15:18.335Z","repository":{"id":36020198,"uuid":"188598182","full_name":"shapr/fermatslastmargin","owner":"shapr","description":"tool for creating and sharing annotations, using github for storage and social network","archived":false,"fork":false,"pushed_at":"2022-01-09T18:47:47.000Z","size":1391,"stargazers_count":90,"open_issues_count":26,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-08-17T03:56:41.525Z","etag":null,"topics":["annotations","doi","research-paper"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shapr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-25T18:09:08.000Z","updated_at":"2025-04-04T12:25:13.000Z","dependencies_parsed_at":"2022-07-29T20:39:46.069Z","dependency_job_id":null,"html_url":"https://github.com/shapr/fermatslastmargin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/shapr/fermatslastmargin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shapr%2Ffermatslastmargin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shapr%2Ffermatslastmargin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shapr%2Ffermatslastmargin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shapr%2Ffermatslastmargin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shapr","download_url":"https://codeload.github.com/shapr/fermatslastmargin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shapr%2Ffermatslastmargin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272008779,"owners_count":24857658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotations","doi","research-paper"],"created_at":"2025-03-18T02:54:15.358Z","updated_at":"2025-08-25T05:15:18.318Z","avatar_url":"https://github.com/shapr.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fermat's Last Margin\nA tool for annotating research papers (and more) and sharing those annotations (via git for starters)\n\n[Fermat's Last Theorem](https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem) was captioned \"I have a truly marvelous demonstration of this proposition which this margin is too narrow to contain.\"\n\nThis tool intends to be an infinite margin.\n\n# WHY WOULD I USE THIS?\n\nDo you read many research papers or PhD theses? If yes, you might want to use this tool!\n\nI like to write in the margins of my books and printed research papers.\nI want to read what other people have to say about a paper after I write down my own notes.\nI want to be able to search my notes. I want to be able to share my notes!\nI want to be able to remember why I downloaded a paper years later.\n\n## Why are notes separate from the paper itself?\n\nDistributing 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.\n\n## Getting Started\n* install [poppler-utils](https://poppler.freedesktop.org/), or more specifically, make sure the pdftocairo binary from poppler-utils is in your `$PATH`\n* git clone this repository\n* run this from cabal `cabal run` (optionally: `nix-shell --run \"cabal run\"`)\n* point your web browser to `localhost:3000`\nAll of the annotations are saved in a local directory `~/.fermatslastmargin/localuser` and your friend's annotations are saved in `~/.fermatslastmargin/friends/\u003cgithub_name_of_friend\u003e`\n\n# Features\n- [X] add paper info\n- [X] read/write annotations\n- [X] load page images\n- [X] render 'uploaded' PDF to page images\n- [X] push to github repo\n- [X] pull from friends' github repo\n- [X] switch notes view to see github friends' notes\n- [X] setup new user (ask for github OAuth and username, set git remote correctly)\n- [X] search crossref.org by title to get DOI\n- [X] update PDF when viewing paper\n- [ ] plugin system to download paper (as PDF) when given unique ID (DOI for now)\n- [ ] search arxiv by title to get DOI\n- [ ] swap to github v4 graphql API so pulling friend repos doesn't get rate limited\n\n# Dependencies\n- git\n- poppler-utils (apt install poppler-utils)\n- zlib (apt install zlib1g-dev)\n## Dependencies when building from source\n- cabal 2.4 - if you get \"cabal: fermatslastmargin.cabal:14: Parse of field 'build-depends' failed.\" you need to upgrade with \"cabal install Cabal\"\n- GHC 8.6 (at least, that's all I've tried)\n\n## Mac\n- brew install poppler\n- brew install zlib\n\n# Project Implementation\n\n[Scotty](http://hackage.haskell.org/package/scotty) is used to handle a bunch of HTTP endpoints.\n\nAll state is saved in `~/.fermatslastmargin/`. For the user viewing the papers, their state will be in `~/.fermatslastmargin/localuser`.\n\nThe notes for each paper will be in `~/.fermatslastmargin/localuser/$DOI/paper.json`.\nFor example, Conor McBride's paper \"Everybody's Got to be Somewhere\" has a DOI of `10.4204/EPTCS.275.6`.\nOnce that paper is added, the notes will be saved into `~/.fermatslastmargin/localuser/10.4204/EPTCS.275.6/paper.json`\n\nNotes written by users followed by this user will be in `~/.fermatslastmargin/friends/\u003cgithub_name_of_friend\u003e`\n\nWhen a PDF is uploaded to create a new paper, the PDF is saved into `~/.fermatslastmargin/pageimages/$DOI/paper.pdf`.\nNext, page images are generated by poppler-utils into `~/.fermatslastmargin/pageimages/$DOI/page-1.png` up to however many pages in the PDF.\n\n# Front End code\n\nThe front end uses jquery in a thoroughly haphazard manner.\n\nThe state is mostly passed around as GET parameters for DOI, page number, and friend name.\nFor example, `http://localhost:3000/index.html?pagenum=1\u0026uid=10.2168/LMCS-10(3:19)2014\u0026friendview=chazzam`\n\nThe front end javascript calls HTTP endpoints defined in Main.hs.\n- page images are fetched from the filesystem via a static endpoint\n- local and friend notes are fetched by GET'ing from `/getannotate`\n- a new or updated note is saved by posting to `/annotate`\n- friends are found by GET'ing the DOI from `/friends?paperuid=DOI`\n- pushing local notes to github GETs `/gitpush`\n- pulling remote notes from github GETs `/gitpull`\n- creating a new paper POSTs to `/paper`\n- creating a new user will hit `/newuser`\n\n# Migrate!\n\nIf 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!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshapr%2Ffermatslastmargin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshapr%2Ffermatslastmargin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshapr%2Ffermatslastmargin/lists"}