Skip to main content

AssignmentWriter

A Python package and command line tool that writes your text on a sheet of paper, in a handwriting font and ink colour of your choice. Pick a paper, a font and an ink, and get back an image of the page(s) (in form of pdf too) - all in a few lines of code.

Version License: MIT

Installation

pip install assignmentwriter -U

Quick Start

from assignmentwriter import Assignment, AssignmentConfigOptions

config = AssignmentConfigOptions(Text="Hello World", Paper="lined", Font="caveat", Ink="blue")
result = Assignment(config).create()

result.save("page.png")  # saves the image
print(result)            # prints the saved path (if saved)

Or write a whole text file, on as many pages as it needs:

config = AssignmentConfigOptions(File="essay.txt", Paper="spiral", Ink="teal")
result = Assignment(config).create()

result.save("essay.png")      # essay_1.png, essay_2.png, ...
result.save_pdf("essay.pdf")  # or all the pages in one PDF

Previews

See at https://github.com/TheHritu/AssignmentWriter

Papers, fonts and inks

Option Values
Paper a4, lined, rough, spiral, wrinkled, cream, cyan, lightblue, lightgreen, lime, orange, pink
Font adinekirnberg, alanishand, architex, caveat, greatvibesregular, hand_note, homemadeapple, honeyscript, jottflf, note_this, pleasewritemeasong, s_hand
Ink blue, black, red, green, pencil, brown, purple, orange, teal, magenta, or any hex colour such as "131394"

A font can also be chosen by its number, 1 to 12, in the order shown above (Font=4 is caveat). Names are not case sensitive and spaces, dashes and underscores are ignored ("Hand Note" and "Light Green" work).

from assignmentwriter import available_fonts, available_papers, INKS

print(available_papers())  # ['a4', 'lined', 'rough', 'spiral', 'wrinkled', 'cream', 'cyan', 'lightblue', 'lightgreen', 'lime', 'orange', 'pink']
print(available_fonts())   # ['adinekirnberg', 'alanishand', 'architex', 'caveat', 'greatvibesregular', 'hand_note', 'homemadeapple', 'honeyscript', 'jottflf', 'note_this', 'pleasewritemeasong', 's_hand']
print(list(INKS))          # ['blue', 'black', 'red', 'green', 'pencil', 'brown', 'purple', 'orange', 'teal', 'magenta']

Note: alanishand draws the digits 2 and 5 very wide, so lines with those numbers can run off the page. Use another font for text with numbers.

Configuration

AssignmentConfigOptions accepts these fields:

Field Type Default Description
Text str None Text to write (give Text or File, not both)
File str or Path None A UTF-8 text file to write instead of Text
Paper str "a4" Paper to write on
Font str "caveat" Handwriting font (name or number)
Ink str "blue" Ink colour (name or hex)
KeepLineBreaks bool False Start a new line wherever your text has one
FontSize int None Override the font size
MaxLineLength int None Override the number of characters per line
MarginLeft int None Override the left margin (pixels)
MarginTop int None Override the top margin (pixels)
MarginBottom int None Override the space kept free at the bottom of each page (pixels)
LineSpacing float None Override the space between lines (pixels)

The last six are None by default, which keeps the layout that is tuned for the chosen paper and font. An invalid value raises a ValueError as soon as the config is created.

By default your text is written as one paragraph, line breaks are treated as spaces. Use KeepLineBreaks=True to keep headings, lists and paragraphs on their own lines.

Text from a file

Pass the path of a UTF-8 text file as File instead of Text:

from assignmentwriter import Assignment, AssignmentConfigOptions

config = AssignmentConfigOptions(File="essay.txt", Paper="lined", Ink="black", KeepLineBreaks=True)
result = Assignment(config).create()
result.save("essay.png")

A ValueError is raised if the file cannot be read, is empty, or if you give both Text and File.

Get the tuned layout for a paper and font:

Returns a dictionary with the default layout values.

from assignmentwriter import Assignment, AssignmentConfigOptions

config = AssignmentConfigOptions(Text="Hi", Paper="lined", Font="caveat")
print(Assignment(config).get_defaults())
# {'Paper': 'lined', 'Font': 'caveat', 'FontFile': 'caveat.ttf', 'FontSize': 85,
#  'MaxLineLength': 52, 'MarginLeft': 370, 'MarginTop': 333, 'MarginBottom': 130, 'LineSpacing': 22}

