Grimoire is a Python library for creating interactive fiction as hyperlinked html.

Overview

Grimoire

Grimoire is a Python library for creating interactive fiction as hyperlinked html.

tests

Installation

pip install grimoire-if

Usage

Check out the tutorial created in Grimoire itself (source).

Get started

Create an instance of a Grimoire app.

from grimoire import Grimoire


app = Grimoire()

Add your first page

Create a function decorated by your app's page method. Pass the keyword argument, start=True for the first page.

@app.page(start=True)
def start(state):
    return "This is my first grimoire app.", state

Render your story

You can render our (rather boring) story right now by calling the app's render method.

# will create all the file in the /site directory

app.render()

# optionally pass an alternate path

app.render("docs/")

Inline html

The content your page function returns is rendered using Python's built-in str function, so you can include html directly in a string if you'd like.

Alternativley, Grimoire comes with a small library for creating html called hype. Import hype's classes and create html using only Python!

from hype import H1, P


@app.page(start=True)
def start(state):
    return Div(
        H1("My First Grimoire Story"),
        "<p>Inline html as a string<p>",
        P("Html using the Hype library")
    ), state

Add an option to your first page

Create another page function (we don't need start=True this time). To add this as an option to an existing page, pass an argument to the parent page which has the same name as the new page function. Use Grimoire's builtin link function to create a link to the page.

You can add as many options as you like by continuing to add arguments to a parent page's function signature.

from grimoire.templates import link


@app.page(start=True)
def start(state, second):
    return Div(
        P("Hello, Grimoire!"),
        Ul(Li(link("Go to the second page", second)))
    ), state


@app.page()
def second(state):
    return Div(
        P("I'm the second page.")
    ), state

Manage your stories state

The state object passed to your page function can be read and updated to manage the state of your application. By default it's a dictionary.

Notice how the we access the message from the first page in the second page.

@app.page(start=True)
def start(state, second):
    state["message"] = "Hello, traveller"
    return Div(
        P("Hello, Grimoire!"),
        Ul(Li(link("Go to the second page", second)))
    ), state


@app.page()
def second(state):
    return Div(
        P(f"message: {state['message']}")
    ), state

Use a custom state class

Dictionaries are cool, but often a custom class will make writing our code much more enjoyable. You can add a custom state class when creating your app.

from dataclasses import dataclass


@dataclass
class State:
    message: str = ""


app = Grimoire(State)


@app.page(start=True)
def start(state, second):
    state.message = "Hello, traveller"
    return Div(
        P("Hello, Grimoire!"),
        Ul(Li(link("Go to the second page", second)))
    ), state


@app.page()
def second(state):
    return Div(
        P(f"message: {state.message}")
    ), state

Back to the beginning

Circular references are easy in Grimoire. Just add the option argument for an eariler page.

Warning: Be careful about creating infinite loops. Grimoire will continue rendering pages as long as it's seeing a version of the state that hasn't previously been rendered.

@app.page(start=True)
def start(state, second):
    state.message = "Hello, traveller"
    return Div(
        P("Hello, Grimoire!"),
        Ul(Li(link("Go to the second page", second)))
    ), state


@app.page()
def second(state, start):
    return Div(
        P(f"message: {state.message}"),
        Ul(Li(link("Start over", start)))
    ), state

Default page function

Grimoire comes packaged with a function to style your page and render your options by default. It returns a decorator which can be applied to your page functions.

from grimoire.templates import default_page


@app.page(start=True)
@default_page("Minimal Example")
def start(state, second):
    state.message = "Hello, traveller"
    return Div(
        P("Hello, Grimoire!")
    ), [("Go to the second page", second)], state

# Also try changing up some of the colors

@app.page()
default_page(
    "Minimal Example",
    primary_bg_color="#ff0000",
    secondary_bg_color="#00ff00"
    font_color="#bbbbbb"
)
def second(state, start):
    return Div(
        P(f"message: {state.message}")
    ), [("Start over", start)], state

Next Steps

That's it! You've completed the Grimoire tutoiral. As you can see, there's not much to it. Grimiore is purposeley very minimal and our belief is that many features can be easily implemented using plain old vanilla Python on top of Grimoire.

Check some further examples:

Code and yara rules to detect and analyze Cobalt Strike

Cobalt Strike Resources This repository contains: analyze.py: a script to analyze a Cobalt Strike beacon (python analyze.py BEACON) extract.py; extrac

Tek 224 Jan 04, 2023
An AI-powered device to stop people from stealing my packages.

Package Theft Prevention Device An AI-powered device to stop people from stealing my packages. Installation To install on a raspberry pi, clone the re

rydercalmdown 157 Nov 24, 2022
A free website that keeps the people informed about housing and evictions.

Eviction Tracker Currently helping verify detainer warrant data for middle Tennessee - via Middle TN DSA - Red Door Collective Features Presents data

Red Door Collective 7 Dec 14, 2022
This is an API to get user details for competitive coding platforms - Codeforces, Codechef, SPOJ, Interviewbit. More Platform will be Added Soon.

Competitive-Programming-Score-API An API to get user details for competitive coding platforms - Codeforces, Codechef, SPOJ, Interviewbit Platforms Ava

Aaditya Prakash 3 Jan 17, 2022
Step by step development of a vending coffee machine project, including tkinter, sqlite3, simulation, etc.

Step by step development of a vending coffee machine project, including tkinter, sqlite3, simulation, etc.

Nikolaos Avouris 2 Dec 05, 2021
A wrapper for the apt package manager.

A wrapper for the apt package manager.

531 Jan 04, 2023
AIST++ API This repo contains starter code for using the AIST++ dataset.

Explainability for Vision Transformers (in PyTorch) This repository implements methods for explainability in Vision Transformers

Google 260 Dec 30, 2022
Notebook researcher - Notebook researcher with python

notebook_researcher To run the server, you must follow these instructions: At th

4 Sep 02, 2022
A python script that changes your desktop background based on current weather and time of the day.

Desktop background wallpaper, based on current weather and time A python script that changes your computer's desktop background based on current weath

Maj Gaberšček 1 Nov 16, 2021
Aevsploit İçin Destekde Bulun Papara: 1427113016

Aevsploit İçin Destekde Bulun Papara: 1427113016 Toolu Geliştirmek İçin Fikirlerinizi Bekliyorum Telegram

9 Jun 07, 2022
InverterApi - This project has been designed to take monitoring data from Voltronic, Axpert, Mppsolar PIP, Voltacon, Effekta

InverterApi - This project has been designed to take monitoring data from Voltronic, Axpert, Mppsolar PIP, Voltacon, Effekta

Josep Escobar 2 Sep 03, 2022
Estimate the Market Size for Electic and Plug-In Hybrid Vehicles In Africa

Estimate the Market Size for Electic and Plug-In Hybrid Vehicles In Africa The goal of this repository is to use open data repositories to answer the

Leonce Nshuti 0 Feb 21, 2022
A good Tool to comment on xmw

A good Tool to comment on xmw

1 Feb 10, 2022
A tool for RaceRoom Racing Experience which shows you launch data

R3E Launch Tool A tool for RaceRoom Racing Experience which shows you launch data. Usage Run the tool, change the Stop Speed to whatever you want, and

Yuval Rosen 2 Feb 01, 2022
an opensourced roblox group finder writen in python 100% free and virus-free

Roblox-Group-Finder an opensourced roblox group finder writen in python 100% free and virus-free note : if you don't want install python or just use w

mollomm1 1 Nov 11, 2021
A numbers check python package

A numbers check python package

Fayas Noushad 3 Nov 28, 2021
A basic tic tac toe game on python!

A basic tic tac toe game on python!

Shubham Kumar Chandrabansi 1 Nov 18, 2021
This repository contains a lot of short scripting programs implemented both in Python (Flask) and TypeScript (NodeJS).

fast-scripts This repository contains a lot of short scripting programs implemented both in Python (Flask) and TypeScript (NodeJS). In python These wi

Nahum Maurice 3 Dec 10, 2022
A python program for rick rolling people.

Rickware A python program for rick rolling people. (And annoying them too) What is rick roll? Read this wikipedia article - Rickrolling About program

2 Jan 18, 2022
Bazel rules to install Python dependencies with Poetry

rules_python_poetry Bazel rules to install Python dependencies from a Poetry project. Works with native Python rules for Bazel. Getting started Add th

Martin Liu 7 Dec 15, 2021