Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
ee992d1
Ignore data-tests
Azeirah Dec 12, 2024
d39fafb
Merge branch 'Big-update'
Azeirah Dec 12, 2024
4a3746d
Automatically start the right python environment in Nix devshell
Azeirah Dec 12, 2024
dadb5b2
Add a fallback highlighter color
Azeirah Jan 2, 2025
911c7fe
Merge branch 'ricklupton:main' into main
Azeirah Mar 21, 2025
320e951
add support for highlight colors
ChenghaoMou Mar 21, 2025
ca7178a
inherit base opacity from color maps
ChenghaoMou Mar 21, 2025
be858ec
Update deps
Azeirah Apr 19, 2025
5598f5a
Merge branch 'scrybble-main' into updated-dependencies
Azeirah Apr 19, 2025
73208e1
Render svg with cairo_svg
Azeirah Aug 25, 2025
2ee2232
Add lib cairo packages for macos tests
Azeirah Aug 25, 2025
ce3e6c8
Add lib cairo packages for macos tests
Azeirah Aug 25, 2025
5825199
Add lib cairo packages for macos tests
Azeirah Aug 25, 2025
4998354
Add lib cairo packages for macos tests
Azeirah Aug 25, 2025
11f7d7d
Add lib cairo packages for windows tests
Azeirah Aug 25, 2025
798ac73
Add docs for readme
Azeirah Aug 25, 2025
286ab08
Merge pull request #5 from Scrybbling-together/updated-dependencies
Azeirah Aug 25, 2025
b310261
Merge branch 'updated-dependencies' into cairo_svg
Azeirah Aug 25, 2025
899dcdd
Update lock from merge
Azeirah Aug 25, 2025
7e8d343
Merge pull request #4 from Scrybbling-together/cairo_svg
Azeirah Aug 25, 2025
d705f63
Update pyproject.toml
Azeirah Sep 6, 2025
82a1d25
Update poetry lock file
Azeirah Sep 6, 2025
b16ad35
Merge pull request #6 from ChenghaoMou/fix/highlight-colors
Azeirah Sep 6, 2025
10f0152
Update poetry lock file
Azeirah Sep 6, 2025
b9bf92f
Merge branch 'main' into GlyphRange-colors
Azeirah Sep 6, 2025
d35cf5c
Add opacity to highlighters
Azeirah Sep 6, 2025
6a1d1b6
Slightly higher opacity
Azeirah Sep 6, 2025
cec0bf1
Wider highlighter
Azeirah Sep 6, 2025
59254a0
Even wider!
Azeirah Sep 6, 2025
6d2d283
Merge pull request #7 from Scrybbling-together/GlyphRange-colors
Azeirah Sep 6, 2025
9fa3f3e
Update deps!
Azeirah Sep 6, 2025
4f9cf05
Merge remote-tracking branch 'origin/main'
Azeirah Sep 6, 2025
c140ca2
Update deps!
Azeirah Sep 6, 2025
7c339c6
Correctly implement color rendering for Ballpoint Pen and Paintbrush
Azeirah Sep 21, 2025
feaaac0
Remove custom color rendering for Ballpoint Pen and Brush, these do n…
Azeirah Sep 21, 2025
fef913d
Fix rare bug caused by an improper sentinel value
Azeirah Oct 12, 2025
cfffbb3
Fix text anchoring and stop stripping whitespace
avncharlie Dec 31, 2025
298aac3
Added support for soft linebreaks
avncharlie Jan 2, 2026
b591e25
Added support for anchoring on text character X coordinate
avncharlie Jan 2, 2026
7b61e1a
Added remarkable fonts
avncharlie Jan 8, 2026
26c13fd
Add Chrome SVG to PDF conversion (with option to opt-out)
avncharlie Jan 8, 2026
e615b69
Add text wrapping, checkboxes, bulleted and numbered lists
avncharlie Jan 8, 2026
d60d0b9
Add device detection (for RM2 and RMPP)
avncharlie Jan 3, 2026
a2890f8
Removed reMarkable fonts (provided download script), and added fallba…
avncharlie Jan 5, 2026
d81c66a
Added option to select reMarkable device
avncharlie Jan 8, 2026
f8b60f4
Updated readme
avncharlie Jan 8, 2026
3ac21ba
Update .gitignore to ignore new reMarkable fonts path
avncharlie Jan 9, 2026
39b98e1
Add support for custom dimension output
avncharlie Jan 9, 2026
dbee726
Refactored enormous svg.py to multiple files, and gathered global sta…
avncharlie Jan 9, 2026
debb816
Added --no-sandbox to chrome invocation
avncharlie Jan 11, 2026
4e8de06
Update packages with newest version of rmc and update versions
Azeirah Jan 11, 2026
78eba13
Remove duplicate functions and create new paragraph styles classes
Azeirah Jan 11, 2026
de743d3
Add missing paragraph style
avncharlie Jan 13, 2026
977d33f
Added tests
avncharlie Jan 13, 2026
872242b
Only use chrome rendering when embedded text is present
avncharlie Jan 13, 2026
535ad63
Fix issue with handling bottom-anchor on document with no text
avncharlie Jan 26, 2026
75687dd
Added support for strokes anchored to words in a wrapped line and fix…
avncharlie Jan 31, 2026
a648ee7
fix conditional chrome logic
avncharlie Feb 22, 2026
f260fea
Merge pull request #10 from avncharlie/text-anchoring
Azeirah Mar 1, 2026
75a76d4
Remove unneded functions
avncharlie Mar 1, 2026
dd9afcd
Merge pull request #12 from avncharlie/remove-unneeded-rmc
Azeirah Mar 1, 2026
3643554
When chrome is missing, fallback gracefully
Azeirah Mar 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- name: Install macOS dependencies
if: matrix.os == 'macos-latest'
run: |
brew install cairo libxml2 libffi
echo "PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH" >> $GITHUB_ENV
echo "DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Install Windows dependencies
if: matrix.os == 'windows-latest'
run: |
choco install msys2 --yes
C:\tools\msys64\usr\bin\pacman -S --noconfirm mingw-w64-x86_64-cairo mingw-w64-x86_64-pkg-config
echo "C:\tools\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Install poetry
run: pipx install poetry
- name: Setup Python ${{ matrix.python-version }}
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
__pycache__/
.idea
data-tests/
.DS_Store
src/rmc/assets/fonts/reMarkableSans.woff2
src/rmc/assets/fonts/reMarkableSerif.woff2
src/rmc/assets/fonts/reMarkableSerifItalic.woff2
61 changes: 44 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,69 @@
# rmc

