Giter Site home page Giter Site logo

rmrl's Introduction

rmrl: reMarkable Rendering Library

rmrl is a Python library for rendering reMarkable documents to PDF files. It takes the original PDF document and the files describing your annotations, combining them to produce a document close to what reMarkable itself would output.

Demo

The same notebook was rendered to a PDF via the reMarkable app and rmrl. The resultant PDF files were converted to PNGs with ImageMagick at 300 dpi.

reMarkable output rmrl output
reMarkable rmrl

The biggest differences are the lack of texture in the pencils and paintbrush, which we hope to address in the future. Two differences are intentional:

  • The highlight color is more saturated, since we feel the default color is too subtle.
  • The grid lines from the template are less saturated, to better reflect the appearance on the device. This is configurable.

Installation

rmrl requires Python 3.7 or later. If that's installed, the easiest installation is to do a

pip install rmrl

Alternatively, you may clone this repository. Poetry is used for development, so once that is installed you can run

poetry install

to get a virtual environment all set up.

Usage

The main interface to rmrl is through a single function:

from rmrl import render

output = render(source)

source may be:

  • The filename of a zip file containing the document.
  • The filename of any (root-level) file from an unpacked document.
  • Any object that provides open() and exists() methods. See rmrl/sources.py for more details on this API.

The output is a filestream with the contents of the PDF file.

The render function takes the following keyword arguments:

  • progress_cb: A callback function to be called periodically during the rendering process. It will be called with a single argument, a number from 0 to 100 indicating the progress. This function can abort the process by raising an exception.

Command-line Usage

rmrl may be called as a command-line tool. Once it has been installed, run

python -m rmrl filename

to convert filename to an annotated PDF. The default output is to stdout. Use

python -m rmrl -h

to see all of the options.

Templates

rmrl can use the reMarkable templates as a background when rendering notebooks. We cannot ship copies of these templates. You may be allowed to copy them from your own reMarkable device on to your computer for personal use. If this is legal in your jurisdiction, you may connect your device to your computer by the USB cable and run

python -m rmrl.load_templates

This will copy these templates to ~/.local/share/rmrl/templates (assuming default XDG settings).

History

rmrl derives from the reMarkable Connection Utility, by Davis Remmel. RCU is a full-featured GUI for managing all aspects of a reMarkable device. Do check it out if you are looking for a stand-alone solution for getting documents on and off of your device.

RCU was chosen as a base for rmrl due to its high-quality rendering. The following are the major changes:

  • rmrl is designed as a library, for incorporation into other programs. RCU is designed as a stand-alone program.
  • rmrl uses the pure-Python ReportLab Toolkit for rendering PDF files. RCU uses the Qt framework, which is a significantly heavier installation.
  • rmrl only supports vector output, while RCU offers both raster and vector rendering.
  • RCU supports PDF layers (Optional Content Groups). At this point, rmrl does not.
  • RCU can add PDF annotations corresponding to highlights. At this point, rmrl does not.

Trademarks

reMarkable(R) is a registered trademark of reMarkable AS. rmrl is not affiliated with, or endorsed by, reMarkable AS. The use of “reMarkable” in this work refers to the company’s e-paper tablet product(s).

Copyright

Copyright (C) 2020 Davis Remmel

Copyright 2021 Robert Schroll

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

rmrl's People

Contributors

rschroll avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rmrl's Issues

Render only annotated PDF pages

Remarkable cannot add white pages or delete useless pages from a PDF.
As workaround, I usually add a white page after each document page and then upload this document on the tablet, so I can read and annotate the document and add comment on white pages. However several pages aren't use and I do not really care about them.

Exporting only the annotated pages will be a great feature. This features is already present, for example, in rmapi, but there's no great open source PDF tool in go, so the render is bad.

Use of templates causes unexpected slowdown

When using templates, rendering a document with 140 pages of handwritten notes takes over half an hour on my raspberry pi. The same file renders in ~1min without templates. It would be nice if the template rendering could be optimized, since the aforementioned slowdown makes them somewhat unusable right now.

