Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore Mechanism to extend workout with computed metrics Nov 11, 2018 Simplified code for analysis Nov 3, 2018
Screenshot_2018-10-23_21-43-06.png Screenshot Oct 23, 2018 Small modifications to parse and README Oct 30, 2018
export-html.png screenshots Oct 30, 2018


The idea is to develop a “fitness tracking utility” (i.e. Strava/Runkeeper) based on org format. I started development mainly to learn a bit of Elisp and because I was disappointed by the switch to closed source license of Runalyze. For now it is just a small prototype



The architecture consists of three components:

  • org-mode (actually the org-mode text format) to store data in human readable format. Org-mode format will play the same role of maildir for mu4e and ledger files for ledger.
  • a command line utility (server) to process and index org-mode files. This plays the same role of mmu for mu4e and ledger
  • a user interface (GUI) to present graph and statistics produced via the server

org-fit format

For now I’m only working on gym notes: i.e. notes taken while training in the gym. The idea is to have functionalities on par with

Each workout is a top-level entity. The second string of the entity title must be a date in format YYYY-MM-DD. The date will probably become a property of the entity.

 * Workout
:date: 2018-01-24

Each exercise is a sub-entity of a workout entity. An exercise can have the following optional properties :

  • name; it’s the name of the entity
  • muscle: a string to identifying the type of exercise. E.g Cardio, Abs, Legs.
  • duration: duration of the exercise in format hh:mm:ss
  • distance: distance in meters, i.e. 3200.0 m
 ** Rowing Machine
:muscle: Cardio 
:duration: 0:15:39 
:distance: 3200.0 m
 ** Crunch Machine
:muscle: Abs  

An exercise can have multiple sets. Sets are expressed as a - list.

- 11.0 kgs x 10 reps
- 11.0 kgs x 15 reps
- 11.0 kgs x 15 reps

Weight property for sets is optional

- 10 reps
- 15 reps
- 15 reps

You can find a complete example in


The server is implemented via a small command line python utility in cli/ The server has a prompt, which allows to load org-files (and in future indexes) and process them without need of reloading them for each invocation.

The server supports the following commands

  • import csvfile orgfile Converts a CSV file exported by fitnotes Android app to org-fit format
  • quit Quit the program
  • load_org orgfile Loads an org-fit file
  • list_muscles List the tags used to classify exercises
  • graph value groupby months muscle filename produces a linear graph from the loaded fit file
    • value is the value displayed and can be count (number of exercises), sets (number of sets), reps (total number of repetitions), volume (weight x reps)
    • groupsby is the resolution of the x axis and can be day, week, or month
    • months is the interval of the x axis and can be all (no limit) or an integer representing the number of months
    • muscle filters the exercises and can be all or one of the strings used to tag the exercises (i.e. Chest)
    • filename filename of the produced png

The server uses pandas, numpy, matplotlib, and orgparser


The GUI consists of an org-file where you can add graph and statistics and emacs functions defined in emacs/gym.el.


There are three variables to customize:

  • org-fit-data-file full-path of your org-fit file
  • org-fit-export-path full-path of the directory used to produce the graphs
  • org-fit-cli-exec full-path of

Using the GUI

Open an org file like This is your main GUI. Graph are produced by manipulating org-babel snippets.

  • To start the org-fit execute org-fit-start.
  • To add a graph for historical data execute org-fit-add-graph-history
  • To add a table for historical data execute org-fit-add-table-summary
  • To add a pie chart graph execute org-fit-add-graph-breakout
  • To add a table for breakout data execute org-fit-add-table-breakout
  • You can update a graph by moving the cursor in the corresponding org-babel fragment and use the following keybinding
    • C-q 1 display volume (i.e. kg * reps)
    • C-q 2 display reps
    • C-q 3 display max weight
    • C-q 4 display sets
    • C-q 5 display max reps
    • C-q 6 display 1RM Epley formula
    • C-w 1 group per month
    • C-w 2 group per week
    • C-w 3 group per day
    • C-e 1 limit results to last month
    • C-e 2 limit results to two months
    • C-e 3 limit results to three months
    • C-e 6 limit results to six month
    • C-e 0 no time limit
    • C-e e filter per exercise
    • C-e 0 filter per muscle

Work in progress

  • breakout graph per exercise
  • selection of time range for breakout graph
  • Import/merging
  • Compute additional data per workout
You can’t perform that action at this time.