Package: exn
Home.exnfrom thedemodossierExonote / ExnWrite and render rich, scriptable, and interactive notesThis project is part of thePyrustic Open Ecosystem.InstallationDemoLatestModulesTable of contentsOverviewWhy not org-mode ?Why use this project ?DemoMarkup languageCommand line interfaceScripting with PythonViewer APIEmbedding GUI programsMiscellaneousInstallationOverviewExnis a lightweight Python application for browsing a dossier of exonotes. Anexonoteisplain textwritten with aneponymousmarkup language inspired byMarkdownand rendered withTkinter(the default GUI library forPython).Interactivitycan be added to an exonote byembedding GUI programswritten in Python with Tkinter. Additionally, all or part of an exonote can be arbitrarily generated usingcustom Python scripts.This application is built with theGaspiumframework and usesSharedandJesthextensively to manipulate data.This project is built on top ofExonote. Solving issues inExonotemeans improvingExn. Check theissues!Dossier of exonotesAdossieris a directory containing exonotes and resources such as attachments and Python source code. At the root of a dossier should be an index file containing an ordered list of exonotes filenames, titles, and their associated tags. The index file is generated automatically by the--buildcommand in the command line (the order is based on the creation timestamp of the exonotes).Exn treats each exonote with the.exnextension as the page of a virtual book, so the graphical user interface of Exn is a metaphor for a book with controls to move from one page to the next or to the previous one.The Search featureExn has a search interface that allows the user to search for exonotes in the dossier by specifying tags, words or a phrase. The search mechanism has an optionalregular expressionmode.SearchinterfaceOn security: run untrusted exonotesThe command line interface exposes two options for running exonotes:OptionDescription-r,--restrict [<filename>]Open a note with low restriction, i.e., block the execution of embedded programs-R,--Restrict [<filename>]Open a note with high restriction, i.e., block executable links and also the execution of embedded programsWhy not org-mode ?Exonote supports codeblocks like in Markdown. Instead of providing the ability to execute codeblocks, which would lead toliterate programminglike inEmacs'org-mode, Exonote would execute a program whose source code isproperly writtenelsewhere by calling a function with arguments.Byproperly writtensource code, I mean a regular Pythonpackagewith tree structure, modularity, Python.pyfile extension, et cetera. Thus, with aminimalistsyntax, one can embed not only a program whose source code is written in a directory inside an exonotes dossier, but also a program whose distributable package is installed in the current Pythonvirtual environment.I thought it would be nice to separate prose and source code and embed a program by simply referencing it with a minimalist syntax the same way an image is embedded in Markdown.This is how an image is embedded in Exonote:@[title](path/to/img.png)This is how a program is embedded in Exonote:${path.to.module:functionOrClass arg1 arg2 "foo bar"}Why use this project ?Despite the existence of interesting note-taking solutions and the storm of AI-powered projects, there are compelling arguments for adopting Exonote and Exn. Let's explore some characteristics and concrete examples.CharacteristicsHere are some characteristics and their consequences:CharacteristicConsequencePlain old text fileSince an exonote is just plain text, you can always use your favorite text editor (Vim, Sublime Text, Visual Studio Code, et cetera) to write your notes. Exonotes are also de facto compatible withVCS.MinimalismExonote's minimalist markup language specification made Tkinter a good candidate to render it, eliminating the need for web-based technology (browser, html, css, et cetera). Hence, we got Exn, a lightweight, cross-platform app to view exonotes.Scripting with PythonPython is one of themost popularprogramming languages in the world. Since people like to tinker with Python, it would be fun to write scripts with this language for personal exonotes.Embed GUI programs written with TkinterTcl/Tkis one of the easiest GUI toolkits to use, unsurprisingly, it's the default solution for GUI programming in Python via Tkinter. In the demo, a working calculator was built with Tkinter and embedded into an exonote.ExamplesThese are few concrete examples of what can be done with Exonote and Exn:create interactive courses;build programming puzzles with levels and backstory;make aproof of concept;use theexonote.Viewerclass to make rich and/or interactive documentation inside another application. Exn itself uses the default viewer in the Exonote library.Whistleblowing and censorship bypass: Due to its nature, a dossier of exonotes is very convenient for disclosing information that can be easily replicated and consumed by people.Decent alternative to a personal website: it is as simple as creating a GitHub repository, upload a dossier of exonote, share the link with readers, then regularly update the contents withgit commit.Note: you can define ablocklistfile in$dossier/.exnto block access to a list of exonotes (filenames). This mechanism with the help of custom scripts, allows the implementation of a system of levels where certain conditions must be met before opening specific exonotes.DemoAdemois available that you can play with. You will need to clone the demo repository, install Exn withpipand then run it without any arguments. By default, it executes the last exonote opened or runs the home page (first exonote referenced in the index).# 1- clone the repository$gitclonehttps://github.com/pyrustic/exn-demo
$cdexn-demo# 2- install exn$pipinstallexn# 3- run exn with zero restriction$exnYou can still run Exn with restriction:# run exn with low restriction$exn-r# run exn with high restriction$exn-RMarkup languageElementDescriptionANCHORCreate an anchor in a specific location of an exonote that can be accessed when its name is appended to the filename of the exonote. Syntax:<anchor_name>ATTACHMENTInsert an asset like an image. Syntax:@[optional text](path/to/assets/resource.png)BOLDMake a text bold. Syntax:*bold*CODESurrounding a word or phrase with double backticks will apply a monospace font to it and also a colored background.CODEBLOCKSame as in MarkdownDINKUSThree asterisks at the start of a blank will be centered and bolded like adinkus.GAPLeave at least one blank line between a group de sentences to create paragraphs.HEADINGAn exonote is made up of sections, which are made up of paragraphs. A section title is the Heading and it a section can have an identifier (section id, A.K.A. sid). A header follows the same pattern as in Markdown. Syntax:# Title of section <section_id>.ITALICApply italic to a text. Syntax:_my sentence_.ITEMUse a hyphen at the beginning of a line, with or without indent, to declare an item of a list.LINKExonote supports link to websites, link to exonotes in the same dossier, link to anchors, and executable links (clicking such link will run a Python function. The documentation is a work in progress. Check the demo.MONOSPACESurround a text with backticks to apply a monospaced font to it.NOTICESurround a text with%to apply a green color to it.PROGRAMReference a function or a view class. Syntax:${path.to.module:functionOrClass arg1 arg2 "arg arg"}STRIKETHROUGHSurround text with~to strikethrough it.TABLECheck the example below.UNDERLINESurround a text with__to underline it.VARIABLEA variable is defined at the beginning of an empty line. This line will not be rendered. The value of a variable can be used to fill in the location placeholder of an attachment or link. Syntax:[variable_name] Value.WARNINGSurround a text with%%to apply a red color to it.This is a table:| Col 1 | Col 2 | Col 3
| val A | val B | val C
| val D | val E | val F
| val G | val H | val INote:you can add a caption to tables, attachments, and views (GUI programs) by written its content in front of a&just under the target element.Example:@[Alt text](path/to/image.png)
& This is a *caption* !Command line interfaceTypeexn -horexn --helpin the command line to display the help text.Usage:$ exn
$ exn <filename>
$ exn <option> [<arg> ...]Options:-b, --build                     Build the index file
-r, --restrict [<filename>]     Open a note with low restriction
-R, --Restrict [<filename>]     Open a note with high restriction
-h, --help                      Show help textBack to topScripting with PythonIt's as simple as referencing a Python function whose module is in the dossier or virtual environment. This Python function must accept a context argument and optionally return a string that will be rendered to where the function was called.Inside the exonote:This is an *exonote*. 
Let's make a call to a Python function here: 
${path.to.module:func arg1 arg2 "args..."}The called function:deffunc(context):print(context.viewer)print(context.arguments)return"Hello World !"Back to topViewer APIThe viewer exposes an API to open a new exonote, refresh the current exonote, render a string to a specific location of the current exonote, scroll the current exonote to a specific location, compute a location index, modify the headings, programmatically read and modify sections, and more.The documentation is a work in progress. Check the APIhere!Back to topEmbedding GUI programsYou can embed GUI views in an exonote by referencing a class that has abuildmethod returning a Tkinter widget. The constructor of this class must accept a context argument.Note:It is recommended to subclass theviewable.Viewableclass to create a view.Inside the exonote:This is an exonote.
Let's embed a view here:
${path.to.module:MyView arg1 arg2}The view:fromviewableimportViewableclassMyView(Viewable):def__init__(self,context):super().__init__()def_build(self):# build the interface of the viewpassBack to topMiscellaneousKeymapFor a smooth user experience, keyboard keys are mapped to certain functions in Exn. For example, pressingFwould activate theFind in Pagefunctionality. PressingHwould open the home page. PressingSwould open the search interface. PressingTwould open the table of contents. PressingF5would refresh the page. Et cetera.Note:Ctrl+Tabwill open theswitcherto allow you to go back to the previously opened exonote.Quick-copyQuickly copy the contents of a codeblock or the address of a link with a right-click over it !AttachmentsFor the moments only images are supported.Path separatorThe separator symbol inside the path to an exonote or asset is the slash/symbol. Also, a path must not start with a separator.FilenamesExn only recognizes files with the extension.exn. Also, to reference a specific filename as a link in an exonote, you must write its path relative to the root of the folder. Filename and Path can be used as synonyms.Example:dossier
    exonote1.exn
    exonote2.exn
    folder
        exonote3.exnThe path toexonote3.exnisfolder/exonote3.exnThe context objectThe context object is a namedtuple instance whose fields are:viewer: theexonote.Viewerinstance which exposes the API to manipulate the representation of the currently displayed exonote;arguments: list of arguments passed to this function in the exonote.ASCII ArtThe ASCII Art at the beginning of the CLI help text is made withpatorjk's TAAGInstallationExniscross platformand versions under1.0.0will be consideredBetaat best. It is built onUbuntuwithPython 3.8and should work onPython 3.5ornewer.For the first time$pipinstallexnUpgrade$pipinstallexn--upgrade--upgrade-strategyeagerBack to top