The design consists of various parts:
Provided by Skulpt, brought in as "vendored" code.
The user's Python code is compiled into JavaScript by Skulpt and run. A custom module (see below) provides the connection between Python and GeoGebra, creating GeoGebra objects and wrapping them in a Python object.
There is a custom sleep() implementation, to allow the user to
interrupt program execution and also to allow GeoGebra the chance to
run.
Brought in via its embedding mechanism and using its API.
Via a Skulpt/Python module written in TypeScript. Various GeoGebra objects are wrapped so that Python-level access is possible.
The front-end, written using React, with easy-peasy for state management. User's files are persisted using in-browser IndexedDB storage.
The script
dev-server.shat the top level of this repo will build the docs, link to them from
the public directory, and launch the development live-reload server.
This requires poetry; the script will point you to installation docs
if needed.
This is done with Cypress. With the development server running, you can start the Cypress interface with
npx cypress openFor deploying to github.io, assuming a git worktree ./pages/
checked out on the branch github-pages:
./tools/build-examples.sh
env VITE_DOCS_BASE_URL_WITHIN_APP=/doc npx vite build --base=/pyggb/
rsync --exclude='*~' --exclude=.git --exclude=vendor/geogebra/GeoGebra --delete --checksum -rtvn dist/ pages/
# Then if that looks OK, same without "vn" options:
rsync --exclude='*~' --exclude=.git --exclude=vendor/geogebra/GeoGebra --delete --checksum -rt dist/ pages/
( cd doc; poetry run make clean && poetry run make html )
rsync --delete --checksum -rt doc/build/html/ pages/doc
touch pages/.nojekyll
# Commit in pages/ worktree
# Push to GitHub
# Wait a few minutesFor deploying to https://some.site.com/python:
# If default "node" is not v24, something like:
nvm use v24
# Adjust PYGGB_ORIGIN_REPO if required:
PYGGB_ORIGIN_REPO=https://github.com/geogebra/pyggb.git ./tools/build-from-clone.shThe script, if successful, will finish by printing a summary to stdout, including printing a docker command line to serve the directory via Nginx.
If deployment will be a path other than python, you can override
this via the PYGGB_HOSTED_BASE_PATH environment variable:
PYGGB_ORIGIN_REPO=https://github.com/geogebra/pyggb.git \
PYGGB_HOSTED_BASE_PATH=pyggb \
./tools/build-from-clone.shA recent copy of deployggb.js is checked in to the repo. By default, the app
uses GeoGebra's CDN to provide the main files. To override this for local
development, fetch the latest GeoGebra bundle from the GeoGebra site:
as per GeoGebra's
instructions.
Unzip this into public/vendor/geogebra, which will result in a directory
public/vendor/geogebra/GeoGebra. It will also result in a file
public/vendor/geogebra/README.txt, which can be removed. Then run the
development server with
VITE_LOCAL_GEOGEBRA=yes npm startTo avoid the contents of this bundle showing up as untracked files in Git, add a
line to your local .git/info/exclude file:
/public/vendor/geogebra/GeoGebra/The above "Release process" instructions refer to this vendor bundle, but should work whether or not you are using a local copy of the bundle.
Is it worth providing common functionality (like setting the colour of an object, or the label-style and -visibility properties) via a Python and/or JavaScript base class? Currently, every object type explicitly declares the methods it supports.
Some programs generate large numbers of temporary GeoGebra objects.
There is currently no way to delete them. Although you can hide them
(by setting is_visible to False), they do continue to exist, which
slows GeoGebra down. Skulpt does not support __del__() but we could
support an explicit .delete() method on wrapped Ggb objects. Some
care will be needed as to how to handle a Python object wrapping a
deleted Ggb object.