{"id":16387978,"url":"https://github.com/dotmpe/permascroll","last_synced_at":"2026-06-03T08:30:18.776Z","repository":{"id":138232637,"uuid":"766882","full_name":"dotmpe/permascroll","owner":"dotmpe","description":"Immutable addressing of Blob content at Google App-Engine","archived":false,"fork":false,"pushed_at":"2016-05-14T01:55:09.000Z","size":184,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-03T07:33:19.132Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://permascroll.appspot.com/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dotmpe.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"license.rst","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2010-07-09T22:14:16.000Z","updated_at":"2019-07-09T00:55:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"1159fb2a-703a-4a00-abe8-d747aeb10a7d","html_url":"https://github.com/dotmpe/permascroll","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotmpe%2Fpermascroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotmpe%2Fpermascroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotmpe%2Fpermascroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotmpe%2Fpermascroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dotmpe","download_url":"https://codeload.github.com/dotmpe/permascroll/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240171746,"owners_count":19759415,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T04:28:03.047Z","updated_at":"2026-06-03T08:30:18.703Z","avatar_url":"https://github.com/dotmpe.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Permascroll\n===========\n:created: 2010-01-01\n:updated: 2010-12-03\n\n\n.. epigraph::\n\n   For any medium has the power of imposing its own assumption on the unwary.\n   Prediction and control consist in avoiding this subliminal state of Narcissus\n   trance. But the greatest aid to this end is simply in knowing that the spell\n   can occur immediately upon contact, as in the first bars of a melody.\n\n   --Marshall McLuhan, Understanding Media\n\n\n.. rubric:: This project describes a `permascroll` implementation for `Google App Engine`.\n\n.. note:: \n\n   What follows is a short introduction that needs to be straightened\n   out. Related experimental projects are mentioned and then components specific\n   to this project are discussed.\n\n\n- Let each publication be a set of symbols.\n- Let each symbol node have *a size of 1*.\n\nThe interpretation of each node is left to the client?\nXXX: or does permascrip incorporate muxdems?\n\n- Let there additionally be *zero-width* nodes, 'virtual points' that only store a pointer to a range of symbols elsewhere. \n- Now a single link enables transclusion: virtual duplication and transpositioning of pieces of existing publications.\n- Multi-way links enable a great deal of forms, overlaying structure on the sets of symbols.\n\nThe interpretation of these links again being left to the client.\n\nThis, at a minimum, is the essence of the Xanalogical system (of hypertext, hyperstructure) that Ted Nelson describes.\n\nThe goal is to support an Xanalogical addressing space. \n\nThe end objective is an Xanalogical Edit Decision format/protocol that overlays\nor can be incorporated into Web (WWW, as in HTTP/(X)HTML) applications.\n\nPS and other projects\n---------------------\n- permascroll supports permanent addressing of content\n- gate supports HTTP entity handling and messaging\n- scrow supports format (de)muxing, and generic document session handling.\n- translit is an Open Source transliterature demonstration, above projects may\n  want to be compatible.\n\nTechnicalities\n--------------\n1. The first requirement is a permanent address space. \n2. The second a set of meaningful or useful rules for linking. \n\nThe first implies a choice of encoding.\nThe easy way is to shout 'unicode!' and have a solution to map many known scripts to and from a multibyte encoding. \nBut ofcourse then there's are various other forms of publication, \nmany of which (hopefully) have new, non-sequential presentations to contrast\nwith the perception of media as being linear.\n\nSecondly, only if a client knows the document structure is it going to handle \nthat structure in any specific, non-generic way. This is a part that is going to\nhinge more on convention.\n\nOverview\n--------\nA publication consists of data and links.\n\nThere may be different types of data, with different types of address spaces.\n\nAddresses start with three components in the form of local tumbler addresses,\none for the identity of the host, one for the owner, \nand one for the publication itself. These threes are organized in several HTTP\naccess points, such as:\n\n- /node/1.1/1.2/5.3.1\n\nThis identifies a publication, a container for content.\nThe first digit of the first tumbler is the ur-digit, it indicates the\ndocuverse. \n\nEach node may be given a title to use for convenience as label in outlining.\nBut only the last node holds links to content. \n\nContent can be deleted, but nodes cannot. \nEach node has an append-only policy.\nThis means at any time the entire docuverse has a certain width,\nbut since this width is expressed in a difference tumbler, the exact number of\nvirtual positions will not be recorded in this tree.\n\nThe tumbler-component approach gives a node-address two forms of hierarchical relationship. \nOne is intrinsical to tumblers: each component has sub-address lies in between parent + 1.\nThe other is the linking of several addresses as components of a larger address in a hierarchical way.\n\nEach node has a width that is a count of the sub-nodes its links to.\nEach node as a length of positions that is a count of is \n\nThese tumbler adresses are local, meaning they are not in any way distributed.\n\nTODO: implement Entry to link to append-only unicode literal and link space.\n\nDevelopment\n------------\nGIT branches\n    master \n        Main development through 2010, 2011.\n\n\nHTTP service\n------------\n\nNode\n______________________________________________________________________________\n\n**node** is the main structural resource, it organizes metadata to describe\nthe tumbler tree and what is at its leafs.\nTumblers are organized into addresses of 3 components, plus one component for\nthe virtual streams.\n\nAllows application/x-www-form-urlencoded posts to add and update nodes.\n\nThe metadata indicates the number of subdigits called positions, and\nsubcomponents called sub-adresses.\n\n/node/*\n  :mediatype: application/x-mpe-permascroll\n  :access: anonymous, group, user or sysadmin\n  :allow: GET, POST\n  :POST: depends on POST entity. Without 'update' key, create new node by incrementing position below tumbler,\n    and return new node description. With 'update' key, replaces node properties\n    where possible with values from POST entity, but only if update key matches\n    entity tag. (both are typical for /node/).  XXX: could also allow POSTing to\n    /node/ (without address) but with update/ETag key?\n  :GET: \n  :params: \n    --update\n    --title  The title of the node.\n\n/node/[0-9]+\n  :type: Docuverse\n  :access: sysadmin\n  :POST: increment tumbler, create Docuverse and return node description (\\*typical)\n  :GET: ::\n\n    $ curl http://permascroll.appspot.com/node/1 -F title=\"My Docuverse\" \n    [My Docuverse, with 0 positions at 1.1, and 0 sub-adresses]\n\n/node/1.1\n  :type: Node\n  :access: sysadmin\n\n/node/1.1/1\n  :type: Directory\n  :access: group or user\n\n  ::\n\n    $ curl http://permascroll.appspot.com/node/1.1/ -F title=\"My directory\" \n    [My Directory, with 0 positions at 1.1.0.1, and 0 sub-adresses]\n\n/node/1.1/1/1\n  :type: Entry\n  :params:\n    --data  Literal string to use as content.\n\n  ::\n\n    $ curl http://permascroll.appspot.com/node/1.1/1/1.1 -X POST\n    [Untitled Entry, with 0 positions at 1.1.0.1.0.1, and 0 sub-adresses]\n\n  Which is not very useful, but can be appropiate given a title and allows\n  grouping of entry sequences. Normally, ``/upload/`` is used however for\n  creating `Entry` nodes.\n\n/node/1.1~0.1\n  :type: Node/Directory/Entry query\n  :GET: returns a list of node descriptions\n\nContent\n______________________________________________________________________________\n\nThe media type here should be adjusted to the content, but each will need a\nmuxdem implementation to and from any of the standardized content streams.\n\n/content/1.1/1/1\n  :type: Entry\n\n/content/1.1/1/1/1\n  :type: LiteralContent\n\n  Character addresses. Valid range 1.1 - 1.n\n\n/content/1.1/1/1/2\n  :type: LinkContent\n\n  Link addresses. Valid range 2.1 - 2.n\n\n/content/1.1/1/1/3\n  :type: Audio..\n\n/content/1.1/1/1/4\n  :type: Video..\n\nUpload\n______________________________________________________________________________\n\n/upload/1.1/1/1/1\n  :POST: accept and store content, increment tumbler, create Entry and \n    acknowledge new node if successful \n\n  ::\n\n    $ curl http://permascroll.appspot.com/node/1.1/ -F title=\"My directory\" \n    [My Directory, with 0 positions at 1.1.0.1, and 0 sub-adresses]\n\n/content/1.1/1/1/1~0.1\n  :GET: returns contents or range\n\n\nPEDL\n----\n- Petal: permanent edition transmission language\n- PEL, PEDL: Permanent Edit Lists?\n- PDEF: Permanent Edit Definition File?\n\nThis is an preliminary version of an import/export format for Permascroll data.\n\n* The format is a set of operations on documents expressed in generic rules\n  which resemble Xu88 type of xanalogical links. \n\n  Each rule at a minimum has an address (empty rule), \n  ...\n  genericly::\n\n    rule-indent = '-' / '*' / '@'\n    rule-index = *DIGIT '.'\n    rule-indicator = ( rule-ident / rule-index )\n    component-value = tumbler / qname\n    petal-rule = rule-indicator WS [[[[\n            \"type\" WS component-value] \n          \"from\" WS component-value] \n        \"to\" WS component-value] \n      \"at\" WS component-value]\n    \n* The rules apply to an Permascroll Entry, an Xanalogical document, which may\n  have unlimited dataspaces. Permascroll recognizes two: 1. a unicode text dataspace \n  and 2. an link dataspace.\n\n  Most rules translate to a link.\n\n* An entry consists of two extendable data spaces.\n  One holds content, one holds links.\n* Each file holds content/links for one or more entries.\n* Each line is a comment, others are part of an PEDL statement.\n* PEDL statements are strings, prefixed by a leader character sequence.\n  By default the leader is '@'?\n* The following expressions are recognized, statements starting with:\n\n  content\n    the following arguments are HEREDOC strings, and/or location\n    indicators for external content.\n\n    The ``at`` keyword may indicate the intended location of the content,\n    and may serve to make the insert conditional.\n    If the given location is not available, the statement fails.\n    \n  link\n    The expression consists a keyword from ``type, from, to`` and ``at``,\n    follewed by one or more location indicators.\n\n    The keywords may appear in any sequence,\n    and indicate the part of the link the locator belongs to.\n    ``type`` is a special part, that recognizes built-in locators.\n\n    The ``at`` keyword works the same for links as it does for contents.\n\n    This is the default statement, meaning any leader without subsequent \n    statement keyword is interpreted as a link.\n\n  prefix/bind\n    bind address space to a prefix using the ``at`` keyword.\n\n* Contents are loaded from locator, or given in HEREDOC style multiline strings.\n* Locators come in URL form, in tumbler address or span form or in\n  a regular expression/search-string form?\n* Tumbler locators may be abbreviated by binding an address to a prefix.\n\n  - This prefix-notation borrows some from Notation3.\n  - A prefix is a ID followed by ':'.\n  - The ':' prefix is by default bound to the current document (the entry node),\n    any tumbler following it addresses a dataspace/virtual stream of that node.\n\n    Content by default is inserted into that node.\n\n* The type part of a link usually refers to another link that provides an\n  discription of a class of links.\n\n* The Permascroll Link document describes the built-in link types.\n  The root of all link types is 'type', the first linkdoc link at\n  ``1.1.0.1.0.2.0.2.1`` or ``linkdoc:type``.\n\n  Type is built-in and at that address whatever the linkdoc says.\n\n* New link-types are made by linking from :type to any new description.  \n\n  The text in the to set should be a single word and will be converted to \n  link type ID. \n  The link should only contain these parts.\n\nProtocol Layering\n__________________\n* The PEDF receiver is bound to a document.\n  There is a generic receiver and a per-entry receiver.\n\n\n----\n\nFor each publication there is a numbered directory, with\na numbered entry. Each entry links to a measure of data. Having an append-only \npolicy, an immutable, permanent adress is kept for this data.\\ [*]_\n\nThese numbers form the components of an address, one for each node or virtual location.\nThe key point is permanent addressing, thus enabling reuse of content by other systems.\nA permascroll realizes this by an append-only policy. \n\nThis may enable use of some xanalogical constructs, but there are no enfiladics\ninvolved. In a Xanalogical system, linked trees perform a mapping of virtual\naddresses to possibly highly rearranged source data. And in addition enable \ntransclusion and effecient link or endset queries.\n\nFor the Web however, proxies may be convenient to rewrite content for use in such a system.\nUsing EDL and the Transliterature algorithms, Web content can be annotated.\nChanges in the source will invalidate any referring EDL, only manual annotation\ncan track for versions--Docuspheres as submarines on the web.\n\nAdressing is done for discrete characters, and Xanalogical links. \nThese are stored in virtual space 1 and 2, resp.\nEncoding of math formulae and diagrams is not entirely clear.\nBeside literal data, other multimedia data could be adressed.\n\n.. Nodes, Directories and Entries server as a curious, tumbler-addressed\n   phenomenon in the address. These really imply some distributed network\n   addressing scheme. \n\n   Why, a permascroll node might only serve virtual spaces, \n   as if the local filesystem. \n\nDetails\n-------\nTumblers allow hierarchical structures. \n\nThe docuverse starts at 1, and remains 1?\nThere is no registry for (distributed) docuverses.\n1.1 is the first address in the docuverse. \n\nTo address each directory, entry, and virtual position, an address with multiple\ncomponents is needed.::\n\n  \u003cnode\u003e \u003cdirectory\u003e \u003centry\u003e \u003cvirtual .. \u003e\n\nEach address is stored as a node, having one super- and a number of sub-nodes,\nand any number of leafs or sub-components.\n\nXu88.1 span notation applies. Ie. 1~0.1 corresponds to range 1 to 1+1.\n(0-prefixed tumblers denote offset for preceding address, Xu88.1 notation)\n\nAny number of virtual component types may be supported, by specific \nDirectory and Entry types?\n\n.. [*] Deleting content could be accomplished by blanking data on the virtual\n       addresses (with the propert effect of serving blanks, storage could be truncated). \n       \n       A host should probably ignore address ranges, ie. serve everything under its own\n       Node address and only certain, cached or proxied, address ranges for \n       other nodes. \n\nVirtual streams\n---------------\nLiteral content has a simple virtual address range: ``1.0.1~0.1``.\n\nLinks shall need to be kept, space 2. Links have no size.\nImages need an 2D address beneath 3. ``3.0.x-pixels.0.y-pixels``..\n\nUses datastore for unicode entries.\nUses blobstore for large unicode, and image entries.\n\nAt each moment, a v-stream has a total width, or length, which is the result of\nits total occumulated content. Thus **an entry has one or more lengths**, one for each\nof its content streams (3, hardcoded?).\n\nSince in permascroll an entry cannot change, its length and thus its address\nspace is fixed. \n(Entry's may always be inserted in a Channel, though this operation is not\nentirly clear yet and the normal mode would be to append entries to an directory)\n\nSources\n-------\nMailinglists\n\tEntries have text only but often in either some quotable plain text standard or HTML. Prime example of quotation in daily usage.\n\tSometimes binaries may be present. \n\tNot all lists may be available in an indexed form? \nBlogs and other sites with articles\n\tMany CMS's base their identification on the automatic record numbering in the relational database. \n\nBut besides listing external content, creating new corpora is far more interesting. \nThink of bookmarks, replies, quotes. \nHaving permanent adresses: inclusion and edition of previous entries--see Transclusion.\nAlso usefulness in rote-learning, collecting knowledge, keeping journals, to-do or\nshopping lists.\n\n..\n  .. paradox, include all virtual positions in the docuverse\n  .. trans:: 1~0.1\n\n\nHTTP API\n---------\n\nNode \n   - tumbler\n   - base\n   - length\n   - label  \n\nEntryNode\n   - blob id\n   - digests  \n   - size\n   - type  \n\n   char-length\n   pixel-size\n   audio-sampling-rate\n   video-size-duration\n    \n\n- ``1`` first docuverse\n- ``1.1`` first scroll (ie. my bookmarks)\n- ``1.1.0.1`` my first bookmark (three space node type)\n  ``1.1.0.1.0.1~0.23`` title\n  ``1.1.0.1.0.2~0.41`` descr\n  ``1.1.0.1.0.3~0.5`` tags (reference nodes?)\n- ``1.2`` mailing lists \n- ``1.2.432`` some mailing list\n- ``1.2.432.0.1.0.1.543`` some character in some mailing list?\n- ``1.2.432.0.1`` first mailing list message\n- ``1.2.432.0.1.0.1.0.1`` first character in that message\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotmpe%2Fpermascroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdotmpe%2Fpermascroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotmpe%2Fpermascroll/lists"}