Command line tool for converting to/from remarkable `.rm` version 6 (software version 3) files.
Command line tool for converting to/from remarkable `.rm` version 6 (software
version 3) files.

## Installation

If you want nice font rendering, you will need to install chrome/chromium (used
to create svg/pdf with embedded fonts). Otherwise, rendering will fall back to
using cairo. Chrome based rendering can also be turned off with `--no-chrome`.

To install in your current Python environment:

pip install rmc

Or use [pipx](https://pypa.github.io/pipx/) to install in an isolated environment (recommended):
Or use [pipx](https://pypa.github.io/pipx/) to install in an isolated
environment (recommended):

pipx install rmc

## Usage
To embed custom reMarkable fonts in the output, you will need to download them first:

Convert a remarkable v6 file to other formats, specified by `-t FORMAT`:
cd ./src/rmc/assets/fonts/
./download_remarkable_fonts.sh

$ rmc -t markdown file.rm
Text in the file is printed to standard output.
## Usage

Specify the filename to write the output to with `-o`:
Convert rm to pdf:

$ rmc -t svg -o file.svg file.rm

The format is guessed based on the filename if not specified:

$ rmc file.rm -o file.pdf

Create a `.rm` file containing the text in `text.md`:
Convert rm to svg:

$ rmc -t rm text.md -o text.rm
$ rmc file.rm -o file.svg

Convert a remarkable v6 file to other formats, specified by `-t FORMAT`:

## SVG/PDF Conversion Status
$ rmc -t markdown file.rm -o file.md

Right now the converter works well while there are no text boxes. If you add text boxes, there are x issues:
Create a `.rm` file containing the text in `text.md`:

$ rmc -t rm text.md -o text.rm

1. if the text box contains multiple lines, the lines are actually printed in the same line, and
2. the position of the strokes gets corrupted.
```
$ rmc --help
Usage: rmc [OPTIONS] [INPUT]...

Convert to/from reMarkable v6 files.

Available FORMATs are: `rm` (reMarkable file), `markdown`, `svg`, `pdf`,
`blocks`, `blocks-data`.

Formats `blocks` and `blocks-data` dump the internal structure of the `rm`
file, with and without detailed data values respectively.

Options:
--version Show the version and exit.
-v, --verbose
-f, --from FORMAT Format to convert from (default: guess from filename)
-t, --to FORMAT Format to convert to (default: guess from filename)
-o, --output PATH Output filename (default: write to standard out)
--no-chrome Use Cairo instead of Chrome for PDF conversion
--chrome-loc PATH Path to Chrome/Chromium binary
--device [RM2|RMPP] Device type (overrides auto-detection)
--help Show this message and exit.
```

# Acknowledgements

Expand Down
131 changes: 130 additions & 1 deletion flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 26 additions & 10 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,43 @@
inputs = {
nixpkgs.url = "nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
poetry2nix = { url = "github:nix-community/poetry2nix"; };
};

outputs = { self, nixpkgs, flake-utils }:
outputs = { self, nixpkgs, flake-utils, poetry2nix }:
flake-utils.lib.eachDefaultSystem (system:
let
pythonEnv = pkgs.python312.withPackages (ps: []);
pkgs = import nixpkgs {
inherit system;
};
inherit (poetry2nix.lib.mkPoetry2Nix { inherit pkgs; })
mkPoetryEnv mkPoetryApplication defaultPoetryOverrides;
poetryArgs = {
python = pkgs.python312;
projectDir = ./.;
preferWheels = true;
overrides = defaultPoetryOverrides.extend (final: prev: {
click = prev.click.overridePythonAttrs (old: {
buildInputs = (old.buildInputs or [ ]) ++ [ prev.flit-scm ];
});
rmc = prev.rmc.overridePythonAttrs (old: {
buildInputs = (old.buildInputs or [ ]) ++ [ prev.poetry-core ];
});
});
};
pythonEnv = mkPoetryEnv (poetryArgs);
rmcBin = mkPoetryApplication (poetryArgs);
in
{
packages = {
default = rmcBin;
};
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
sqlite.dev
poetry
inkscape
buildInputs = [
pkgs.poetry
rmcBin
pythonEnv
];

LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
pkgs.sqlite.out
];
};
});
}
Loading
Loading