Index out of bounds errror?

Hi - getting the following error:

Traceback (most recent call last): File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code exec(code, run_globals) File "/usr/local/lib/python3.9/site-packages/rmrl/__main__.py", line 53, in <module> sys.exit(main()) File "/usr/local/lib/python3.9/site-packages/rmrl/__main__.py", line 44, in main stream = render(source, File "/usr/local/lib/python3.9/site-packages/rmrl/render.py", line 130, in render rmpage = rmpdfr.pages[i] IndexError: list index out of range

Looks like the code is operating on a range using the length of the basepdfr.pages array and then also using that on the rmpdfr.pages array that apparently isn't always the same length. Don't know how to fix. Anyone else experiencing this?

`basepage.CropBox or basepage.MediaBox or basepage.Parent.MediaBox` returns `None`

Hi,

the renderer crashes when used on the supplied buggy.zip (called via python -m rmrl buggy.zip ) resulting in the following error:

Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/florian/.local/lib/python3.9/site-packages/rmrl/__main__.py", line 53, in <module>
    sys.exit(main())
  File "/home/florian/.local/lib/python3.9/site-packages/rmrl/__main__.py", line 44, in main
    stream = render(source,
  File "/home/florian/.local/lib/python3.9/site-packages/rmrl/render.py", line 149, in render
    merge_pages(basepage, rmpage, i in changed_pages, expand_pages)
  File "/home/florian/.local/lib/python3.9/site-packages/rmrl/render.py", line 442, in merge_pages
    bpage_box = list(map(float, basepage.CropBox
TypeError: 'NoneType' object is not iterable

Apparently, in this particular case, neither basepage.CropBox, nor basepage.MediaBox nor basepage.parent.CropBox exist.

I'm trying to debug it myself, but am not particularly confident right now. Could you provide me some hints?

Thank you very much :)

simulation of pens

Hi,

i know you said 'eventually' to bring new features like pen-simulations into the library.
Any progress on this? (no, please don't feel pushed in any way, just asking about the 'roadmap')
BTW, pretty good work so far!!!

Add support for red and blue pens

v2.11 added support for two more pen colors (red and blue): https://support.remarkable.com/hc/en-us/articles/4413620362897-Software-release-2-11#article-heading-1

(The fork @naturale0 mentions in #12 (comment) includes support for these.)

As-is, I get the following error when I try to use 89b5cc3 on a document where I've drawn in red or blue:

$ python -m rmrl 'Quick reference.zip' 'Quick reference.pdf'
Traceback (most recent call last):
  File "/Users/jmyers/.pyenv/versions/3.9.6/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Users/jmyers/.pyenv/versions/3.9.6/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/jmyers/wtf/rm-todos/rmrl/src/rmrl/rmrl/__main__.py", line 53, in <module>
    sys.exit(main())
  File "/Users/jmyers/wtf/rm-todos/rmrl/src/rmrl/rmrl/__main__.py", line 44, in main
    stream = render(source,
  File "/Users/jmyers/wtf/rm-todos/rmrl/src/rmrl/rmrl/render.py", line 95, in render
    page.render_to_painter(pdf_canvas, vector, template_alpha)
  File "/Users/jmyers/wtf/rm-todos/rmrl/src/rmrl/rmrl/document.py", line 148, in render_to_painter
    layer.render_to_painter(canvas, vector)
  File "/Users/jmyers/wtf/rm-todos/rmrl/src/rmrl/rmrl/document.py", line 245, in render_to_painter
    self.paint_strokes(painter, vector=vector)
  File "/Users/jmyers/wtf/rm-todos/rmrl/src/rmrl/rmrl/document.py", line 238, in paint_strokes
    color=self.colors[color])
IndexError: list index out of range

Running this on the reMarkable itself?

I want to be able to run this on the device itself to export PDFs to a directory.

I've tried installing python 3 and other items via toltec. I've done the following:

opkg install python-3 python3-pip python3-dev libxml2 libxml2-dev libxslt python3-lxml

Then when I try:

pip install rmrl

I get a bunch of errors below.

Is it because there no Entware package for libxslt-dev? I've tried this:

opkg install libxslt-devel
Unknown package 'libxslt-devel'.

Errors I get on pip install rmrl:

Collecting rmrl
  Using cached rmrl-0.2.1-py3-none-any.whl (519 kB)
Collecting pdfrw<0.5,>=0.4
  Using cached pdfrw-0.4-py2.py3-none-any.whl (69 kB)
Collecting svglib<2.0.0,>=1.0.1
  Using cached svglib-1.2.1.tar.gz (896 kB)
Collecting xdg<6.0.0,>=5.0.1
  Using cached xdg-5.1.1-py3-none-any.whl (5.0 kB)
Collecting reportlab<4.0.0,>=3.5.59
  Using cached reportlab-3.6.8.tar.gz (4.5 MB)
Collecting pillow>=4.0.0
  Using cached Pillow-9.0.1.tar.gz (49.5 MB)
Collecting lxml
  Using cached lxml-4.8.0.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_be3a8c5a26a64a79b1597aadcc844957/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_be3a8c5a26a64a79b1597aadcc844957/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-uumkos1o
         cwd: /tmp/pip-install-gpdmkj2i/lxml_be3a8c5a26a64a79b1597aadcc844957/
    Complete output (3 lines):
    Building lxml version 4.8.0.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/3b/94/e2b1b3bad91d15526c7e38918795883cee18b93f6785ea8ecf13f8ffa01e/lxml-4.8.0.tar.gz#sha256=f63f62fc60e6228a4ca9abae28228f35e1bd3ce675013d1dfb828688d50c6e23 (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.7.1.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_9897fc1680fc4fe7bf94e67fd3453bc3/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_9897fc1680fc4fe7bf94e67fd3453bc3/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-4qqd7cvf
         cwd: /tmp/pip-install-gpdmkj2i/lxml_9897fc1680fc4fe7bf94e67fd3453bc3/
    Complete output (3 lines):
    Building lxml version 4.7.1.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/84/74/4a97db45381316cd6e7d4b1eb707d7f60d38cb2985b5dfd7251a340404da/lxml-4.7.1.tar.gz#sha256=a1613838aa6b89af4ba10a0f3a972836128801ed008078f8c1244e65958f1b24 (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.6.5.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_25b1ad733309462c9b1acde05cb640a6/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_25b1ad733309462c9b1acde05cb640a6/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-t67f5uvh
         cwd: /tmp/pip-install-gpdmkj2i/lxml_25b1ad733309462c9b1acde05cb640a6/
    Complete output (3 lines):
    Building lxml version 4.6.5.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/e6/e1/34b3ab08553fe9a30e15b2bb9d1803a49d7d907dd9f245638839190042f0/lxml-4.6.5.tar.gz#sha256=6e84edecc3a82f90d44ddee2ee2a2630d4994b8471816e226d2b771cda7ac4ca (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.6.4.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_e3bc24bf52d54b969d8debee5b7a4e18/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_e3bc24bf52d54b969d8debee5b7a4e18/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-ten5m3nq
         cwd: /tmp/pip-install-gpdmkj2i/lxml_e3bc24bf52d54b969d8debee5b7a4e18/
    Complete output (3 lines):
    Building lxml version 4.6.4.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/fe/4c/a4dbb4e389f75e69dbfb623462dfe0d0e652107a95481d40084830d29b37/lxml-4.6.4.tar.gz#sha256=daf9bd1fee31f1c7a5928b3e1059e09a8d683ea58fb3ffc773b6c88cb8d1399c (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.6.3.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_63004563a68546a698c1583822c0341f/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_63004563a68546a698c1583822c0341f/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-puy8pbiv
         cwd: /tmp/pip-install-gpdmkj2i/lxml_63004563a68546a698c1583822c0341f/
    Complete output (3 lines):
    Building lxml version 4.6.3.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/e5/21/a2e4517e3d216f0051687eea3d3317557bde68736f038a3b105ac3809247/lxml-4.6.3.tar.gz#sha256=39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468 (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.6.2.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_04c27419a28c4b08923a74df446ad40b/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_04c27419a28c4b08923a74df446ad40b/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-bvlxwq6f
         cwd: /tmp/pip-install-gpdmkj2i/lxml_04c27419a28c4b08923a74df446ad40b/
    Complete output (3 lines):
    Building lxml version 4.6.2.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/db/f7/43fecb94d66959c1e23aa53d6161231dca0e93ec500224cf31b3c4073e37/lxml-4.6.2.tar.gz#sha256=cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.6.1.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_498dbd20f35f47ada88bbcd0ddb96ba8/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_498dbd20f35f47ada88bbcd0ddb96ba8/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-4kxza0d7
         cwd: /tmp/pip-install-gpdmkj2i/lxml_498dbd20f35f47ada88bbcd0ddb96ba8/
    Complete output (3 lines):
    Building lxml version 4.6.1.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/c5/2f/a0d8aa3eee6d53d5723d89e1fc32eee11e76801b424e30b55c7aa6302b01/lxml-4.6.1.tar.gz#sha256=c152b2e93b639d1f36ec5a8ca24cde4a8eefb2b6b83668fcd8e83a67badcb367 (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Using cached lxml-4.6.0.tar.gz (3.2 MB)
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-gpdmkj2i/lxml_50b0dfd6c92641aebd64ea7ed392a312/setup.py'"'"'; __file__='"'"'/tmp/pip-install-gpdmkj2i/lxml_50b0dfd6c92641aebd64ea7ed392a312/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-703vabft
         cwd: /tmp/pip-install-gpdmkj2i/lxml_50b0dfd6c92641aebd64ea7ed392a312/
    Complete output (3 lines):
    Building lxml version 4.6.0.
    Building without Cython.
    Error: Please make sure the libxml2 and libxslt development packages are installed.
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/3c/5a/81446fb5a4706bb07a98427634ab93219dc7fa393841d81f5da5c7e151b7/lxml-4.6.0.tar.gz#sha256=8319abacbbe9fd9791c2e3c23deb9b6a16abc0fcbdfcc26722035e865b3d207f (from https://pypi.org/simple/lxml/) (requires-python:>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
reMarkable: ~/convert/ pip install rmrl
Collecting rmrl
  Using cached rmrl-0.2.1-py3-none-any.whl (519 kB)
Collecting xdg<6.0.0,>=5.0.1
  Using cached xdg-5.1.1-py3-none-any.whl (5.0 kB)
Collecting svglib<2.0.0,>=1.0.1
  Using cached svglib-1.2.1.tar.gz (896 kB)
Collecting reportlab<4.0.0,>=3.5.59
  Using cached reportlab-3.6.8.tar.gz (4.5 MB)
Collecting pdfrw<0.5,>=0.4
  Using cached pdfrw-0.4-py2.py3-none-any.whl (69 kB)
Collecting pillow>=4.0.0
  Using cached Pillow-9.0.1.tar.gz (49.5 MB)
Requirement already satisfied: lxml in /opt/lib/python3.10/site-packages (from svglib<2.0.0,>=1.0.1->rmrl) (4.6.4)
Collecting tinycss2>=0.6.0
  Downloading tinycss2-1.1.1-py3-none-any.whl (21 kB)
Collecting cssselect2>=0.2.0
  Downloading cssselect2-0.5.0-py3-none-any.whl (15 kB)
Collecting webencodings
  Downloading webencodings-0.5.1-py2.py3-none-any.whl (11 kB)
Using legacy 'setup.py install' for reportlab, since package 'wheel' is not installed.
Using legacy 'setup.py install' for pillow, since package 'wheel' is not installed.
Using legacy 'setup.py install' for svglib, since package 'wheel' is not installed.
Installing collected packages: webencodings, tinycss2, pillow, reportlab, cssselect2, xdg, svglib, pdfrw, rmrl
    Running setup.py install for pillow ... error
    ERROR: Command errored out with exit status 1:
     command: /opt/bin/python3 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-zrig3tko/install-record.txt --single-version-externally-managed --compile --install-headers /opt/include/python3.10/pillow
         cwd: /tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/
    Complete output (163 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-armv7l-3.10
    creating build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/features.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/_version.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/_util.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/_tkinter_finder.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/_binary.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/__main__.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/__init__.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/XpmImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/XbmImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/XVThumbImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/WmfImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/WebPImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/WalImageFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/TiffTags.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/TiffImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/TgaImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/TarIO.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/SunImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/SpiderImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/SgiImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PyAccess.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PsdImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PpmImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PngImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PixarImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PdfParser.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PdfImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PcxImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PcfFontFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PcdImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PalmImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PaletteFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/PSDraw.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/MspImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/MpoImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/MpegImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/MicImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/McIdasImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/JpegPresets.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/JpegImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/Jpeg2KImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/IptcImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImtImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageWin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageTransform.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageTk.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageStat.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageShow.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageSequence.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageQt.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImagePath.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImagePalette.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageOps.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageMorph.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageMode.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageMath.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageGrab.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageFont.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageFilter.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageEnhance.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageDraw2.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageDraw.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageColor.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageCms.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImageChops.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/Image.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ImImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/IcoImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/IcnsImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/Hdf5StubImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/GribStubImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/GimpPaletteFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/GimpGradientFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/GifImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/GdImageFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/GbrImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/FtexImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/FpxImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/FontFile.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/FliImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/FitsStubImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ExifTags.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/EpsImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/DdsImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/DcxImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/CurImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/ContainerIO.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/BufrStubImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/BmpImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/BlpImagePlugin.py -> build/lib.linux-armv7l-3.10/PIL
    copying src/PIL/BdfFontFile.py -> build/lib.linux-armv7l-3.10/PIL
    running egg_info
    writing src/Pillow.egg-info/PKG-INFO
    writing dependency_links to src/Pillow.egg-info/dependency_links.txt
    writing top-level names to src/Pillow.egg-info/top_level.txt
    reading manifest file 'src/Pillow.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no files found matching '*.c'
    warning: no files found matching '*.h'
    warning: no files found matching '*.sh'
    warning: no previously-included files found matching '.appveyor.yml'
    warning: no previously-included files found matching '.clang-format'
    warning: no previously-included files found matching '.coveragerc'
    warning: no previously-included files found matching '.editorconfig'
    warning: no previously-included files found matching '.readthedocs.yml'
    warning: no previously-included files found matching 'codecov.yml'
    warning: no previously-included files matching '.git*' found anywhere in distribution
    warning: no previously-included files matching '*.pyc' found anywhere in distribution
    warning: no previously-included files matching '*.so' found anywhere in distribution
    no previously-included directories found matching '.ci'
    adding license file 'LICENSE'
    writing manifest file 'src/Pillow.egg-info/SOURCES.txt'
    running build_ext


    The headers or library files could not be found for zlib,
    a required dependency when compiling Pillow from source.

    Please see the install instructions at:
       https://pillow.readthedocs.io/en/latest/installation.html

    Traceback (most recent call last):
      File "/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py", line 989, in <module>
        setup(
      File "/opt/lib/python3.10/site-packages/setuptools/__init__.py", line 153, in setup
      File "/opt/lib/python3.10/distutils/core.py", line 148, in setup
      File "/opt/lib/python3.10/distutils/dist.py", line 966, in run_commands
      File "/opt/lib/python3.10/distutils/dist.py", line 985, in run_command
      File "/opt/lib/python3.10/site-packages/setuptools/command/install.py", line 61, in run
      File "/opt/lib/python3.10/distutils/command/install.py", line 568, in run
      File "/opt/lib/python3.10/distutils/cmd.py", line 313, in run_command
      File "/opt/lib/python3.10/distutils/dist.py", line 985, in run_command
      File "/opt/lib/python3.10/distutils/command/build.py", line 135, in run
      File "/opt/lib/python3.10/distutils/cmd.py", line 313, in run_command
      File "/opt/lib/python3.10/distutils/dist.py", line 985, in run_command
      File "/opt/lib/python3.10/site-packages/setuptools/command/build_ext.py", line 79, in run
      File "/opt/lib/python3.10/distutils/command/build_ext.py", line 343, in run
      File "/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py", line 804, in build_extensions
        raise RequiredDependencyException(f)
    __main__.RequiredDependencyException: zlib

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py", line 1009, in <module>
        raise RequiredDependencyException(msg)
    __main__.RequiredDependencyException:

    The headers or library files could not be found for zlib,
    a required dependency when compiling Pillow from source.

    Please see the install instructions at:
       https://pillow.readthedocs.io/en/latest/installation.html


    ----------------------------------------
ERROR: Command errored out with exit status 1: /opt/bin/python3 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vzrk0rdx/pillow_63dcc110421046ebab7061d959a6be4b/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-zrig3tko/install-record.txt --single-version-externally-managed --compile --install-headers /opt/include/python3.10/pillow Check the logs for full command output.
WARNING: You are using pip version 21.2.3; however, version 22.0.3 is available.
You should consider upgrading via the '/opt/bin/python3 -m pip install --upgrade pip' command.

UnboundLocalError

For some files, I get this error:

Traceback (most recent call last):
File "/home/xxx/Downloads/rmirro-main/render_rmrl.py", line 31, in
status = render_rmrl(infile, outfile)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/xxx/Downloads/rmirro-main/render_rmrl.py", line 18, in render_rmrl
stream = render(input)
^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/rmrl/render.py", line 157, in render
if apply_ocg:
^^^^^^^^^
UnboundLocalError: cannot access local variable 'apply_ocg' where it is not associated with a value.

apply_ocg is set a few lines above, however inside a for-loop. So I assume there's nothing to loop through at this point and hence the variable is not being set. Setting it just before line 157 removed the error, but the resulting file is broken, so something more is going on...

Python 3.6

Is there a way to compile the program with Python 3.6?
OpenSUSE Leap (current 15.2 and upcoming 15.3) stays at 3.6.12.

Render crash with annotated PDF

Related to rschroll/rmfuse#17

Run python -m rmrl Test.zip Test,pdf

File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.9/site-packages/rmrl/__main__.py", line 53, in <module>
    sys.exit(main())
  File "/usr/lib/python3.9/site-packages/rmrl/__main__.py", line 44, in main
    stream = render(source,
  File "/usr/lib/python3.9/site-packages/rmrl/render.py", line 149, in render
    merge_pages(basepage, rmpage, i in changed_pages, expand_pages)
  File "/usr/lib/python3.9/site-packages/rmrl/render.py", line 478, in merge_pages
    effective_rotation = int(basepage.Rotate)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

where Test.zip is an annotated PDF.

Support for reMarkables "smart highlighter"

First of all: thank you for the great work, really nice and useful library!

In their software release 2.7, reMarkable introduced the so-called "smarter highlighter", which gives nice rectangular highlights when highlighting text in PDFs. These highlights currently don't appear in PDFs rendered with rmrl.
Would it be possible to add this feature? That would be really useful (for me at least), but I totally understand if that's not possible for you. :)

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.