Several pages

When your text is too long for one page, it continues on as many pages as it needs, so none of it is lost. A line is never split between two pages.

config = AssignmentConfigOptions(File="essay.txt", Paper="spiral")
result = Assignment(config).create()

print(len(result))            # the number of pages
result.save("essay.png")      # essay_1.png, essay_2.png, ...
result.save_pdf("essay.pdf")  # or all the pages in one PDF

AssignmentResult

Assignment.create() returns an AssignmentResult object:

result = Assignment(config).create()

bool(result)                 # False if the pages could not be created
len(result)                  # the number of pages
result.image                 # the first page as a Pillow Image
result[1]                    # the second page, `for page in result` goes through all of them
result.save()                # assignment.png, or assignment_1.png, assignment_2.png ... for several pages
result.save("out.png")       # save to a specific path (png, jpg, ...), returns the list of paths
result.save("pages/")        # save in a folder
result.save_pdf("out.pdf")   # all the pages in one PDF (as wide as an A4 sheet), returns the path
str(result)                  # the paths of the last save, one per line ("" before saving)

Each page is drawn when you ask for it, so a very long text does not keep every page in memory at once.

If anything fails, create() returns a falsy AssignmentResult and logs the error. save() and save_pdf() return None and log the error if a file cannot be written. A warning is logged if some lines run past the right edge of the page. Use a smaller FontSize / MaxLineLength.


CLI

First, install the extra dependency for coloured output (optional, the CLI also works without it):

pip install "assignmentwriter[cli]"

Usage

No arguments — launches an interactive prompt:

assignmentwriter

Quick create — just pass your text directly (saved as assignment.png):

assignmentwriter "Hello World"

Pick a paper, font and ink:

assignmentwriter "Hello World" --paper lined --font caveat --ink black

Save the image to a file:

assignmentwriter "Hello World" --save output.png

Write the text of a file (keep its line breaks):

assignmentwriter --file notes.txt --keep-line-breaks

Long text continues on more pages, saved as essay_1.png, essay_2.png, ... :

assignmentwriter --file essay.txt --paper spiral --save essay.png

Save all the pages as one PDF:

assignmentwriter --file essay.txt --paper spiral --pdf

Plain output (just the saved paths, no colors — useful for scripting):

assignmentwriter "Hello World" --as-text

List

See every paper, font and ink:

assignmentwriter list

Add --as-text to get plain line-by-line output instead of a table.

On Some OS

On some operating systems, the CLI may not be available as assignmentwriter immediately after installation. If you encounter a "command not found" error, try running it with Python:

python -m assignmentwriter "Hello World"

Fonts and papers

The code is MIT licensed, but the fonts and paper images have their own terms.

Coffee is love, coffee is life.

https://www.buymeacoffee.com/hritu

Contributing

Contributions are welcome — open an issue or submit a pull request.

License

MIT © TheHritu

Metadata

Release files for assignmentwriter 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for assignmentwriter 0.1.0
File Size Uploaded Provenance Actions
assignmentwriter-0.1.0.tar.gz 4.4 MB Without provenance Details for assignmentwriter-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for assignmentwriter 0.1.0
File Interpreter ABI Platform Actions
assignmentwriter-0.1.0-py3-none-any.whl Python 3 none any Details for assignmentwriter-0.1.0-py3-none-any.whl

Total release size: 8.8 MB

Release files / assignmentwriter-0.1.0.tar.gz

Download URL assignmentwriter-0.1.0.tar.gz
Size 4.4 MB
Tags Source
SHA-256 checksum
How to use checksums
5d37146be3e2de0a482b5a4b13972972c7b3c9564e652eef22b535b7adb45d71
BLAKE2b-256 checksum
How to use checksums
df5f83de7dd4364b9d209b96599e3d776f29b6596c46e79a571a834c7d3a9c34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Release files / assignmentwriter-0.1.0-py3-none-any.whl

Download URL assignmentwriter-0.1.0-py3-none-any.whl
Size 4.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
84847cab7305f6ca445f66d89b25b8f9eabfa1f03f9adbc8cc7f8f8ff4e3d038
BLAKE2b-256 checksum
How to use checksums
8e5909f077337a7f443a1eb401f1aac2587f232eaa0bcf20fac6f35126039bb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Security for assignmentwriter 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page