Introduction
___ .-------.
/ | __________________ | Tokyo |
/ /| | / ___/ ___/ / / __ \ '-------' .-----------.
/ ___ |(__ ) /__/ / / /_/ / ^ | Tuju-Tuju |
/_/ |_/____/\___/_/_/\____/ | '-----------'
| ^
.-------. |
.------.---| Malmö |---------' .-------.
| | '-------' | Korba |
v | ^ '-------'
.--------. | | .-------. |
| Dallas | | '-----| Paris |<-----'
'--------' | '-------'
v
.--------.
| Moscow |
'--------'
Asciio allows you to draw ASCII diagrams in a GUI or TUI. The diagrams can be saved as ASCII text or in a format that allows you to modify them later.
Diagrams consist of boxes and text elements connected by arrows. The elements stay connected when you move them around.
Both GUI and TUI have vim-like bindings, the GUI has a few extra bindings that are usually found in GUI applications; bindings can be modified.
ASCII format is easy and universal, many tools exist to manipulate it and even transform it to other formats.
I’ve used it a lot to draw trees and graphs when my hand drawn pictures were not good enough for presentations. Having the possibility to copy and modify the graphs/diagrams makes it possible to present changes in an attractive way.
History
Asciio was born … as a dare; the cool name was coined at a conference in Oslo.
.------.
.-----------| root |---------.
| '------' | other process
| .------------|-------------.
v | v |
.--. | .--. |
.---'--' | .---'--'---. |
| | | | | |
v | | v v |
.--. | link | .--. .--. |
.--'--' .--------------------'--' '--' |
| | | | |
v | | v |
.--. v | .--. |
'--' .--. | '--' |
'--' | |
'--------------------------'
Asciio is developed, and runs, on both Linux and Windows (cygwin).
Running asciio
$> asciio [file.asciio] # GUI application using Gtk3
$> tasciio [file.asciio] # TUI application
$> asciio_to_text file.asciio # converts asciio files to ASCII
$> text_to_asciio ... # makes an asciio file from text
Command line options
| option | context | |
|---|---|---|
| b | put the input in a box element | text_to_asciio |
| text_separator=s | put the input in a boxed element | text_to_ascioo |
| display_setup_information | verbose setup information | |
| show_binding_override | display binding overrides in terminal | |
| setup_path=s | sets the root of the setup directory | |
| s,script=s | script to be run at Asciio start | |
| p,web_port=s | port for web server | |
| debug_fd=i | debug file descriptor number | |
| add_binding=s | file containing bindings to embedd | |
| reset_bindings | remove all embedded bindings from document | |
| dump_bindings | write the embedded bindings to files | |
| dump_binding_names | display name of embbeded bindings |
Opening Asciio documents from the command line
Asciio Documents and Projects
The Asciio (tabbed) application distinguishes between two file types: individual asciio documents and asciio projects. Understanding this distinction is essential for proper file management.
File Types
Asciio Documents
Asciio documents represent individual diagrams. Each document contains:
- Drawing elements and their properties
- Setup data
Documents are loaded into individual tabs within the application interface.
Asciio Projects
Asciio projects are container that bundle multiple asciio documents together. A project file contains:
- Multiple serialized asciio documents
- Project data specifying tab count and document order
Loading Files from Command Line
Command Line Behavior
Files specified as command-line arguments are processed sequentially. The application automatically detects whether each file is a document or project.
Type Detection Mechanism
File type detection operates through document validation:
- The application attempts to open the file as an asciio project
- Open failure triggers single-document loading
This approach allows transparent handling of both file types without requiring file extension conventions or explicit type specification.
Multiple File Loading
When multiple files are provided via command line:
- Each file is processed independently
- Projects expand into multiple tabs (one per contained document)
- Asciio documents in a tab each
- All loaded files coexist in the same application session
Writing Projects
Project Structure
When saving a project, the application:
- Serializes each open tab’s asciio document
- Generates unique filenames for each document within the archive
- Creates an
asciio_projectdata file containing document count and ordering - Packages all components into a project file
Naming Collision Resolution
During Project Creation
The application implements collision detection when saving projects:
- Documents without titles receive automatic names (
untitled_0,untitled_1, etc.) - Duplicate names trigger automatic suffix generation using random integers (0-9999)
This ensures filesystem-safe uniqueness within the project file.
Save Operations
Project Modified State
The application tracks modifications at two levels:
- Individual document modification (tracked per tab)
- Project-level modification (tab operations, document additions/removals)
File Overwrite Protection
The save mechanism implements defensive overwrite handling:
- Existing filenames trigger confirmation dialogs
- User cancellation aborts the save operation
Application Exit
Modified Content Handling
Application termination with unsaved changes triggers:
- Detection of any modified documents or project structure
- Presentation of save/quit/cancel dialog
Document vs Project Saves
Asciio uses project-level saves during exit. Individual document modifications are captured within the project save operation. You can save individual documents at any time.
Error Handling Behavior
Non-Existent Files
When a non-existent file path is provided on the command line:
- A new empty tab is created
The application launches successfully but the non-existent file produces an empty tab, error is output to the console.
Invalid File Formats
When an existing file contains invalid or corrupted data:
- A new empty tab is created
Error Recovery
Asciio is resilient to bad input:
- Individual file failures do not prevent application launch
- Subsequent command-line files are processed
- Error messages provide diagnostic information to STDERR
Command Line Examples
Single Asciio Document
Command:
asciio diagram.ascii
Behavior:
- Application launches with one document
- no tab is displayed when a single file is loaded
Single Project
Command:
asciio project.asciios
Behavior:
- Application launches with multiple tabs (one per contained document)
- Tab labels reflect individual document names from archive
- Tab order matches the orders of the saved project
Multiple Asciio Documents
Command:
asciio doc1.asciio doc2.asciio doc3.asciio
Behavior:
- Application launches with three tabs
- Each document loads into separate sequential tab
- Tab labels:
doc1.asciio,doc2.asciio,doc3.asciio
Multiple Projects
Command:
asciio project1.asciios project2.asciios
Behavior:
- Application launches with tabs from both projects
- First project’s documents load into initial tabs
- Second project’s documents append to tab bar
- Tab labels reflect individual document names
- Naming collision resolution applies if documents share names
Mixed Asciio Documents and Projects
Command:
asciio header.asciio project.asciios footer.asciio
Behavior:
- Tab sequence:
header.asciio, then project documents, thenfooter.asciio - Project expands into multiple consecutive tabs
- Final tab arrangement reflects command-line order
Project with Document Name Collisions
Command:
asciio project1.asciios project2.asciios
Where both projects contain a document named diagram:
Behavior:
- First
diagramfromproject1.asciioloads with original name - Second
diagramfromproject2.asciioreceives random suffix - Resulting tabs:
diagram,diagram_4721(random number varies) - Collision detection operates at session load time
- Suffix generation prevents tab label conflicts
All Invalid Files
Command:
asciio missing1.ascii0 missing2.asciio missing3.asciio
Behavior:
- Three empty tabs created
- Three error messages to STDERR
- Application remains functional
- User can immediately begin working in empty tabs
- No crash or abnormal termination
Installation
asciio’s is hosted on github
Debian/Ubuntu package
No packages pre-build for distributions yet, work is ongoing.
Manual install on debian based distros.
See the OCI build instruction in Containerfile.
OCI image
user config
A user configuration is copied from ‘repo:OCI/Asciio’ to ‘/root/.config/Asciio/’, it can be modified to suit your needs.
pre-built image
The image is on github
Change <PATH_YOU_WANT_TO_SHARE>, if you want to save your files to your file system, before running the command below.
linux
podman run -it --net=host --env="DISPLAY" --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --volume="$HOME:<PATH_YOU_WANT_TO_SHARE>" ghcr.io/nkh/p5-app-asciio:release asciio
Jypiter notebook
Example of installation and testing.
windows wsl
If using Podman, add github repository to podman in ‘/etc/containers/registries.conf’
[registries.search]
registries = ['ghcr.io']
Install an Xserver in windows. I used VcXsrv and disabled access control.
The IP of Xserv was not correct. Had to use this, to have it report the Windows host virtual IP:
export DISPLAY=$(ip route | grep default | awk '{print $3}'):0
podman run -it --net=host --env="DISPLAY" --volume="$HOME:<PATH_YOU_WANT_TO_SHARE>" p5-app-asciio:release asciio

Windows
In the windows environment, you can use asciio through msys2 or WSL or cygwin.
windows msys2 package
P5-App-Asciio-msys2, Here are the complete packaging and installation instructions.
WSL
The use of WSL is not much different from the Linux environment.However, there are some things that need attention. This link talks about how to connect to the WSL environment and execute GUI programs through remote connections under Windows.
Cygwin
- First install Cygwin.
- Make sure the following components are installed correctly
- x11
- perl
- Gnome
- gun-make
- gcc-g++
- Search for “gcrypt” in all the packages to be installed, and install all the packages that appear.
- Install all dependent modules of asciio
Pay attention when installing perl modules, some may be installed through cpan, but some cannot, and can only be installed manually.
When compiling, the Makefile of several modules has an unrecognized option
-lnsl. removed it when install it manually.
Start asciio by the following method:
startxwin >/dev/null 2>&1 &
export DISPLAY=:0.0
asciio
Interface
Asciio input is from mouse and keyboard bindings, they are defined in a configuration files that you can change.
Asciio’s interface is minimal by design.
keyboard bindings
This is the preferred method, and the fastest. The bindings are vim-like and which make the many bindings much easier to remember. See the Bindings section
mouse bindings
Although work can mostly be done using the keyboard, the mouse is still useful and it’s fast when creating new diagrams. See Working efficiently
popup menus
My least favorite way of using Asciio, it’s slow and cumbersome for most actions. I try to limit the amount of menu and sub menus.
Asciio Tab Management

Overview
Asciio provides a comprehensive tab-based workflow system that allows you to work with multiple documents simultaneously within a single application window. Each tab represents an independent drawing canvas, and you can organize, navigate, and manage these tabs efficiently through a variety of operations.
Bindings: Tab Management
Index
Creating New Tabs
Creating new tabs | Duplicating tabs | Closing tabs
Tab Navigation
Sequential navigation | Direct tab access | Jump to last tab
Tab Organization
Moving tabs | Renaming tabs | Tab label visibility
Project Operations
Opening projects | Saving projects | Reading files into tabs
Application Control
Workflow Tips
Organizing multiple documents | Project management strategy
Handling name conflicts | Maximizing canvas space
Tab Creation and Removal
Creating New Tabs
Create a new empty tab to start a fresh drawing. The new tab is appended to the end of the tab bar and automatically receives focus.
Binding: «t» + «n»
The newly created tab begins with default canvas settings and an empty drawing surface. Tab labels are automatically shown when multiple tabs exist.
Duplicating Tabs
Clone the current tab to create an exact copy of your work. This operation duplicates all elements, their positions, properties, and the current canvas state.
Binding: «t» + «c»
The duplicated tab is created as a new tab with identical content. This is useful for creating variations of a design or maintaining snapshots of work in progress. The cloned tab is independent from the original and modifications to either tab do not affect the other.
Closing Tabs
Close operations are handled directly within each document window. Closing a tab with unsaved modifications triggers a save confirmation dialog. The application prevents accidental data loss by prompting for save actions before tab removal.
When closing the last remaining tab, the application follows its exit procedures, including project-level save prompts if modifications exist.
Tab Navigation
Sequential Navigation
Navigate through tabs in sequential order using forward and backward operations.
Binding: «t» + «t»
Move focus to the tab immediately to the right of the current tab. When viewing the rightmost tab, this operation wraps around to the leftmost tab, creating circular navigation behavior.
Binding: «t» + «Shift+T»
Move focus to the tab immediately to the left of the current tab. When viewing the leftmost tab, this operation wraps around to the rightmost tab.
Direct Tab Access
Jump directly to specific tabs by their position index. Tabs are numbered from 0 to 9, allowing instant access to the first ten tabs.
Binding: «t» + «0» through «t» + «9»
Each number key corresponds to a tab position:
- «t» + «0» focuses the first tab
- «t» + «1» focuses the second tab
- «t» + «2» focuses the third tab
- And so on through «t» + «9» for the tenth tab
If you attempt to access a tab index that doesn’t exist (for example, pressing «t» + «5» when only three tabs are open), the operation has no effect and focus remains on the current tab.
Jump to Last Tab
Quickly navigate to the rightmost tab regardless of current position.
Binding: «t» + «$»
This operation is particularly useful when working with many tabs and you need to access the most recently created tab or the last tab in your workspace.
Tab Organization
Moving Tabs
Reorder tabs within the tab bar by moving them left or right. Tab reordering is purely organizational and does not affect tab content or properties.
Binding: «t» + «h»
Moves the current tab one position to the left in the tab bar. If the current tab is already in the leftmost position, this operation has no effect.
Binding: «t» + «l»
Moves the current tab one position to the right in the tab bar. If the current tab is already in the rightmost position, this operation has no effect.
Tab movement operations preserve tab focus. After moving a tab, it remains the active tab in its new position. If a help tab is visible, the application correctly maintains its position tracking during tab reordering.
Renaming Tabs
Assign meaningful names to tabs for easier identification and organization. Tab names appear in the tab label and help distinguish between multiple documents.
Binding: «t» + «Shift+R»
The rename operation prompts for a new tab name. The provided name updates the tab label immediately. Tab names are preserved when saving projects and are used as filenames when archiving documents within project files.
If multiple tabs share the same name when saving a project, the application automatically applies numeric suffixes to ensure unique filenames within the archive.
Tab Label Visibility
Control the visibility of tab labels to maximize drawing canvas space or show tab organization.
Binding: «t» + «Shift+L»
Tab label visibility toggles between shown and hidden states. When working with a single tab, labels are automatically hidden by default since no navigation is necessary. Opening a second tab automatically shows labels to facilitate navigation.
Hidden labels do not affect tab functionality. All navigation and management operations work identically regardless of label visibility state.
Project Operations
Opening Projects
Load an existing project file into the application. Project files contain multiple documents that are extracted and opened as individual tabs.
Binding: «t» + «e»
The operation presents a file selection dialog. Upon selecting a project file, the application prompts to save any unsaved work in currently open tabs. After confirmation, existing tabs are closed and the project’s documents are loaded.
Each document from the project opens in a sequential tab with its preserved name. Tab order matches the document order stored in the project metadata. The application window title updates to reflect the opened project filename.
If the project file is invalid or corrupted, appropriate error messages are displayed and the operation is aborted.
Saving Projects
Save all open tabs as a unified project file. This operation captures the entire workspace state including all documents and their organization.
Binding: «t» + «w»
The save operation checks for modifications at both the project level (tab operations, additions, removals) and document level (content changes within tabs). If no modifications exist, the operation completes immediately without prompting.
For modified projects, the application uses the current project filename if one exists. If no project filename is associated with the current workspace, or if you explicitly request “save as” functionality, a file selection dialog appears prompting for a filename.
When saving to an existing file, a confirmation dialog asks whether to overwrite the file. Canceling at this point aborts the save operation without modifying any files.
Successful save operations reset all modification flags for both the project and individual documents.
Binding: «t» + «Shift+W»
Force the file selection dialog to appear regardless of whether a project filename already exists. This allows saving the current workspace as a new project file while preserving the original.
Reading Files into Tabs
Load individual document files or project files into the current workspace without closing existing tabs.
Binding: «t» + «r»
The read operation presents a file selection dialog. The selected file is loaded according to its type:
Single Document Files: A new tab is created and the document content is loaded into it. The new tab is appended to the end of the tab bar.
Project Files: All documents within the project are extracted and each opens in its own new tab. These tabs are appended sequentially to the existing tab bar.
Unlike the open project operation, reading files does not close existing tabs or prompt for save operations. This allows you to progressively build a workspace by loading multiple files from different sources.
If a loaded document name conflicts with an existing tab name, a numeric suffix is automatically appended to ensure unique identification.
Application Control
Exiting the Application
Close the application and terminate the session. The exit operation provides safeguards against data loss through modification checking and save prompts.
Binding: «t» + «q»
The application checks for unsaved modifications in both the project structure (tab organization changes) and individual documents (content changes). If modifications exist, a dialog appears with three options:
- Save and Quit: Saves the entire project before exiting. If no project filename exists, a file selection dialog prompts for the destination filename.
- Quit Without Saving: Exits immediately, discarding all unsaved changes.
- Cancel: Aborts the exit operation and returns to the workspace.
Binding: «t» + «Shift+Q»
This operation bypasses all save prompts and modification checks, exiting the application immediately. All unsaved work is discarded without confirmation. Use this operation only when you are certain you want to abandon current work.
Workflow Tips
Organizing Multiple Documents
When working with related documents, use tab reordering to group them logically. Position frequently accessed tabs toward the left for easier access with direct tab shortcuts («t» + «0» through «t» + «9»).
Project Management Strategy
Use the “read file” operation («t» + «r») to incrementally build a workspace from multiple sources. Once your workspace is organized, save it as a project («t» + «w») to preserve the entire configuration for future sessions.
Handling Name Conflicts
When loading multiple projects that contain identically named documents, the application automatically prevents conflicts by appending numeric suffixes. You can rename tabs afterward («t» + «Shift+R») to provide more meaningful distinctions.
Maximizing Canvas Space
When tab names are not needed for orientation, you can hide tab labels («t» + «Shift+L»). Labels can be toggled back on at any time without affecting functionality.
Asciio hides the tab label if only one tab exists.
Unicode support
Asciio supports Unicode is a work under progress; including support for Asian languages, thanks to the co-developer who writes in these languages, but you may need a font that supports them.
https://github.com/be5invis/Sarasa-Gothic/


In the examples above the box is drawn with unicode characters, the box is oversized by design, it shrinks and expands properly.

If you want to align Thai, or Arabic, or Hebrew, under normal circumstances, the default monospaced font of the system is fine. If you find that it cannot be aligned, you can download a font that can align them.

When displayed in exported software, you also need a font that aligns them.
.-----. .----------------.
| abc |----->| สวัสดีเราเคยพบกัน |
'-----' '----------------'
|
|
|
| .---------------.
'-->| שלום, נפגשנו |
'---------------'
|
|
.------------------. |
| مرحبا هل التقينا |<-------------'
'------------------'
Accessing documentation
Asciio’s documentation is available in multiple formats
-
this HTML documentation, generated by mdbook
-
a manpage, available from within Asciio.
There’s also:
-
a bindings list
-
a short help
-
a “user” defined documentation. «H» Add help box
UIs
Asciio offers multiple UIs
- a GUI
- a TUI (under construction)
- a command line interface
There’s even a ticket about a web interface, if you’re a websocket, rpc, minimal interface geek who like Web technology … join us!
GUI

.-------------------------------------------------------------.
| ........................................................... |
| ..........-------------..------------..--------------...... |
| .........| stencils > || asciio > || box |..... |
| .........| Rulers > || computer > || text |..... |
| .........| File > || people > || wirl_arrow |..... |
grid----->......'-------------'| divers > || axis |..... |
| ..................^.....'------------'| ... |..... |
| ..................|...................'--------------'..... |
| ..................|........................................ |
'-------------------|-----------------------------------------'
|
context menu access some commands
most are accessed through the keyboard
Display colors
Access the color group with binding: «zc»
Night Colors
binding: «zcs»
change grid color
binding: «zcg»
change grid background color
binding: «zcg»
Display options
display/hide grid lines
binding: «zg»
display/hide hint lines
binding: «zh»
Displays thicker lines around the selected elements to help you with alignment

Rulers
Access the rule group with binding: «ir»
display/hide ruler
binding: «zr»
TUI

The TUI interface is a work in progress. Drawing graphs in a terminal (without mouse) is more difficult than it seem, I’m actively working on creating better bindings to make as smooth as when using a mouse.
- mouse emulation
- differences
- dialogs
- manpage

Asciio TUI and Vim
You can call Asciio from vim and insert your diagram.
map <leader><leader>a :call TAsciio()<cr>
function! TAsciio()
let line = getline('.')
let tempn = tempname()
let tempnt = tempn . '.txt'
let temp = shellescape(tempn)
let tempt = shellescape(tempnt)
exec "normal i Asciio_file:" . tempn . "\<Esc>"
if ! has("gui_running")
exec "silent !mkdir -p $(dirname " . temp . ")"
exec "silent !cp ~/.config/Asciio/templates/empty.asciio ". temp . "; tasciio " . temp . "; asciio_to_text " . temp . " >" . tempt
exec "read " . tempnt
endif
redraw!
endfunction
CLI
asciio can be used and controlled from the command line.
asciio_to_text
Converts an existing ‘.asciio’ file to ASCII and display it in the terminal
text_to_asciio
Converts files, or text, to asciio elements.
Converting Files
text_to_asciio filename.asciio file [file ...]
The command will create a box elements containing the content each file and save it in ‘filename.asciio’.
Converting text
A text stream is read from STDIN, split into chunks, and converted into asciio elements.
The resulting asciio file is output to STDOUT.
some_command | text_to_asciio > file.asciio
In this mode, text_to_asciio accepts the following options:
| option | default | |
|---|---|---|
| -b | create a box element | create a text element |
| text_separator | perl regular expression used to split | “\n” |
scripting interface
You can create these types of scripts for asciio:
-
a script that modifies a running asciio
- you can send script to it via a POST to asciio web server
- you can, from the UI, choose a script to be run
-
a script in which you can create an asciio, without UI, and insert elements in it
- the result can be saved in an ‘.asciio’ file
- the result can be printed as ASCII in your terminal
See the Scripting section for detailed information.
Stencils
Asciio boxes
Elements

popup menu
You can access some functionality via the popup menu.

auto-shrink
If the text is changed, the size of the box will change to fit.
disable connectors
Enable or disable the possibility to connect to the box.
disable optimize
A standard box had four connectors, Asciio optimizes the arrow routes so they don’t cross the box. You can disable that optimization.
connect inside element borders
Allow connection to be made anywhere inside the element borders , not just the connectors.

rotate box/text

Types
A box
Binding: «ibb» Add box
A box with the frame drawn with Unicode characters
Binding: «iub» Add unicode box
A text
Texts are just boxes without frames.
Binding: «it» Add text
A shrink-box
A box which is already has auto-shrink set
Binding: «ibs» Add shrink box
Asciio if and process boxes
| element | binding |
|---|---|
| Add if box | «iei» |
| Add process box | «iep» |
if-box and process-box

Asciio exec-boxes
An “exec-box” is and object that lets you run an external command and put its output in a box. There are different types of exec-boxes explained below.
Multi command
Binding: «ib» «ctl-e» Add exec box
The simplest exec-box accepts multiple commands, one per line. It will redirect stderr for each command.
Editing the box will let you edit the command.

Verbatim
Binding: «ib» «ctl-v» Add exec box verbatim
This exec-box doesn’t redirect stderr, you can use it for commands that span multiple line or commands that take a multi line input
Editing the box will let you edit the command.

Once
**Binding: «ib» «ctl-o» Add exec box verbatim once
This exec-box will run your commands once, editing the box will let you edit the command’s output.

Add line numbers
Binding: «ib» «ctl-l» Add line numbered box
This is an example of a custom stencil which will add line numbers to your input.

Examples
Using previously generated output
If you already have text in a file you can use ‘cat your_file’ as the command.
Tables
tbd: Command: …
+------------+------------+------------+------------+
| input_size ‖ algorithmA | algorithmB | algorithmC |
+============+============+============+============+
| 1 ‖ 206.4 sec. | 206.4 sec. | 0.02 sec. |
+------------+------------+------------+------------+
| 250 ‖ - | 80 min. | 2.27 sec. |
+------------+------------+------------+------------+
FIGlet
Figlet generates large letters out of ordinary text.

You can specify a font with the -f option.
$ ls /usr/share/figlet/
646-ca.flc 646-hu.flc 646-se2.flc big.flf lean.flf smslant.flf
646-ca2.flc 646-irv.flc 646-yu.flc block.flf mini.flf standard.flf
646-cn.flc 646-it.flc 8859-2.flc bubble.flf mnemonic.flf term.flf
646-cu.flc 646-jp.flc 8859-3.flc digital.flf moscow.flc upper.flc
646-de.flc 646-kr.flc 8859-4.flc frango.flc script.flf ushebrew.flc
646-dk.flc 646-no.flc 8859-5.flc hz.flc shadow.flf uskata.flc
646-es.flc 646-no2.flc 8859-7.flc ilhebrew.flc slant.flf utf8.flc
646-es2.flc 646-pt.flc 8859-8.flc ivrit.flf small.flf
646-fr.flc 646-pt2.flc 8859-9.flc jis0201.flc smscript.flf
646-gb.flc 646-se.flc banner.flf koi8r.flc smshadow.flf
For example, we want to specify this font: slant

This is the exported effect:
.-----------------------------------.
| _ _ _ |
| / \ ___ ___ (_)(_) ___ |
| / _ \ / __| / __|| || | / _ \ |
| / ___ \ \__ \| (__ | || || (_) | |
| /_/ \_\|___/ \___||_||_| \___/ |
| |
'-----------------------------------'
.------------------------------------.
| ___ _ _ |
| / | _____ _____ (_)(_)____ |
| / /| | / ___// ___// // // __ \ |
| / ___ | (__ )/ /__ / // // /_/ / |
| /_/ |_|/____/ \___//_//_/ \____/ |
| |
'------------------------------------'
Diagon
Diagon transforms markdown expressions into an ascii-art representation.

Mathematical Expressions

File Tree
Use exec verbatim box to input multiple lines.


plantuml
Asciio arrows
| element | binding |
|---|---|
| Add arrow | «ia» |
| Add Unicode arrow | «iua» |
| Add angled arrow | «iA» |

wirl-arrow
Rotating the end clockwise or counter-clockwise changes its direction.

multi section wirl-arrow
A set of whirl arrows connected to each other.

angled-arrow and axis

Note that an axis doesn’t connect.
Connecting lines
A specialized wirl-arrow with no head nor tail.
| element | binding |
|---|---|
| Add ASCII line | «il» |
| Add Unicode line | «iL» |
| Add Unicode bold line | «i+Alt-l» |
| Add Unicode double line | «i+Shift+Alt-l» |

Non connecting lines
A specialized wirl-arrow with no head nor tail and auto-connection turned off, it’s often used to draw the table in the crossing mode.
| element | binding |
|---|---|
| Add ASCII non-connecting line | «ik» |
| Add Unicode non-connecting line | «iK» |
| Add Unicode non-connecting bold line | «i+Alt-k» |
| Add Unicode non-connecting double line | «i+Shift+Alt-K» |
ascii line
----------------------.
|
|
|
|
|
unicode line
─────────────────────────╮
│
│
│
│
│
unicode bold line
━━━━━━━━━━━━━━━━━━━━━━━┓
┃
┃
┃
┃
unicode double line
═══════════════════════════╗
║
║
║
║
║
Example of non-connecting lines in crossing mode
╔═════╦═════╦══════╦═════╦════╦═════╗
║ ║ ║ ║ ║ ║ ║
╠═════╬═════╬══════╬═════╬════╬═════╣
║ ║ A ║ ║ B ║ ║ ║
╠═════╬═════╬══════╬═════╬════╬═════╣
║ ║ C ║ ║ ║ ║ ║
╠═════╬═════╬══════╬═════╬════╬═════╣
║ ║ ║ ║ ║ D ║ ║
╠═════╬═════╬══════╬═════╬════╬═════╣
╚═════╩═════╩══════╩═════╩════╩═════╝
Wirl arrow dynamic configuration
The wirl arrow can be dynamically configured by using the keyboard bindings. Some configuration can be done via the popup menus but we are working eliminating them in favor of keyboard bindings.
The keyboard bindings can have changed, best is to check them in the default_bindings.pl configuration file.
You can also define your own bindings.
Changing the arrow type
binding: << e >> + << w >> + chose the arrow type
Controlling the connectors
binding: << a >> + chose the connection command
-
start enable connection
-
start disable connection
-
end enable connection
-
end disable connection
-
enable diagonals
-
disable diagonals
-
Start flip enable connection
-
End flip enable connection
changing the arrow connector
binding: << a >> + << c >> + (<< s >> or << e >>) + chose the arrow connector
- << a >> group ‘arrow’
- << c >> sub group ‘connector’
- << s >> sub group ‘start_connector’
- << e >> sub group ‘end_connector’
fixed connector shape
A single character will be used as the connector regardless of the arrow geometry
dynamic connector shape
A set of character that will be used depending on the arrow geometry
RIGHT DOWN LEFT UP 45 135 225 315
[ ['-', '|', '-', '|', '/', '\\', '/', '\\'] ],
Pseudo-connectors
Pseudo-connectors are a one-glyph-text boxes, used by git mode for example, which can also be used to add connectors to user-created groups.
- create a pseudo-connector
- change its glyph if necessary
- place it
- group all your elements
pseudo-connector with 4 “optimized” connectors
| Binding | Connector |
|---|---|
| o | «ic» |
| * | «iC» |
pseudo-connector with one connector
Use a “center connect box”

Using the character under the current cursor to Create a “center connect box”. Visually, this connector looks like it is one piece with the underlying element.

Example

Box connectors
It is possible to add custom connectors when creating a box stencil, see setup/Asciio for the default stencils.
create_box
(
NAME => 'rabbit paw',
TEXT_ONLY => <<'TEXT'
(\_/)
(O.o)
/>
TEXT
,
RESIZABLE => 0,
WITH_FRAME => 0,
DEFAULT_CONNECTORS => 0,
CONNECTORS => [[2, -1, -1, 2, -1, -1, 'paw']]
),
CONNECTORS
[ # An array of connector
[
2, # X coordinate
-1, # percentage of width, -1 to disabe
-1, # offset added to position if perventage is used
2, # Y coordinate
-1, # same as above for Y
-1, # same as above for Y
'paw' # connector name
],
[
# next connector
...
],
]
The box element class also has these functions:
- add_connector, dynamically add connector
- remove_connector, by name
Example

Asciio shapes
You can add triangles, rombus, and elipses via the popup menu or use the bindings below:
| element | binding |
|---|---|
| Add rhombus | «ir» |
| Add ellipse | «ie» |

Asciio image box
The purpose of an image box is to have a background image; it’s ideal as a background when creating ASCII Art in Pen Mode.
- Image boxes have grayscale and transparency settings
- Images aren’t exported instead a text placeholders will be exported

Bindings
Prefix: All operations require pressing «I» to enter the image Box group.
| action | binding |
|---|---|
| Enter image box group | «I» |
| All bindings |
Create an image box from a file
| action | biding |
|---|---|
| inserted from file | «i» |

Image box operations
Image boxes, like ordinary boxes, support resizing and moving.

image box visual controls sub group
| action | binding |
|---|---|
| rendering control | «<c» |
| action | bingding |
|---|---|
| increase gray scale | «g» |
| decrease gray scale | «G» |
| increase alpha | «a» |
| decrease alpha | «A» |
| revert to default | «o» |

Freezing image boxes
Bindings:
| action | binding |
|---|---|
| freeze to background | ’«f»` |
| thaw | ’«t»` |
Frozen image boxes
- can’t be resized
- can’t be moved
- are put in the background
- they can’t be deleted if frozen and in the background, thaw to delete

Copy and paste the image from the clipboard
Under Linux system, we need to install the xclip tool.
Copy an image to the clipboard through one of the following commands:
- If the image is in
PNGformat then use the following command
xclip -selection clipboard -t image/png -i image.png
Only PNG format is supported.
Under the Windows system, we can directly use the system function to copy a
picture.
Use Ctrl+v directly in the canvas to paste the image into the canvas,
and it will automatically create an image box.

verbatim objects
Text elements with ASCII art or normal text. Asciio has as set of verbatim elements in its stencils which can be accessed via the popup menu, or you can add a binding if you use them often. The element’s text can be edited. You can also use any Ascii-art/Text you have in a file via an exec-box.

___________
1 //////|\\\\\\
2 '.-----------.'
3 | ___ |
4 (\_/) Zzz | [] | | [] | (\_/)
5 (-.-) |____|_|____| (o.o)
6 (> <) (> <)
7
8
9
0
scales
Simple text elements representing scales/rulers that you can use to scale or align, see hints, your elements.
1 1234567890
2
3 1___5____0____5____0____5____0____5____0____5____0
4
5
6
7
8
9
0
User stencils
You can create stencils that you are going to reuse, details of how to do it in the best way can be found in the Configuration section.
Here are three examples:
integrating Asciio and ditaa (third party example)
There was a page (Corn Empire) where a user detailed how to make an integration.
That page is not online anymore, I modified a copy for this documentation.
If you are the original author please contact me so I can give you credit.
Introduction
You found this page because you are looking for more information on installing asciio and ditaa, and then modifying asciio to better interact with ditaa. Well you came to the right place. This guide will take you step-by-step through installing both tools, and modifying asciio to output diagrams to ditaa.
Modifying asciio
Make yourself familiar with ditaa and asciio, you may see the benefit of outputting asciio text files that are compatible with ditaa without modification. Or better yet, generate your diagrams for you when you save :) . This section will explain how to do all of that and more!
Adding in a Ditaa Stencil
You will need to create a new stencils file to create boxes and arrows that are compatible with ditaa (you could optionally modify the standard files if you will only use asciio for ditaa purposes). I got the idea for the modifications from here: http://strawp.net/archive/geeking-out-with-diagrams-in-ascii/
A Standard Box
Go to the App/Asciio/setup/stencils (in the /usr/share/perl5/ or /usr/share/perl/5.10.0/) directory, and find the asciio file. Using for favourite editor, copy and paste the standard box code into a new file called ditaa. Then make the following changes to the standard box code in this new file:
To change the corners, modify line 14/33 and change . to + and modify line 17/36 and change ' to +.
Then modify lines 5 and 7 in the same way. Replace the . with + and the ' with +.
Or you could optionally just copy and paste the completed code below (the $VAR1 = [ is only needed once, and just starts off the file, the ]; at the end of the block, ends the file. All bless calls should be between these lines) :
$VAR1 = [
bless( {
'HEIGHT' => 3,
'TEXT' => '+---+
| |
+---+',
'NAME' => 'ditaabox',
'WIDTH' => 5,
'TEXT_ONLY' => '',
'TITLE' => '',
'BOX_TYPE' =>
[
[TRUE, 'top', '+', '-', '+', TRUE, ],
[FALSE, 'title separator', '|', '-', '|', TRUE, ],
[TRUE, 'body separator', '| ', '|', ' |', TRUE, ],
[TRUE, 'bottom', '+', '-', '+', TRUE, ],
] ,
'EDITABLE' => 1,
RESIZABLE => 1,
X_OFFSET => 0, Y_OFFSET => 0,
}, 'App::Asciio::stripes::editable_box2' ),
];
Add Rounded Box
But why stop there? How about we add in a nice ditaa rounded box. Add this code to the ditaa stencil file just below our modified box code:
bless( {
'HEIGHT' => 3,
'TEXT' => '/---\\
| |
\\---/',
'NAME' => 'roundedbox',
'WIDTH' => 5,
'TEXT_ONLY' => '',
'TITLE' => '',
'BOX_TYPE' =>
[
[TRUE, 'top', '/', '-', '\\', TRUE, ],
[FALSE, 'title separator', '|', '-', '|', TRUE, ],
[TRUE, 'body separator', '| ', '|', ' |', TRUE, ],
[TRUE, 'bottom', '\\', '-', '/', TRUE, ],
] ,
'EDITABLE' => 1,
RESIZABLE => 1,
X_OFFSET => 0, Y_OFFSET => 0,
}, 'App::Asciio::stripes::editable_box2' ),
Add ditaa Arrows
The asciio arrows don’t jive well with ditaa. You can add this in the ditaa stencil file, it is based on the whirl arrow:
bless({
'NAME' => 'ditaa_arrow',
'HEIGHT' => 6,
'WIDTH' => 17,
'POINTS' => [[16,5]],
'SELECTED' => 0,
'EDITABLE' => 1,
'ALLOW_DIAGONAL_LINES' => 0,
'POINTS_OFFSETS' => [[0,0]],
'DIRECTION' => 'down-right' ,
'ARROW_TYPE' =>
[
['origin', '', '*', '', '', '', TRUE],
['up', '|', '|', '', '', '^', TRUE],
['down', '|', '|', '', '', 'v', TRUE],
['left', '-', '-', '', '', '<', TRUE],
['upleft', '|', '|', '\\', '-', '<', TRUE],
['leftup', '-', '-', '\\', '|', '^', TRUE],
['downleft', '|', '|', '/', '-', '<', TRUE],
['leftdown', '-', '-', '/', '|', 'v', TRUE],
['right', '-', '-','', '', '>', TRUE],
['upright', '|', '|', '/', '-', '>', TRUE],
['rightup', '-', '-', '/', '|', '^', TRUE],
['downright', '|', '|', '\\', '-', '>', TRUE],
['rightdown', '-', '-', '\\', '|', 'v', TRUE],
['45', '/', '/', '', '', '^', TRUE, ],
['135', '\\', '\\', '', '', 'v', TRUE, ],
['225', '/', '/', '', '', 'v', TRUE, ],
['315', '\\', '\\', '', '', '^', TRUE, ],
],
'ARROWS' =>
[
bless(
{
'HEIGHT' => 6,
'STRIPES' =>
[
{'TEXT' => '|
|
|
|
|
\'',
'HEIGHT' => 6,
'Y_OFFSET' => 0,
'WIDTH' => 1,
'X_OFFSET' => 0}
,
{
'TEXT' => '--------------->',
'HEIGHT' => 1,
'Y_OFFSET' => 5,
'WIDTH' => 16,
'X_OFFSET' => 1
}
],
'WIDTH' => 17,
'END_X' => 16,
'ARROW_TYPE' =>
[
#name: $start, $body, $connection, $body_2, $end
['origin', '', '*', '', '', '', TRUE],
['up', '|', '|', '', '', '^', TRUE],
['down', '|', '|', '', '', 'v', TRUE],
['left', '-', '-', '', '', '<', TRUE],
['upleft', '|', '|', '\\', '-', '<', TRUE],
['leftup', '-', '-', '\\', '|', '^', TRUE],
['downleft', '|', '|', '/', '-', '<', TRUE],
['leftdown', '-', '-', '/', '|', 'v', TRUE],
['right', '-', '-','', '', '>', TRUE],
['upright', '|', '|', '/', '-', '>', TRUE],
['rightup', '-', '-', '/', '|', '^', TRUE],
['downright', '|', '|', '\\', '-', '>', TRUE],
['rightdown', '-', '-', '\\', '|', 'v', TRUE],
['45', '/', '/', '', '', '^', TRUE, ],
['135', '\\', '\\', '', '', 'v', TRUE, ],
['225', '/', '/', '', '', 'v', TRUE, ],
['315', '\\', '\\', '', '', '^', TRUE, ],
],
'END_Y' => 5,
'DIRECTION' => 'down-right'
}, 'App::Asciio::stripes::wirl_arrow' ),
],
}, 'App::Asciio::stripes::section_wirl_arrow' ) ,
Add Colours and Special Shape Codes
All of the above will give you the core functionality of ditaa into asciio. But what about some basic colour tags, and shape codes. I’ve created a special stencil file for those. You can copy this below, and place it in a file called ditaatags next to the asciio stencil file.
my @ascii =
(
'shapes/document' => <<'EOA',
{d}
EOA
'shapes/storage' => <<'EOA',
{s}
EOA
'shapes/input_output' => <<'EOA',
{io}
EOA
'shapes/tr' => <<'EOA',
{tr}
EOA
'shapes/o' => <<'EOA',
{o}
EOA
'shapes/mo' => <<'EOA',
{mo}
EOA
'shapes/c' => <<'EOA',
{c}
EOA
'colours/Red' => <<'EOA',
cRED
EOA
'colours/Blue' => <<'EOA',
cBLU
EOA
'colours/Pink' => <<'EOA',
cPNK
EOA
'colours/Black' => <<'EOA',
cBLK
EOA
'colours/Green' => <<'EOA',
cGRE
EOA
'colours/Yellow' => <<'EOA',
cYEL
EOA
) ;
my @boxes ;
use App::Asciio::stripes::editable_box2 ;
for(my $ascii_index = 0 ; $ascii_index < $#ascii ; $ascii_index+= 2)
{
my $box = new App::Asciio::stripes::editable_box2
({
TEXT_ONLY => $ascii[$ascii_index + 1],
EDITABLE => 1,
RESIZABLE => 1,
}) ;
$box->set_box_type([map{$_->[0] = 0; $_} @{$box->get_box_type()}]) ;
$box->shrink() ;
$box->{'NAME'} = $ascii[$ascii_index] ;
push @boxes, $box ;
}
[@boxes] ;
Once these have been added, you need to modify the setup.ini file to point to the new stencils. To do that, run the following commands:
cd .. sudo vim setup.ini Where it says ‘stencils/divers’, add on the next line, ‘stencils/ditaa’, and then ‘stencils/ditaatags’,. Your new file should look like this:
{
STENCILS =>
[
'stencils/asciio',
'stencils/computer',
'stencils/people',
'stencils/divers',
'stencils/ditaa',
'stencils/ditaatags',
],
ACTION_FILES =>
[
'actions/align.pl',
'actions/clipboard.pl',
'actions/debug.pl',
'actions/new_elements.pl',
'actions/elements_manipulation.pl',
'actions/file.pl',
'actions/mouse.pl',
'actions/colors.pl',
'actions/unsorted.pl',
'actions/animation.pl',
'actions/context_menu_multi_wirl.pl',
'actions/context_menu_box.pl',
'actions/context_menu_rulers.pl',
],
HOOK_FILES =>
[
'hooks/canonize_connections.pl',
],
ASCIIO_OBJECT_SETUP =>
[
'asciio_object/basic.pl',
],
IMPORT_EXPORT =>
[
'import_export/ascii.pl',
'import_export/perl.pl',
'import_export/png.pl',
],
}
Modifying Saving
It is nice to generate a text file of the data in case you need to make further tweaks before running it through ditaa. It is also required if you want to generate .pngs on the fly of your diagrams.
Go to App/Asciio/setup/actions and load up the file.pl file.
On line 65, replace the original saving code with the following:
#$new_title = $self->save_with_type($elements_to_save, $type, $file_name) ;
## Regardless of previous stuff, save one asciio file and one asciio.<ext>.txt ascii file
## Courtesy of Strawp of http://strawp.net/archive/geeking-out-with-diagrams-in-ascii/
$new_title = $self->save_with_type($elements_to_save, "asciio", $file_name) ;
$new_title = $self->save_with_type($elements_to_save, "txt", $file_name.".txt") ;
## Run ditaa to convert text version into nice copy
## Use this if you have Proc::Background available. Otherwise, use the system call below.
#use Proc::Background;
#my $proc1 = Proc::Background->new("c:\\bin\\ditaa.bat \"".$file_name.".txt\" \"".$file_name.".png\"");
#my $proc1 = Proc::Background->new("java -jar /home/thomas/programs/ditaa/ditaa0_9.jar \"".$file_name.".txt\" \"".$file_name.".png\"");
## This call converts while saving. Slows down save time. Replace the path below with your path to ditaa.jar
## You can add any special parameters here that you commonly use as well.
## Use this command if you unzipped the .jar file
system("java -jar /home/thomas/programs/asciio-ditaa/ditaa0_9.jar \"".$file_name.".txt\" \"".$file_name.".png\"");
## Use this command if you installed the .deb.
#system("ditaa \"".$file_name.".txt\" \"".$file_name.".png\"");
Using the New Setup
Now that you have made all of your tweaks, you are ready to start using your asciio/ditaa combo! Start by making a simple diagram. Here is one below:
Notice when you save this file for the first time:
Several files are created at first. As well as our rendered image.
Now, lets spice it up with some colour and some shapes. Use the right click menu to add the document tag to each of the items labelled document. To do this you will need to:
Right click and select stencils → ditaatags → shapes → document Drag the {d} over the first document. I suggest you group any shapes, and shape modifiers by using CTRL+G once you set them up. If you do this, all of your pieces will move around if you have to tweak your image. Grouping involves selecting each item (hold shift while clicking each item), then press CTRL+G on your keyboard. This will cause this group of items to change background colour, and if you move one item, they will all move together. (You can ungroup by pressing CTRL+U) Add another {d} to the other document. If your item is falling behind the item you want, you can press CTRL+F to bring it to the foreground. Or CTRL+B to push the item on top into the background. Now lets add some colour. Right click, and add some colour tags to the documents. As you save, you will notice the .png updates automatically.
Here is your final work of art:
Troubleshooting
asciio Won’t Load File I’ve noticed that if you modify the stock asciio shapes (either through the gui itself, or in the stencils file) often times if you launch asciio, and then try to load a file with altered shapes, it will fail to load. It generates this output in the terminal:
thomas@thomas-desktop:~/programs/asciio-ditaa$ asciio Using setup directory:‘/usr/share/perl5/App/Asciio/setup/’ running action ‘Open’. load_file: can’t load file ‘/home/thomas/programs/asciio-ditaa/saves/test’: Unrecognized character \x8E in column 23827 at (eval 105) line 372. You can still get asciio to open, you just need to launch it with the file you want to load. So either launch it by typing something like:
thomas@thomas-desktop:~/programs/asciio-ditaa$ asciio /home/thomas/programs/asciio-ditaa/saves/test Using setup directory:‘/usr/share/perl5/App/Asciio/setup/’ running action ‘Open’. Or launch from your file manager. In my case, Nautilus:
asciio Forgets Where I Saved
When loading asciio for the first time, and saving, I find that asciio forgets where I saved the document. It always returns to the original launching location.
To avoid this, I’d recommend that after your first save, you reopen asciio by using one of the two procedures mentioned above. This will allow it to remember where you are working, and the Save function will work correctly.
Editing elements text and attributes
Asciio has two editing mode, Dialog and Inline, the default mode is Dialog.
Dialog editing
Binding: Return, double-click
Asciio opens a dialog which lets you set:
- boxing options
- title
- text

Inline editing
Binding: Return, double-click
In this mode you can only edit the text.

Alternate editing
You can edit in the other mode with these bindings:
- ctl + Return
- ctl + double-click
Changing mode
To change the mode during the session use:
Binding: «zi»
Setting the editing mode in the user configuration
EDIT_TEXT_INLINE => 0,
EDIT_TEXT_INLINE => 0Indicates that the default editing mode isDialog editingEDIT_TEXT_INLINE => 1Indicates that the default editing mode isInline editing
Markup mode
We can use color in asciio, But if exported, the color information will be lost. The markup mode adds marks in the chart, and these marks can be retained when exporting, so that special effects can be displayed in some specific software.
Use markup mode
To use marks in the chart, turn on this option in the configuration.The markup enable variable is the basic attribute of the chart and cannot be changed at runtime.
USE_MARKUP_MODE => 'zimwiki',
If you do not need to use any markup mode, please keep this variable empty.
USE_MARKUP_MODE => '',
Currently, only zimwiki format markup is supported, then markdown format or pure html format may be supported in the future.
zimwiki format description
Edit marks
zimwiki markup mode currently supports text editing of box type elements.Just place the text in the middle of the marks.
Currently supports 5 types of markers:
- bold
<b>something</b>
- underline
<u>something</u>
- double underline
<span link="https://github.com/nkh/P5-App-Asciio">link name</span>
- strikethrough
<s>something</s>
- italics
<i>something</i>
This is what it looks like in Asciio:

This is the effect in inline editing mode:

Marks can only be valid for a single line, not multi lines.
Marks support nesting:

Although this function is supported, it is not recommended to use it in this way, and it does not make much sense
Export
Normally, when exporting to ascii, you will get the following text
Binding: «ctl-e» «shift-Y» «Y»
.----------. .---------------. .-----------. .---------------.
| italics | | strikethrough | | underline | | asciio github |
'----------' '---------------' '-----------' '---------------'
Currently, an export format is also supported, and the mark up character is added, which can be recognized by zim.
Binding: «ctl-shift-E»
.----------. .---------------. .-----------.
| //italics// | | ~~strikethrough~~ | | __underline__ |
'----------' '---------------' '-----------'
In the zim environment, they will be rendered like this:

Working efficiently
You can do a lot of thing with just the mouse and the popup menus but that would be a mistake, keyboard bindings are much faster and more efficient, including moving elements around.
The mouse shines when quick-linking elements, they allow you to create a base diagram fast but editing and fine tuning goes faster with the keyboard or keyboard + mouse.
Learn the keyboard bindings, they are a very good way to use Asciio.
Keyboard
Asciio has many bindings which let you work effectively, a list of all the bindings can be found in the Bindings section.
| Example |
|---|
| action | binding |
|---|---|
| insert a box | ibb |
| resize it | 2, 4 |
| move it | hjkl/Arrows |
| insert a new box | ibb |
| insert an arrow | ia |
| connect other box | Alt+A, hjkl/Arrows |
| escape arrow end mode | Escape |
| select both boxes | V |
| align them | A, t |

Mouse
Quick link
Binding: «alt-left-mouse-click»
- create a box is nothing is selected
- if only a box is selected, create a new box and connect to it
- if a box is selected and mouse over a box, connect them
- if multiple boxes are selected, create a box and connect to all boxes

Quick links will use the current attributes, see: Changing element attributes.
Orthogonal quick link
Binding: «shift-alt-left-mouse-click»
Works like a quick link but, when necessary, will create a box that is either aligned horizontally or vertically with the first element of the selection (whichever is closest)

Orthogonal quick links will use the current attributes, see: Changing element attributes.
Quick copy
Binding: «alt-shift-left-mouse-click»
Copy the current selection and move it to another position, see cloning

Quick arrow
Binding: «ctl-alt-mouse-motion»
If an arrow is selected, move its end point with the mouse.

Quick section
Binding: «ctl-alt-left-mouse-click»
- If a wirl arrow is selected, add section.
- if another element is selected, add new arrow
You can then move the its end point with the mouse. releasing «ctl» lets you move the mouse to another position for a new section.

Quick box and section
You can quickly create boxes and section by combining quick link and quick section.
- «alt-left-mouse-click», create a box
- «ctl-alt-left-mouse-click», link the box to a new arrow
- move mouse
- «ctl-alt-left-mouse-click», add a section
- move mouse
- «ctl-alt-left-mouse-click», add a section
- move mouse
- «alt-left-mouse-click», connect last section to new box

Cloning
You can activate the cloning feature to quickly add elements.
Binding: c
Cloning Base Elements
When you initiate cloning without any elements selected, Asciio allows you to clone one of the base elements.
| Element | Binding |
|---|---|
| Box | b |
| Text | t |
| Wirl Arrow | a |
| Angled Arrow | A |

Cloning the Selection
You can also clone a set of elements that have been selected. The bindings for the base elements are still applicable.

Hint Lines
If hint lines are enabled, additional lines are displayed to indicate the limits of the elements being cloned. You can toggle the hint lines on and off.
Binding: h

Stencils and “Drag And Drop”
Stencils
You can access Stencils via “Drag and Drop”.
Asciio has bindings to open stencils in a separate instance
Start Binding: is
Then uses one of the following keys:
| bindings | action |
|---|---|
| s | select from user stencils in $HOME/.config/Asciio/stencils/ |
| d | open stencil ‘default_stencil.asciio’ from current directory |
| a | select stencil from your computer |
| 0 | open ‘elements.asciio’ from $HOME/.config/Asciio/stencils/ |
| 1 | open ‘computer.asciio’ from $HOME/.config/Asciio/stencils/ |
| 2 | open ‘people.asciio’ from $HOME/.config/Asciio/stencils/ |
| 3 | open ‘buildings.asciio’ from $HOME/.config/Asciio/stencils/ |
user stencils
User stencils are plain Asciio files.
The distribution contains a few asciio stencils in “setup/Stencils/*.asciio”, copy the ones you want to your $HOME/.config/Asciio/stencils.
You can create a new stencil directly from the file picker, just type the name of the new stencil and open it.
Drag and Drop
Binding: control + left click + drag
| Type | From | To |
|---|---|---|
| Asciio elements | Asciio | Asciio |
| Asciio elements | Asciio | text applications |
| Text | text applications | Asciio |
| URLs | URL aplications | Asciio |

Changing element attributes
Element attributes control how elements are rendered.
Example attributes:
- character to use to draw a box
- ASCII or Unicode characters
- filled shapes or not
- …
Using the context menu in the GUI
Only one element attributes can be changed.

Using the keyboard bindings
Multiple elements can be selected and modified.
Binding:
- «e» enters the element operation group
- «?» sub group for the element you want to change

Copy-Paste attributes to other elements
Also under the element operation group, there are two operations:
Copy the attributes from an element
Select one element then :
Binding:
- «e» enters the element operation group
- «c» copy the attributes
Paste the attributes
Select one or more element then :
Binding:
- «e» enters the element operation group
- «p» paste the attributes

Paste the control attributes
Select one or more element then :
Binding:
- «e» enters the element operation group
- «Shift+P» paste the control attributes

The control attributes of the element are as follows:
- AUTOCONNECT_DISABLED
- OPTIMIZE_DISABLED
- CROSSOVER_DISABLED
- NOT_CONNECTABLE_START
- NOT_CONNECTABLE_END
- ALLOW_BORDER_CONNECTION
- AUTO_SHRINK
- RESIZABLE
- EDITABLE
interactive wirl arrow
The following bindings make it easy to interactively work with a wirl arrow:
Binding:
- «Ctrl+Alt+mouse-1» Wirl arrow add section
- «Ctrl+Alt+d» Wirl arrow insert flex point
- «Ctrl+Alt+motion» Arrow to mouse
They will used the currently copied appearance and control properties.


Mouse Quick link and Orthogonal quick link
See: mouse
Quick links and Orthogonal links use the current appearance properties.

Export/Save
Asciio format
The default format asciio uses when not saved in one of the other supported formats.
This is the format that allows you to reload your diagram as objects and continue editing it.
Asciio embedded in a PNG file
You can save your asciio document as a PNG, it will be recognized by image viewers; that also allows you to have a preview in your file manager.
You need to give the .pnge extension to the file you save (please note the final ‘e’), this lets asciio know what you want to do. Your file will have the .png extension.
When opening a PNG file, asciio looks for its data and opens the file if it’s present.

PNG
Asciio export directly to PNG.
Save your file with a .png extension.
it will save the current display from 0,0 to the extent of the elements in the diagram plus one row and one line.
Exporting to ASCII
You can export to a file in ASCII by using a ‘.txt’ file extension.
You can also export the selection, in ASCII, to the Primary clipboard.
SVG
Asciio doesn’t export directly to SVG but uses a text to SVG application like Goat or SvgBob.
Create a diagram in Asciio

Export it to SVG
Further process the SVG
I used fskpf web site to generate a pseudo hand-drawn graph out of it

The svg2roughj sproject is here
JSON
asciio has an experimental JSON exporter and no JSON importer.
I’m not using it as I script directly with the Scripting API.
If you need a full JSON exporter/importer, open a ticket and explain why (I’ll try to convince you that you don’t need it :) )
Clipboard
| command | bindings |
|---|---|
| Copy to clipboard | ‘C00-c’ or ‘C00-Insert’ |
| Insert from clipboard | ‘C00-v’ or ‘00S-Insert’ |
| - | - |
| Copy to clipboard | ‘000-y’+‘000-y’ |
| Export to clipboard & primary as ascii | ‘000-y’+‘00S-Y’ |
| Export to clipboard & primary as markup | ‘000-y’+‘000-m’ |
| - | - |
| Insert from clipboard | ‘000-p’+‘000-p’ |
| Import from primary to box | ‘000-p’+‘00S-P’ |
| Import from primary to text | ‘000-p’+‘0A0-p’ |
| Import from clipboard to box | ‘000-p’+‘000-b’ |
| Import from clipboard to text | ‘000-p’+‘000-t’ |
Some clipboard commands are using the xsel command.
Win11 Msys2
For users of Win11 Msys2 system. To make using the clipboard function smoother,
it is best to install the Win32::Clipboard module. If this module is not
installed, then using PowerShell to perform clipboard operations is very
inefficient. Users of other systems do not have this requirement!
cpanm Win32::Clipboard --force
Modes
selection
Select elements by:
- clicking on them
- «left-click» - select the element
- «Shift» + «left-click» - add the element to the current selection
- using the rectangular selection boxes - «left-click» + «drag»
There are more options for selecting elements:
- graph selection group
- mouse-drawn polygon selection
- mouse-move selection (with the left mouse button held down)
Graph selection group
Prefix: All operations require pressing «S» to enter the graph selection mode
| action | binding |
|---|---|
| Select neighbors | «n» |
| Select predecessors | «p» |
| Select ancestors | «a» |
| Select successors | «s» |
| Select descendants | «d» |
| select reachable | «r» |
| Select all connected | «c» |
.---------------------------------------------------------.
| all connected nodes |
|---------------------------------------------------------|
| .----------. .-----------. |
| | ancestor |---.---| reachable | |
| '----------' | '-----------' |
| | |
| | |
| v |
| .----------------------. |
| .-------| predecessor-neighbor | |
| | '----------------------' |
| | | |
| v v |
| .-----------. .------. |
| | not | .-------| node |--------. |
| | reachable | | '------' | |
| '-----------' | | |
| v v |
| .--------------------. .--------------------. |
| | successor-neighbor | | successor-neighbor | |
| '--------------------' '--------------------' |
| | | |
| v v |
| .------------. .-----------. |
| | descendant | | reachable | |
| '------------' '-----------' |
'---------------------------------------------------------'
Polygon and Mouse-move selection mode
Entering and exiting selection mode
Prefix: All operations require pressing «s» to enter the selection mode
| action | binding |
|---|---|
| Enter selection mode | <<s>> |
| Exit selection mode | <<Escape>> and <<<s>>> |
| Toggle selection and deselection | <<<e>>> |
| Select motion | <<<mouse_motion>>> |
| Select mouse click | <<<mouse_left_button>>> |
| Enter the polygon selection operation group | <<<x>>> |
Polygon selection operation group operation collection:
| action | binding |
|---|---|
| Exit polygon selection mode | <<<Escape>>> and <<<x>>> |
| Polygon select motion | <<<mouse_motion>>> |
| Polygon deselect motion | <<<Ctrl-mouse_motion>>> |
Operation after entering selection mode
Common selection operation example:

Operation after entering polygon selection mode
- selection situation.
- deselection situation.

pen
Introduction
Pen mode is used to draw one character at a time into the canvas, often used for small ascii art creations. It is also very convenient to use it for stencil making .This is a special feature of the GUI port.
Here are a few examples of making ascii art.


Here are a few examples of making stencil.


Basic operations
Entering and exiting pen mode
| action | binding |
|---|---|
| Enter pen mode | <<b>> |
| Exit pen mode | <<Escape>> |

After entering the pen mode, The mouse pointer will change to a text pointer, It means we can enter characters. Before any characters are changed, the question mark character is currently inserted by default.
Draw characters
- Move the mouse to a certain position, then click the
left mouse buttonor theEnter keyto insert a character at the current position. - Move the mouse to a certain position, then hold down the left mouse button, drag the mouse, and continuously draw characters in each grid along the path passed by the pen tip.

- Press a key on the keyboard and the corresponding characters on the keyboard will be inserted immediately at the current position. And the character inserted by the current mouse become the character you pressed.

- The overlay prompt has three shapes, which correspond to the position of the cursor after different inputs.
| action | binding |
|---|---|
| pen mouse toggle direction | <<C00-Tab>> |
(1). Square
After inserting a character, the cursor does not move automatically.
(2). Right triangle
After inserting a character, the cursor automatically moves to the right one position, which can be used for automatic input in the horizontal direction.
(3). Downward triangle
After inserting a character, the cursor automatically moves down one position, which can be used for automatic input in the vertical direction.

The BackSpace key can delete characters, In the latter two direction modes the Shift + Enter key can wrap lines. You can imagine that you are free input in a text editor.

Fast keyboard-based movement
When we are drawing ascii art, we may have to draw many small elements, if we click with the mouse every time we change the character,It may not be efficient, but if you can operate it with a pure keyboard within a small range, it may be much more efficient. Refer to vim editor, we also Customized a lot of Fast keyboard-based movement.
| action | binding |
|---|---|
| pen mouse move left | <<C00-h>> <<000-Left>> |
| pen mouse move right | <<C00-l>> <<000-Right>> |
| pen mouse move up | <<C00-k>> <<000-up>> |
| pen mouse move down | <<C0S-j>> <<000-Down>> |
| pen mouse move left quick | <<0A0-h>> |
| pen mouse move right quick | <<0A0-l>> |
| pen mouse move up quick | <<0A0-k>> |
| pen mouse move down quick | <<0A0-j>> |
| pen mouse move left tab | <<00S-ISO_Left_Tab>> |
| pen mouse move right tab | <<000-Tab>> |

Types of characters that can be entered
By default, we type in ascii characters on the keyboard, including letters,
numbers and symbols. But if the user is Other character groups are customized in
gui.pl. So we just need to switch to that character group and press the
corresponding key on the keyboard. The characters corresponding to the key in
the currently specified group will be entered instead of the default ascii
characters.
| action | binding |
|---|---|
| Switch user-defined character set forward | <<0A0-Enter>> |
| Switch user-defined character set back | <<C00-Enter>> |
| Toggle prompt keyboard position | <<C0S-Enter>> |
PEN_CHARS_SETS => # For the mapping of keys to inserted characters in pen mode
# Unlimited groups can be defined
# Unmapped keys are inserted according to the keyboard value
[
{
'~' => '─' , '!' => '▀' , '@' => '▁' , '#' => '▂' , '$' => '▃' , '%' => '▄' ,
'^' => '▅' , '&' => '▆' , '*' => '▇' , '(' => '█' , ')' => '▉' , '_' => '▊' ,
'+' => '▋' , '`' => '▋' , '1' => '▌' , '2' => '▍' , '3' => '▎' , '4' => '▏' ,
'5' => '▐' , '6' => '░' , '7' => '▒' , '8' => '▓' , '9' => '▔' , '0' => 'À' ,
'-' => '│' , '=' => '┌' , 'Q' => '┐' , 'W' => '└' , 'E' => '┘' , 'R' => '├' ,
'T' => '┤' , 'Y' => '┬' , 'U' => '┴' , 'I' => 'Ì' , 'O' => 'Ð' , 'P' => '┼' ,
'{' => 'Ã' , '}' => 'Ä' , '|' => 'Â' , 'q' => 'Á' , 'w' => 'Å' , 'e' => 'Æ' ,
'r' => 'Ç' , 't' => 'Ò' , 'y' => 'Ó' , 'u' => 'Ô' , 'i' => 'Õ' , 'o' => 'à' ,
'p' => 'á' , '[' => 'â' , ']' => 'ã' , '\\' => 'ì' , 'A' => 'ø' , 'S' => 'ù' ,
'D' => 'ú' , 'F' => 'û' , 'G' => '¢' , 'H' => '£' , 'J' => '¥' , 'K' => '€' ,
'L' => '₩' , ':' => '±' , '"' => '×' , 'a' => '÷' , 's' => 'Þ' , 'd' => '√' ,
'f' => '§' , 'g' => '¶' , 'h' => '©' , 'j' => '®' , 'k' => '™' , 'l' => '‡' ,
';' => '†' , "'" => '‾' , 'Z' => '¯' , 'X' => '˚' , 'C' => '˙' , 'V' => '˝' ,
'B' => 'ˇ' , 'N' => 'µ' , 'M' => '∂' , '<' => '≈' , '>' => '≠' , '?' => '≤' ,
'z' => '≥' , 'x' => '≡' , 'c' => '─' , 'v' => '│' , 'b' => '┌' , 'n' => '┐' ,
'm' => '└' , ',' => '┘' , '.' => '├' , '/' => '┤' ,
},
{
'1' => '┬', '2' => '┴', '3' => '┼',
},
],
The user-defined map content, there can be infinitely multiple groups(you can map a part of the keys for each group, and the unmaped part according to the default characters of the keyboard.).
By default, there is no overlay prompt because the keys on the keyboard correspond to their characters. But if switch to the user-defined group, a button prompt panel will appear for you. It is convenient for you to understand the corresponding situation of the current key group. The position of the prompt panel can be placed on the left or on the right, and the user switches according to the current editing situation.

The layout of the prompt keyboard can also be customized. Currently, two keyboard layouts are supported.
PEN_KEYBOARD_LAYOUT_NAME => 'US_QWERTY', # US_QWERTY or SWE_QWERTY
Change the character drawn by the pen
- After entering pen mode, directly press the key corresponding to an ascii character on the keyboard to switch to that character. Note: When pressed, one is inserted at the current position.

- After entering pen mode, move the mouse to a non-empty character and right-click. At this time, the character to be inserted becomes the character at the current position, which is equivalent to character extraction. If the characters in the current grid are stacked, take the top character.

- If the current mouse pointer is on a character before entering pen mode. Then after entering pen mode, the inserted character becomes this character.

- If a part of the area is selected before entering pen mode, and the selected elements contain characters, then these characters will be used as loop insertion characters after entering pen mode. (This has the highest priority).

In this case, the pen will loop through each non-blank character in the order in which it was extracted.
Switch to pen mode’s built-in eraser mode
This is mainly to delete multiple or consecutive dot elements (pen elements)
without exiting pen mode. In pen mode, press the <<Ctrl+Shift+Tab>> key to
switch to the eraser.
Press the <<Ctrl+Shift+Tab>> key again to switch back to pen mode.

There are 3 ways to delete elements in pen mode:
- In pen mode, place the cursor on the dot element (pen element), and then
press the
<<Back Space>>key. - In the eraser submode, Click the left mouse button directly on elements.
- In the eraser submode,Click the left mouse button and then draging, then all elements encountered on the dragging path will be deleted.

Merge the completed ascii art into a text box
| action | binding group | bingding |
|---|---|---|
| convert to a big text | <<element leader>>(<<e>>) | <<S-T>> |
The pen inserts a special type of elements called dots, which have almost no properties, no linker, and cannot be edited. After completing a small ASCII art work, what needs to be done is to combine them into a stencil.
Although it can be done with a strip group, due to the special nature of dot elements, there is no point in saving copies of them, so we can make it simpler.

Split any elements into dots
| action | binding group | bingding |
|---|---|---|
| convert to dots | <<element leader>>(<<e>>) | <<S-D>> |
Note: Do not perform this operation unless you know exactly what you are doing, as it will delete the original elements.
The main function of this function is to facilitate us to re-edit the saved ascii art template text box
For example, in the picture below, we want to add a nose to the kitten:

find
Introduction
The find mode is mainly used to find the location where our target text appears in all asciio objects, and can quickly locate those matching positions and highlight them. This is a special feature on the GUI port.

Basic operations
Entering and exiting find mode
| action | binding |
|---|---|
| Enter find mode | <<f>> |
| Exit find mode | <<Escape>> |
When you enter find mode, the mouse cursor will turn into a spider.After exiting, the mouse pointer changes to the default shape.
Operation after entering find mode
| action | binding |
|---|---|
| Perform new search | <<s>> |
| Jump to next match | <<n>> |
| Jump to previous match | <<Shift+N>> |
| Zoom in | <<000-plus>> <<C0S-J>> <<C00-scroll-up>> |
| Zoom out | <<000-minus>> <<C0S-H>> <<C00-scroll-donw>> |
After entering find mode, if we do not perform any search, no content will be
highlighted. At this time, press the <<s>> key to pop up a dialog box, enter
the characters to be found (regular expressions in Perl format are supported).
If a match is found, it will jump to the first matching character position,
and highlight the first match in blue, and other matches in purple. If you
press <<n>> or <<N>> to switch to the next or previous match, the current
match will be highlighted in blue and other matches will be highlighted in
purple.
If the position of the matching character is not in the current window, it will automatically jump to the corresponding position. Canvas zoom can be used during the search process to better locate character positions.
Example of finding a normal string:

Find examples of regular expressions:

Example of canvas zooming:

Repeat find
If we exit the find mode and re-enter, the last keyword search will be performed
by default before pressing <<s>> to perform a new search. It just won’t
automatically jump to the first match. If you need to jump, press <<n>> or
<<N>> again to perform the jump.

git
.*-----*------------------------------*
/ \
/ \
*------*---------*-----BETA---. \
\ \ \
\ .-----. ' \
.-------------. *---| fix |---*-----RELEASE 1.3------>*-----*---------*
| Release 2.0 | '-----' \ / /
|-------------| \ / /
| changes |-------------------> '---*-------*--------------*------*
| tag: ... | \ /
| eta: ... | \ /
'-------------' *-------'
The git mode allows you to draw git graph quickly.
The git mode redefines some bindings to allow you to work faster. Only the bindings listed below are available when editing.
| action | binding |
|---|---|
| Exit git mode | «Escape» |
| Undo | «u» |
| Insert and link node | «g» «right-click» |
| Change arrow direction | «d» |
| Add box | «b» |
| Add text | «t» |
| Add arrow | «a» |
| Select objects | «left-click» |
| Edit Selected element | «Return» «double-click» |
| Delete elements | «Delete» «x» |
| Flip hint lines | «h» |
| Display popup menu | «alt+right-click» |
When you insert and link a node:
- if nothing is under the pointer or selected, it will insert a commit node
- if a node is selected and nothing under the pointer, it will insert a new node and connect with the previously selected node
- if a node is selected and the pointer is over a node, it will link the nodes
Let’s create a git graph.

You can export the text and use it in our documentation
.----------------------------------.
| feature branch |
| |
| *-------------------* |
| / \ |
| / \ |
'----/-------------------------\---'
/ \
*---------*---------*---------*---------*---------*
^ ^
| |
| |
| |
we need a new we want to merge here
feature branch
or you can generate some fancy SVGs for a presentation.
The connector and arrow type of the git mode can be changed.
In the user configuration for the connector,
GIT_MODE_CONNECTOR_CHAR_LIST => ['*', 'o', '+', 'x', 'X', '┼', '╋', '╬'],
or in the popup menu for both.

Cross Mode
Introduction
Previously, crossover was a separate mode. But not anymore, crossover is just an attribute of the element. By default, the following shortcut keys are used to switch the cross attribute of the element. By default, the element has no cross attribute. The intersection of the boundaries of elements with the cross attribute will present special visual effects.
Binding:
- «e» enters the element operation group
| action | binding |
|---|---|
| Enable elements cross | <<x>> |
| Disable elements cross | <<Shift-X>> |

Complex graphics
The element cross attribute allows you to draw complex tables like the following:

╔═══════╤═══════════════════════════════════════════════╗
║ │ test scores ║
║ Name ├───────┬────────┬───────┬───────┬──────┬───────╢
║ │ Math│ Physics│ │ │ │ ║
╟───────┼───────┼────────┼───────┼───────┼──────┼───────╢
║ Jim │ A+ │ B │ │ │ │ ║
╟───────┼───────┼────────┼───────┼───────┼──────┼───────╢
║Stephen│ B │ A │ │ │ │ ║
╟───────┼───────┼────────┼───────┼───────┼──────┼───────╢
║ Kate │ A │ C │ │ │ │ ║
╚═══════╧═══════╧════════╧═══════╧═══════╧══════╧═══════╝
Stripe group situation
When we merge elements into a strip group, if the merged elements themself has a cross attribute, the merged strip group will also presents the visual effect of intersection, but the strip group element itself has no cross attribute.

Exported to text
.--------. ╭────────╮ ┏━━━━━━━━┓ ╔════════╗
| | │ │ ┃ ┃ ║ ║
| | │ │ ┃ ┏━━━━━┻━━┓ ║ ║
| | │ │ ┃ ┃ ┃ ║ ║
'--------' ╰────────╯ ┗━━┫ ┃ ╚════════╝
┃ ┃
┗━━━━━━━━┛
| │ ┃ ║
| │ ┃ ║
| │ ┃ ║
| │ ━━━━━╋━━━━━━ ║
| │ ┃ ║
| │ ┃ ║
| │ ┃ ║
| │ ┃ ║
| │ ┃ ║
.--------.
| | ╭─┬────────┬─────╮
| .-----'--. │ │ │ │
| | | │ │ │ │
'--. | │ │ │ │ ╔══════════════╗
| | │ ╰────────╯ │ ║ ║
'--------' │ │ ║ ║
│ │ ║ ║
│ ╔═══════╧╗ ║ ║
│ ║ ║ ║ ║
╰────────╢ ║ ║ ║
║ ║ ║ ║
╚════════╝ ╚══════════════╝
Slides
Slides are multiple asciio documents contained in a single project.
You can add, remove, reorder slides with the tab commands.
You can enter the slides mode which defines a few commands that you can use when presenting your slides.
Animations
You can create animations with Asciio
Animation Format
Animations are simple scripts that are run within a single asciio document.
use strict ;
use warnings ;
use App::Asciio::Utils::Animation ;
# the slides definition
[
# first slide
[
# text is added to a box at 0, 0
"0 intro",
# you can add scritpt with shortcuts per slide
{
a => sub
{
my ($self) = @_ ;
App::Asciio::Actions::Elements::add_element($self, ['Asciio/box', 0, 20, 20]) ;
},
},
],
# second slide
[
# if you have multiple elements in squre bracket, Asciio uses them as steps in your slide
[ "1.0", ],
[ "1.1", ],
# a step within a step, thereäs no limit but navigation becomes more intricate
[
["1.2.0", ]
],
],
# third slide
[
clear_and_box_at(0, 0, "2"), ],
],
# fourth slide
[
# you can load an asciio file
load(0, 0, 'path/file.asciio'),
# and add elements to the slide
box(10, 20, 'title', '3', 0),
],
# final slide
[
clear_all(),
# multiline box
box(19, 11, '', <<'EOT', 0),
6.0
(\_/)
(O.o) ASCII world domination is near!
(> <)
EOT
],
]
Utilities are defined in lib/App/Asciio/Utils/Animation.pm
Examples
Unix structure
.---. .---. .---. .---. .---. .---.
OS API '---' '---' '---' '---' '---' '---'
| | | | | |
v v | v | v
.------------. | .-----------. | .-----.
| Filesystem | | | Scheduler | | | MMU |
'------------' | '-----------' | '-----'
| | | |
v | | v
.----. | | .---------.
| IO |<----' | | Network |
'----' | '---------'
| | |
v v v
.---------------------------------------.
| HAL |
'---------------------------------------'
Documenting hardware instrumentation
_____
| ___ |
||___|| load
| ooo |--.------------------.------------------------.
'_____' | | |
v v v
.----------. .--------------------------. .----------------.
| module C | | module A | | module B |
'----------' |--------------------------| | (instrumented) |
| | .-----. | '----------------'
'---------------->| A.o | | |
| '-----' | |
| .------------------. | |
| | A.instrumented.o |<-------------'
| '------------------' |
'--------------------------'
Decorating Forth code
index? dup dup dup dup dup average @ + average ! ." data = " .
.--------------.
| Data Stack |
|--------------|
| next element |-----> average @ + average !
| dup |-----> ." data = " .
| dup |-----> minv @ < if--.
| dup | '------> minv ! ." (new minv) " or DROP after ELSE
| dup |-----> maxv @ > if---.
| dup | '----> maxv ! ." (new maxv) " or DROP after ELSE
'--------------'
minv @ < if
minv ! ." (new minv) "
else drop \ data > minv so it's ignored
maxv @ > if
maxv ! ." (new maxv) "
else drop \ data < maxv so it's ignored
then
then
counter @ 1 - counter ! \ Decrement counter
example 1
describing a class hierarchy
.-Base::Class::Derived_B
/
Something::Else /
\ .----Base::Class::Derived_C
\ /
'----Base::Class
' \
/ '----Latest::Greatest
Some::Thing--'
German railroad
Graph-Easy is an application that generates graphs in ASCII, a bit like GraphViz.
..................................
: v
+------+ +--------+ ............. +---------+ +---------+
| Bonn | --> | Berlin | --> : : --> | Potsdam | ==> | Cottbus |
+------+ +--------+ : : +---------+ +---------+
^ : : ^
| : Frankfurt : |
| : : |
+--------+ : : +---------+ |
| x | --> : : <-- | y | ------+
+--------+ :...........: +---------+
|
|
v
+-----------+
| Dresden |
+-----------+
I re-drew the example above in Asciio.
.------------------------------.
| |
| v
.------. .--------. .-----------. .---------. .---------.
| Bonn |-.->| Berlin |-.->| Frankfurt |-.->| Potsdam |->| Cottbus |
'------' | '--------' | '-----------' | '---------' '---------'
| | | ^
.---. | | .---------. |
| x |-----------' '->| Dresden | |
'---' | '---------' |
.---. | |
| y |-----------'-------------------------------------'
'---'
There are few interesting things to notice:
- Graph-Easy smartly changes the size of the boxes to accommodate more connections
- Asciio doesn’t have a routing functionality for graph, it would be a nice addition
- Asciio has 4 connectors per box (but you can get around it)
Unicode Example
Asciio does’t generate SVG but, in the spirit of unix tools, rely on another tool to convert text files to SVG.
The “goat” project (https://github.com/blampe/goat) has been chosen to make the conversion, it must be installed, but you can use any converter you want; I recommend having a look athe ecexelent SVGBob too.
See the “Exporter” section to learn how to write your own.

videos
-
presentation
-
efficient session
-
grouping
-
working with external commands
-
input to asciio
-
using Asciio’s output
-
-
doing a presentation with Asciio
-
writing requirements with Asciio and markdown
Some older videos (15 years!) that show some basic usage:
Asciio Keyboard Bindings Reference
Understanding the Binding System
Asciio uses a hierarchical keyboard binding system where many operations are organized into groups accessed through prefix keys.
It’s faster and easier to work with keyboard shortcuts than the mouse plus the number of combination of mouse buttons * control-keys is limited.
Asciio bindings are vim-like, they initially take a little time to get used to and often take multiple key presses but they are much more logical as families of commands are accessed with shortcuts that start with the same letter.
Both GUI and TUI have vim-like bindings, the GUI has a few extra bindings that are usually found in GUI applications; bindings can be user modified. See configuration/user_bindings
Actions
Code that is added to asciio (a plugin is another term).
Asciio provides many actions but you can write your own and bind it to a shortcut.
Bindings
Registration of shortcuts that execute actions.
The default Bindings are setup by the register_action_handlers in the following files:
- setup/actions/default_bindings.pl
- setup/Text/actions/vim_bindings.pl (which overrides default bindings)
User defined bindings
The bindings can be changed in your user configuration.
Set the ACTION_FILES section of file ‘$HOME/.config/Asciio/Asciio.ini’ to point at one or more files that will be loaded by asciio.
The files contain bindings override but can also contain actions code.
Show Bindings Completion
Binding: «zb»

Makes Asciio show the current bindings iwhile you type.
You can add it in your config:
USE_BINDINGS_COMPLETION => 1,
Embedded bindings
Extra bindings can be embedded in an asciio document with command line options
| option | |
|---|---|
| add_binding=s | file containing bindings to embedd |
| reset_bindings | remove all embedded bindings from document |
| dump_bindings | write the embedded bindings to files |
| dump_binding_names | display name of embbeded bindings |
Binding Notation
Bindings are shown using the notation «key» where:
«key»means press that key directly«Shift+Key»means hold Shift and press the key«Ctrl+Key»means hold Control and press the key«Alt+Key»means hold Alt and press the key
Prefix System
Many operations require a prefix key followed by an operation key:
- Press the prefix key (e.g.,
«t»for tab operations) - Then press the operation key (e.g.,
«n»for new tab) - Result:
«t»+«n»creates a new tab
Escaping Groups
When in a binding group, press «Escape» to return to root level bindings.
Why vim-like bindings
Combinations
To simplify, let’s start with having 26 letters accessible on the keyboard, no uppercase.
- using ctl + alt + key gives us around 100 combinations
- letter + letter gives use around 650 combinations
- letter + letter + letter gives use around 18 000 combinations
If we had uppercase, ie, 52 letters
- using ctl + alt + key gives us around 200 combinations
- letter + letter + letter gives use around 140 000 combinations
Speed
typing ctl + alt + key is not faster than key + key + key, and even less key + key
Structure and mnemonics
Of course we don’t need tens of thousands of combinations
But do you know what CA0-a does? C0S-A? 0AS-a? CAS-A? C00-A? 0A0-a? 00S-a? … without looking at the docs?
The whole point vim-like binding is to remember them, it’s not a perfect system but it’s expandable and easier to remember
Let me give you and example, we have multiple types of boxes, let’s say
- normal
- unicode
- shrink
- with hash tag as a border
Let’ start with a generic binder «i» for insert and «b» for box
- «ibb» normal, we cound have used «ibn» too but the most used keys are usually double for speed
- «ibu» unicode
- «ibs» shrink
- «ibh» with hash tag as a border
The good thing here is that we can use the same thing for arrows but with «ia» as a prefix.
But let’s imagine that you come up with 4 new types of unicode borders (well you have), I don’t want to imagine how to do that with the mouse, and with ctl + …. we’ve run out of shortcuts that are easy to remember. on the other hand …
- «ibb» normal, we cound have used «ibn» too but the most used keys are usually double for speed
- «ibuu» unicode
- «ibu1» unicode
- «ibu2» unicode
- «ibu3» unicode
- «ibs» shrink
- «ibh» with hash tag as a border
I used 1, 2, and 3 because I was lacking imagination but
- double
- thick
- whatnot
would have given us keys to remember.
Quizz
Do you remember (although you’ve just seen it) …
- insert a box
- insert a box using unicode type 2
- insert a box that shrinks
- insert a box with the default unicode
Root Level Bindings
Navigation: Index > Root Level Bindings
These bindings work directly without requiring a prefix key.
Editing Operations
| Operation | Binding | Description |
|---|---|---|
| Undo | «Ctrl+z» or «u» | Undo last operation |
| Redo | «Ctrl+y» or «Ctrl+r» | Redo previously undone operation |
| Delete selected elements | «Delete» or «d» | Remove currently selected elements |
View Control
| Operation | Binding | Description |
|---|---|---|
| Zoom in | «+» or «Ctrl+j» or «Ctrl+scroll-up» | Increase canvas zoom level |
| Zoom out | «-» or «Ctrl+h» or «Ctrl+scroll-down» | Decrease canvas zoom level |
Selection Operations
Basic Selection
| Operation | Binding | Description |
|---|---|---|
| Select all elements | «Ctrl+a» or «Shift+V» | Select every element in the canvas |
| Deselect all elements | «Escape» | Clear current selection |
| Select connected elements | «v» | Select all elements connected to current selection |
| Select elements by word | «Ctrl+f» | Select all elements containing specific text |
| Select elements by word no group | «Ctrl+Shift+f» | Select by text without grouping |
Sequential Selection
| Operation | Binding | Description |
|---|---|---|
| Select next element | «Tab» | Cycle forward through all elements |
| Select previous element | «Shift+Tab» | Cycle backward through all elements |
| Select next non-arrow | «n» | Cycle forward through non-arrow elements |
| Select previous non-arrow | «Shift+N» | Cycle backward through non-arrow elements |
| Select next arrow | «m» | Cycle forward through arrow elements |
| Select previous arrow | «Shift+M» | Cycle backward through arrow elements |
Advanced Selection
| Operation | Binding |
|---|---|
| Enter interactive selection mode | «s» |
Element Manipulation
Editing Elements
| Operation | Binding | Description |
|---|---|---|
| Edit selected element | «Double-click-1» or «Return» | Open editor for selected element |
| Edit selected element inline | «Ctrl+Double-click-1» or «Alt+Return» | Edit element text directly on canvas |
Moving Elements
| Operation | Binding | Description |
|---|---|---|
| Move selected left | «Left» or «h» | Move selection one character left |
| Move selected right | «Right» or «l» | Move selection one character right |
| Move selected up | «Up» or «k» | Move selection one character up |
| Move selected down | «Down» or «j» | Move selection one character down |
| Move selected left (fast) | «Alt+Left» | Move selection 10 characters left |
| Move selected right (fast) | «Alt+Right» | Move selection 10 characters right |
| Move selected up (fast) | «Alt+Up» | Move selection 10 characters up |
| Move selected down (fast) | «Alt+Down» | Move selection 10 characters down |
Resizing Elements
| Operation | Binding | Description |
|---|---|---|
| Make element narrower | «1» | Decrease width by one character |
| Make element taller | «2» | Increase height by one character |
| Make element shorter | «3» | Decrease height by one character |
| Make element wider | «4» | Increase width by one character |
Mouse Operations
See Mouse Operations Reference for complete details.
Basic Mouse
| Operation | Binding | Description |
|---|---|---|
| Mouse left-click | «Left-click» | Select element or set insertion point |
| Mouse right-click | «Right-click» | Open context menu |
| Mouse left-release | «Left-release» | Complete drag operation |
| Mouse selection flip | «Shift+Left-click» | Toggle element in selection |
Quick Operations
| Operation | Binding | Description |
|---|---|---|
| Quick link | «Alt+Left-click» or «.» | Create arrow to clicked location |
| Quick link orthogonal | «Alt+Shift+Left-click» | Create orthogonal arrow |
| Quick box | «Ctrl+Shift+Left-click» | Create box at location |
| Duplicate elements | «,» | Duplicate selected elements |
Drag and Drop
| Operation | Binding | Description |
|---|---|---|
| Start drag and drop | «Ctrl+Left-click» | Begin dragging elements |
Interactive Arrow Editing
| Operation | Binding | Description |
|---|---|---|
| Arrow to mouse | «Ctrl+Alt+motion» | Extend arrow to follow mouse |
| Arrow change direction | «Ctrl+Alt+d» | Toggle arrow direction interactively |
| Arrow mouse change direction | «Ctrl+Alt+Double-click» | Change arrow direction at click point |
| Wirl arrow add section | «Ctrl+Alt+Left-click» | Add section to multi-segment arrow |
| Wirl arrow insert flex point | «Ctrl+Alt+Middle-click» | Insert flexible point in arrow |
Mouse Motion
| Operation | Binding | Description |
|---|---|---|
| Mouse motion | «motion» | Track mouse position |
| Mouse motion (extended) | «Alt+Shift+motion» | Track with alternate behavior |
Mouse Emulation
| Operation | Binding | Description |
|---|---|---|
| Toggle mouse emulation | «'» | Enable/disable keyboard mouse control |
When Mouse Emulation Active
| Operation | Binding | Description |
|---|---|---|
| Emulation left-click | «ö» | Simulate left mouse click |
| Emulation expand selection | «Shift+Ö» | Expand selection at cursor |
| Emulation selection flip | «Ctrl+ö» | Toggle selection at cursor |
| Emulation right-click | «ä» | Simulate right mouse click |
| Emulation move left | «Ctrl+Left» | Move mouse cursor left |
| Emulation move right | «Ctrl+Right» | Move mouse cursor right |
| Emulation move up | «Ctrl+Up» | Move mouse cursor up |
| Emulation move down | «Ctrl+Down» | Move mouse cursor down |
| Emulation drag left | «Shift+Left» | Drag while moving left |
| Emulation drag right | «Shift+Right» | Drag while moving right |
| Emulation drag up | «Shift+Up» | Drag while moving up |
| Emulation drag down | «Shift+Down» | Drag while moving down |
Clipboard Operations
| Operation | Binding | Description |
|---|---|---|
| Copy to clipboard | «Ctrl+c» or «Ctrl+Insert» | Copy selection to system clipboard |
| Paste from clipboard | «Ctrl+v» or «Shift+Insert» | Insert from system clipboard |
GUI bindings
Navigation: Index > GUI bindings
keyboard
| Operation | Binding |
|---|---|
| Select all elements | «C00-a» |
| Copy to clipboard | «C00-c» |
| Export to clipboard & primary as ascii | «C00-e» |
| Insert from clipboard | «C00-v» |
| Import from primary to box | «C0S-V» |
| Undo | «C00-z» |
| Redo | «C00-y» |
| Zoom in | «+» |
| Zoom out | «-» |
mouse
| Operation | Binding |
|---|---|
| Edit selected element | «double-click» |
| Add to selection | «C00-button-1» |
| Quick link | «0A0-button-1» |
| Duplicate elements | «0AS-button-1» |
| Insert flex point (in arrow) | «CA0-button-1» |
Tab Management
Navigation: Index > Root level bindings > Tab Management
Prefix: All operations require pressing «t» first
Exit: Press «Escape» to return to root bindings
Tab Navigation bindings
| Operation | Shortcut | Description |
|---|---|---|
| Next tab | «t» | Move to next tab (wraps around) |
| Previous tab | «T» | Move to previous tab (wraps around) |
| Last tab | «$» | Jump to rightmost tab |
| Focus tab 0 | «0» | Jump to first tab |
| Focus tab N | «1» .. «9» | Jump to Nth tab |
Tab Management bindings
| Operation | Shortcut | Description |
|---|---|---|
| New tab | «n» | Create new empty tab |
| Clone tab | «c» | Duplicate current tab |
| Rename tab | «R» | Change tab label text |
| Move tab left | «h» | Shift tab position left |
| Move tab right | «l» | Shift tab position right |
| Toggle tab labels | «L» | Show or hide tab labels |
File Operations bindings
| Operation | Shortcut | Description |
|---|---|---|
| Read file | «r» | Load file into new tab |
| Open project | «e» | Open project (closes existing tabs) |
| Save project | «w» | Save current workspace |
| Save project as | «W» | Save with new filename |
Application level bindings
| Operation | Shortcut | Description |
|---|---|---|
| Quit with save | «q» | Exit with save prompt |
| Quit without save | «Q» | Exit immediately without saving |
Insert Operations
Navigation: Index > Insert Operations
Prefix: All operations require pressing «i» first
Exit: Press «Escape» to return to root bindings
Basic Elements
| Operation | Binding | Description |
|---|---|---|
| Add connector | «c» | Insert connection point |
| Add text | «t» | Insert text element |
| Add arrow | «a» | Insert multi-segment arrow |
| Add angled arrow | «Shift+A» | Insert angled arrow |
Insert Sub-Groups
| Operation | Binding | Description |
|---|---|---|
| Stencil | «s» | Insert from stencils |
| Multiple | «m» | Insert multiple elements |
| Unicode | «u» | Insert unicode elements |
| Box | «b» | Insert box variants |
| Elements | «e» | Insert special elements |
| Ruler | «r» | Insert rulers |
| Line | «l» | Insert lines |
| Connected | «k» | Insert connected elements |
Related Groups
- Pen Mode - Character-by-character drawing
- Clone Mode - Clone and place elements
box variants
Insert Box
Navigation: Index > Insert > Box
Prefix: Press «i» «b»
Box Operations
| Operation | Binding | Description |
|---|---|---|
| Add box | «b» | Insert standard box |
| Add shrink box | «s» | Insert box that shrinks to fit content |
| Add exec box | «e» | Insert box with executable content |
| Add exec box verbatim | «v» | Insert box with verbatim executable content |
| Add exec box verbatim once | «o» | Insert box with one-time verbatim execution |
| Add line numbered box | «l» | Insert box with line numbers |
multiple elements
Insert Multiple Elements
Navigation: Index > Insert > Multiple Elements
Prefix: Press «i» «m»
Multiple Element Operations
| Operation | Binding | Description |
|---|---|---|
| Add multiple boxes | «b» | Insert multiple boxes at once |
| Add multiple boxes connected | «B» | Insert multiple boxes at once |
| Add multiple texts | «t» | Insert multiple text elements at once |
| Add multiple texts connected | «T» | Insert multiple text elements at once |
unicode elements
Insert Unicode
Navigation: Index > Insert > Unicode
Prefix: Press «i» «u»
Unicode Element Operations
| Operation | Binding | Description |
|---|---|---|
| Add unicode box | «b» | Insert box with unicode characters |
| Add unicode arrow | «a» | Insert arrow with unicode characters |
| Add unicode angled arrow | «A» | Insert angled arrow with unicode characters |
| Add unicode line | «l» | Insert connecting unicode line |
| Add unicode bold line | «L» | Insert bold unicode line |
| Add unicode double line | «Alt+l» | Insert double unicode line |
| Add unicode no-connect line | «k» | Insert non-connecting unicode line |
| Add unicode no-connect bold line | «K» | Insert non-connecting bold unicode line |
| Add unicode no-connect double line | «Alt+K» | Insert non-connecting double unicode line |
connected elements
Insert Connected
Navigation: Index > Insert > Connected
Prefix: Press «i» «k»
Starting from a box or text, element, automatically link to one or more new boxes or text.
Connected Element Operations
| Operation | Binding | Description |
|---|---|---|
| Add connected box edit | «b» | Insert box with immediate edit and auto-connect |
| Add multiple connected box edit | «B» | Insert multiple boxes with edit and auto-connect |
| Add connected text edit | «t» | Insert text with immediate edit and auto-connect |
| Add multiple connected text edit | «T» | Insert multiple texts with edit and auto-connect |


lines
Insert Line
Navigation: Index > Insert > Line
Prefix: Press «i» «l»
Line Operations
| Operation | Binding | Description |
|---|---|---|
| Add ASCII line | «l» | Insert connecting ASCII line |
| Add ASCII no-connect line | «k» | Insert non-connecting ASCII line |
stencils
Insert Stencil
Navigation: Index > Insert > Stencil
Prefix: Press «i» «s»
Stencil Operations
| Operation | Binding | Description |
|---|---|---|
| From user stencils | «s» | Open user stencil directory |
| From default stencil | «d» | Open default_stencil.asciio |
| From any stencil | «a» | Open any stencil file |
| From user elements | «0» | Open elements.asciio |
| From user computer | «1» | Open computer.asciio |
| From user people | «2» | Open people.asciio |
| From user buildings | «3» | Open buildings.asciio |
special elements
Insert Special Element
Navigation: Index > Insert > Elements
Prefix: Press «i» «e»
Special Element Operations
| Operation | Binding | Description |
|---|---|---|
| Add connector type 2 | «c» | Insert alternate connector style |
| Add connector use top character | «C» | Insert center connector using top character |
| Add if box | «i» | Insert diamond-shaped if/decision box |
| Add process box | «p» | Insert process box |
| Add rhombus | «r» | Insert rhombus shape |
| Add ellipse | «e» | Insert ellipse shape |
rulers
Insert Ruler
Navigation: Index > Insert > Ruler
Prefix: Press «i» «r»
Ruler Operations
| Operation | Binding | Description |
|---|---|---|
| Add vertical ruler | «v» | Insert vertical measurement ruler |
| Add horizontal ruler | «h» | Insert horizontal measurement ruler |
| Delete rulers | «d» | Remove all rulers |
Element Operations
Navigation: Index > Element Operations
Prefix: All operations require pressing «e» first
Exit: Press «Escape» to return to root bindings
Element Modification
| Operation | Binding | Description |
|---|---|---|
| Shrink box | «s» | Shrink box to fit content |
| Make elements unicode | «u» | Convert selection to unicode style |
| Make elements not unicode | «U» | Convert selection from unicode style |
| Convert to big text | «g» | Merge selected elements into single text element |
| Convert to dots | «G» | Convert selected elements to dot characters |
Freeze Thaw
| Operation | Binding | Description |
|---|---|---|
| freeze | «f» | freeze elements, they can’t be moved or resized |
| freeze to background | «F’» | freese elements and move them to the background |
| thaw | «t’» | thaws the elements |
Element Attributes
| Operation | Binding | Description |
|---|---|---|
| Copy element attributes | «c» or «y» | Copy attributes from selected element |
| Paste element attributes | «p» | Apply copied attributes to selection |
| Paste control attributes | «P» | Apply only control-related attributes |
Crossover Control
| Operation | Binding | Description |
|---|---|---|
| Enable elements cross | «x» | Allow elements to cross over each other |
| Disable elements cross | «X» | Prevent elements from crossing over |
Element Type Change
Prefix: All operations require pressing «T» first
| Operation | Binding |
|---|---|
| Box styles | «b» |
| Wirl arrow styles | «w» |
| Angled arrow styles | «a» |
| Ellipse styles | «e» |
| Rhombus styles | «r» |
| Triangle up styles | «u» |
| Triangle down styles | «d» |
Related Groups
Resizing elements
| Operation | Binding |
|---|---|
| Make element narrower | «1» |
| Make element taller | «2» |
| Make element shorter | «3» |
| Make element wider | «4» |

Shrinking boxes
| Operation | Binding |
|---|---|
| Shrink box | «es» |

There an auto-shrink attribute so you don’t have to shrink boxes manually each time you change their size.

There’s also a box you can add which already has auto-shrink set; you can insert it with a shortcut or via the popup menu.
| Operation | Binding |
|---|---|
| Add auto-shrink box | «i»«b»«s» |

Grouping Elements
Navigation: Index > Element operations > Grouping elements
Prefix: All operations require pressing «g» first
| Operation | Binding |
|---|---|
| Group selected elements | «g» |
| Ungroup selected elements | «u» |
| Move selected elements to the front | «f» |
| Move selected elements to the back | «b» |
| Temporary move to the front | «F» |

Only arrows that are fully connected will be grouped.

Arrow Manipulation
Navigation: Index > Arrow Operations
Prefix: All operations require pressing «a» first
Exit: Press «Escape» to return to root bindings
Arrow Manipulation
| Operation | Binding | Description |
|---|---|---|
| Change arrow direction | «d» | Change arrow direction |
| Flip arrow start and end | «f» | Reverse arrow |
| enable diagonals | «Alt+d» | |
| disable diagonals | «Alt+D» |
Connector Configuration
| Operation | Binding | Description |
|---|---|---|
| Connectors | «c» | Enters connector group |
Multi-Segment Arrow Operations
| Operation | Binding | Description |
|---|---|---|
| Prepend section | «s» | Add section to start of multi-segment arrow |
| Append section | «e» | Add section to end of multi-segment arrow |
| Insert section | «S» | Insert section in middle of arrow |
| Remove last section | «r» | Delete last section from arrow |
Select Arrows
| Operation | Binding | Description |
|---|---|---|
| Flip drag selects arrows | «Alt+s» | Toggle whether drag operations select arrows |
Related Groups
- Mouse Operations - Interactive arrow editing
Arrow Connectors Operations
Navigation: Index > Arrow Operations > Arrow Connectors Operations
Prefix: All operations require pressing «a» «c» first
Exit: Press «Escape» to return to root bindings
| Operation | Binding |
|---|---|
| ‘start enable connection’ | «Alt+s» |
| ‘start disable connection’ | «Alt+S» |
| ‘end enable connection’ | «Alt+e» |
| ‘end disable connection’ | «Alt+E» |
| ‘Start flip enable connection’ | «Ctl+s» |
| ‘End flip enable connection’ | «Ctl+e» |
| ‘start connectors ->’ | «s» |
| ‘end connectors ->’ | «e» |
| ‘both connectors ->’ | «b» |
Start Connector
Navigation: Index > Arrow Manipulation > Connectors > Start Connector
Prefix: Press «a» «c» «s» to enter this group
Exit: Press «Escape» to return to both connectors configuration
Start Connector Styles
| Operation | Binding |
|---|---|
| fixed start connectors -> | f |
| dash, | «minus», |
| arrow reversed, | «less», |
| arrow, | «greater», |
| t, | «t», |
| T, | «T», |
End Connector
Navigation: Index > Arrow Manipulation > Connectors > End Connector
Prefix: Press «a» «c» «e» to enter this group
Exit: Press «Escape» to return to both connectors configuration
Start Connector Styles
| Operation | Binding |
|---|---|
| fixed end connectors -> | f |
| dash, | «minus», |
| arrow reversed, | «less», |
| arrow, | «greater», |
| t, | «t», |
| T, | «T», |
Both Connectors
Navigation: Index > Arrow Manipulation > Connectors > Both Connector
Prefix: Press «a» «c» «b» to enter this group
Exit: Press «Escape» to return to both connectors configuration
Start Connector Styles
| Operation | Binding |
|---|---|
| fixed both connectors -> | f |
| dash, | «minus», |
| arrow reversed, | «less», |
| arrow, | «greater», |
| t, | «t», |
| T, | «T», |
Fixed vs Dynamic Connectors
Fixed connectors remain the same regardless of arrow direction while dynamic connectors change according to the arrow direction

Example: Bindings for Both Connectors Fixed
Navigation: Index > Arrow Operations > Connectors > Both_connectors > Fixed
Prefix: Press «a» «c» «b» «f»` to enter this group
Exit: Press «Escape» to return to both connectors configuration
Fixed Connector Styles
| Operation | Binding | Description |
|---|---|---|
| Dash fixed (both) | «-» | Use dash (-) at both ends |
| Dot fixed (both) | «.» | Use dot (.) at both ends |
| Star fixed (both) | «Shift+*» | Use star (*) at both ends |
| Circle fixed small (both) | «o» | Use small circle (o) at both ends |
| Circle fixed large (both) | «Shift+O» | Use large circle (O) at both ends |
| Bullet fixed (both) | «d» | Use bullet (•) at both ends |
The same bindings exist when changing the start or the end connector.
Yank Operations
Navigation: Index > Yank Operations
Prefix: All operations require pressing «y» first
Exit: Press «Escape» to return to root bindings
Yank operations copy selected elements to the clipboard in various formats.
Copy Operations
| Operation | Binding | Description |
|---|---|---|
| Copy to clipboard | «y» | Copy selection to system clipboard (native format) |
| Export as ASCII | «Shift+Y» | Copy as plain ASCII text to clipboard and primary |
| Export as markup | «m» | Copy with markup/formatting to clipboard and primary |
Mouse Operations Reference
Navigation: Index > Mouse Operations
Complete reference for all mouse-based interactions in Asciio.
Basic Mouse Operations
Clicking
| Operation | Binding | Description |
|---|---|---|
| Left-click | «Left-click» | Select element at cursor position |
| Double-click | «Double-click-1» | Edit element at cursor position |
| Right-click | «Right-click» | Open context menu |
| Shift+Left-click | «Shift+Left-click» | Toggle element selection (add/remove from selection) |
Drag Operations
| Operation | Binding | Description |
|---|---|---|
| Drag elements | «Left-click+drag» | Move selected elements |
| Start drag and drop | «Ctrl+Left-click» | Begin drag and drop operation |
| Release | «Left-release» | Complete drag operation |
Quick Creation
| Operation | Binding | Description |
|---|---|---|
| Quick link | «Alt+Left-click» | Create arrow from selection to click point |
| Quick link orthogonal | «Alt+Shift+Left-click» | Create orthogonal arrow to click point |
| Quick box | «Ctrl+Shift+Left-click» | Create box at click location |
| Duplicate element | «,» | Duplicate selected elements |
Interactive Arrow Editing
| Operation | Binding | Description |
|---|---|---|
| Arrow to mouse | «Ctrl+Alt+motion» | Extend/modify arrow following mouse cursor |
| Arrow change direction | «Ctrl+Alt+Double-click» | Change arrow direction at click point |
| Add arrow section | «Ctrl+Alt+Left-click» | Add section to multi-segment arrow |
| Insert flex point | «Ctrl+Alt+Middle-click» | Insert flexible point in arrow path |
Mouse Motion Tracking
| Operation | Binding | Description |
|---|---|---|
| Standard motion | «motion» | Track mouse position for hover effects |
| Extended motion | «Alt+Shift+motion» | Track with alternate behavior |
Mouse Emulation Mode
Mouse emulation allows full mouse control via keyboard.
Activation
| Operation | Binding | Description |
|---|---|---|
| Toggle mouse emulation | «'» | Enable/disable keyboard mouse control |
Cursor Movement
| Operation | Binding | Description |
|---|---|---|
| Move cursor left | «Ctrl+Left» | Move mouse cursor one character left |
| Move cursor right | «Ctrl+Right» | Move mouse cursor one character right |
| Move cursor up | «Ctrl+Up» | Move mouse cursor one character up |
| Move cursor down | «Ctrl+Down» | Move mouse cursor one character down |
Clicking
| Operation | Binding | Description |
|---|---|---|
| Emulated left-click | «ö» | Simulate left mouse button click |
| Emulated right-click | «ä» | Simulate right mouse button click |
| Expand selection | «Shift+Ö» | Expand selection at cursor |
| Toggle selection | «Ctrl+ö» | Add/remove element at cursor from selection |
Dragging
| Operation | Binding | Description |
|---|---|---|
| Drag left | «Shift+Left» | Drag selection while moving left |
| Drag right | «Shift+Right» | Drag selection while moving right |
| Drag up | «Shift+Up» | Drag selection while moving up |
| Drag down | «Shift+Down» | Drag selection while moving down |
Zoom with Mouse
| Operation | Binding | Description |
|---|---|---|
| Zoom in | «Ctrl+scroll-up» | Increase zoom level |
| Zoom out | «Ctrl+scroll-down» | Decrease zoom level |
Image Box Operations
Navigation: Index > Image Box
Prefix: All operations require pressing «I» first
Exit: Press «Escape» to return to root bindings
| Operation | Binding | description |
|---|---|---|
| inserted from file | «i» | |
| freeze | «f» | freeze and put image box in the background |
| thaw | «t» | |
| rendering controls | «c» |
Rendering controls:
Prefix: All operations require pressing «I» «c» first
| Operation | Binding |
|---|---|
| increase gray scale | «g» |
| decrease gray scale | «G» |
| increase alpha | «a» |
| decrease alpha | «A» |
| reset to default | «r» |
Display options
Navigation: Index > Display options
Prefix: All operations require pressing «z» first
Exit: Press «Escape» to return to root bindings
Element Modification
| Operation | Binding |
|---|---|
| Change font | «f» |
| Change color -> | «c» |
| Flip binding completion | «b» |
| Flip transparent element background | «t» |
| Flip grid display | «g» |
| Flip rulers display | «r» |
| Flip hint lines | «h» |
| Flip edit inline | «i» |
| Flip show/hide connectors | «v» |
Related Groups
Color Configuration
navigation: index > display options > color configuration
Prefix: Press «z» then «c» to enter this group
Exit: Press «Escape» to return to display options
Color Operations
| Operation | Binding | Description |
|---|---|---|
| Flip color scheme | «s» | Toggle between color schemes |
| Change element foreground | «f» | Set foreground color for selected elements |
| Change element background | «b» | Set background color for selected elements |
| Change canvas background | «Shift+B» | Set overall canvas background color |
| Change grid color | «g» | Set grid line color |
Related Groups
Debug Operations
Navigation: Index > Debug Operations
Prefix: All operations require pressing «D» first
Exit: Press «Escape» to return to root bindings
Debug operations provide diagnostic information for development and troubleshooting.
Debug Operations
| Operation | Binding | Description |
|---|---|---|
| Display undo stack statistics | «u» | Show undo/redo stack information |
| Dump self | «s» | Output Asciio object state |
| Dump all elements | «e» | Output all element information |
| Dump selected elements | «E» | Output selected element information |
| Toggle numbered objects | «t» | Show/hide object ID numbers |
| Test | «o» | Run test operation |
| ZBuffer test | «z» | Display z-buffer crossing information |
Modes
Clone Mode Bindings
Navigation: Index > Clone Mode
Prefix: Press «c» to enter clone mode
Exit: Press «Escape» to return to root bindings
Clone mode allows cloning selected elements and placing copies interactively.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Exit clone mode | «Escape» | Return to normal mode |
Clone Placement
| Operation | Binding | Description |
|---|---|---|
| Clone motion | «motion» | Move clone preview following mouse |
| Insert clone | «Left-click» or «Return» | Place clone at current position |
Clone Template Selection
| Operation | Binding | Description |
|---|---|---|
| Clone arrow | «a» | Set clone template to arrow |
| Clone angled arrow | «Shift+A» | Set clone template to angled arrow |
| Clone box | «b» | Set clone template to box |
| Clone text | «t» | Set clone template to text |
Display Options
| Operation | Binding | Description |
|---|---|---|
| Flip hint lines | «h» | Toggle hint lines in clone mode |
Keyboard Movement
| Operation | Binding | Description |
|---|---|---|
| Move clone left | «Left» | Move clone position left |
| Move clone right | «Right» | Move clone position right |
| Move clone up | «Up» | Move clone position up |
| Move clone down | «Down» | Move clone position down |
Mouse Emulation in Clone Mode
| Operation | Binding | Description |
|---|---|---|
| Emulation move left | «Ctrl+Left» | Move mouse cursor left |
| Emulation move right | «Ctrl+Right» | Move mouse cursor right |
| Emulation move up | «Ctrl+Up» | Move mouse cursor up |
| Emulation move down | «Ctrl+Down» | Move mouse cursor down |
Eraser Mode
Navigation: Index > Eraser Mode
Prefix: Press «E» to enter eraser mode
Exit: Press «Escape» to return to root bindings
Eraser mode removes elements by hovering the mouse over them.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Exit eraser mode | «Escape» | Return to normal mode |
Erasing Operations
| Operation | Binding | Description |
|---|---|---|
| Erase motion | «motion» | Erase elements under mouse cursor |
Pen Mode
Navigation: Index > Pen Mode
Prefix: Press «P» to enter pen mode
Exit: Press «Escape» to return to root bindings
Pen mode provides character-by-character drawing with keyboard navigation.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Exit pen mode | «Escape» | Return to normal mode |
| Switch pen/eraser | «Ctrl+Shift+Tab» | Toggle between pen and eraser |
Character Placement
| Operation | Binding | Description |
|---|---|---|
| Insert or delete character | «Left-click» or «Return» | Place/remove character at cursor |
| Change character | «Right-click» | Change character at cursor position |
Cursor Movement
| Operation | Binding | Description |
|---|---|---|
| Move left | «Left» or «Ctrl+h» | Move cursor one character left |
| Move right | «Right» or «Ctrl+l» | Move cursor one character right |
| Move up | «Up» or «Ctrl+k» | Move cursor one character up |
| Move down | «Down» or «Ctrl+j» | Move cursor one character down |
| Move left (fast) | «Alt+h» | Move cursor multiple characters left |
| Move right (fast) | «Alt+l» | Move cursor multiple characters right |
| Move up (fast) | «Alt+k» | Move cursor multiple characters up |
| Move down (fast) | «Alt+j» | Move cursor multiple characters down |
Special Movement
| Operation | Binding | Description |
|---|---|---|
| Space | «Space» | Move according to direction setting |
| Left tab | «Shift+Tab» | Move to previous tab stop |
| Right tab | «Tab» | Move to next tab stop |
| Enter | «Shift+Return» | Move to beginning of next line |
| Toggle direction | «Ctrl+Tab» | Change auto-movement direction |
Character Deletion
| Operation | Binding | Description |
|---|---|---|
| Delete forward | «Delete» | Delete character at cursor |
| Delete backward | «BackSpace» | Delete character before cursor and move back |
Character Set Management
| Operation | Binding | Description |
|---|---|---|
| Next character set | «Ctrl+Return» | Switch to next character mapping |
| Previous character set | «Alt+Return» | Switch to previous character mapping |
| Toggle help location | «Ctrl+Shift+Return» | Change where character set help is displayed |
Direct Character Input
Pen mode allows direct entry of alphanumeric and special characters. Simply type the character to place it at the cursor position.
Lowercase Letters
Type «a» through «z» to insert lowercase letters.
Uppercase Letters
Type «Shift+A» through «Shift+Z» to insert uppercase letters.
Numbers
Type «0» through «9» to insert digits.
Special Characters (Shifted)
- «Shift+Å» - Å
- «Shift+Ä» - Ä
- «Shift+Ö» - Ö
- «Shift+*» - *
- «Shift+(» - (
- «Shift+!» - !
- «Shift+@» - @
- «Shift+#» - #
- «Shift+$» - $
- «Shift+%» - %
- «Shift+^» - ^
- «Shift+&» - &
- «Shift+)» - )
- «Shift+_» - _
- «Shift++» - +
- «Shift+{» - {
- «Shift+}» - }
- «Shift+:» - :
- «Shift+“» - “
- «Shift+~» - ~
- «Shift+|» - |
- «Shift+?» - ?
- «Shift+<» - <
- «Shift+>» - >
Special Characters (Unshifted)
- «å» - å
- «ä» - ä
- «ö» - ö
- «-» - -
- «=» - =
- «[» - [
- «]» - ]
- «;» - ;
- «’» - ’
- «
» - - «\» - \
- «/» - /
- «,» - ,
- «.» - .
Mouse Operations
| Operation | Binding | Description |
|---|---|---|
| Pen motion | «motion» | Track mouse position in pen mode |
Move Arrow Ends Mode
Navigation: Index > Move Arrow Ends Mode
Prefix: Press «Alt+a» to enter arrow ends mode
Exit: Press «Escape» to return to root bindings
Move arrow ends mode allows precise adjustment of arrow start and end points.
Arrow Start Movement
| Operation | Binding | Description |
|---|---|---|
| Move start up | «Up» or «k» | Move arrow start point up |
| Move start down | «Down» or «j» | Move arrow start point down |
| Move start left | «Left» or «h» | Move arrow start point left |
| Move start right | «Right» or «l» | Move arrow start point right |
Arrow End Movement
| Operation | Binding | Description |
|---|---|---|
| Move end up | «Shift+Up» or «Shift+K» | Move arrow end point up |
| Move end down | «Shift+Down» or «Shift+J» | Move arrow end point down |
| Move end left | «Shift+Left» or «Shift+H» | Move arrow end point left |
| Move end right | «Shift+Right» or «Shift+L» | Move arrow end point right |
Related Operations
Find Mode
Navigation: Index > Find Mode
Prefix: Press «f» to enter find mode
Exit: Press «f» or «Escape» to return to root bindings
Find mode searches for text within elements and navigates through results.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Exit find mode | «f» or «Escape» | Return to normal mode |
Search Operations
| Operation | Binding | Description |
|---|---|---|
| Perform new search | «s» | Enter new search term |
| Find next | «n» | Navigate to next match |
| Find previous | «Shift+N» | Navigate to previous match |
View Control in Find Mode
| Operation | Binding | Description |
|---|---|---|
| Zoom in | «+» or «Ctrl+Shift+J» or «Ctrl+scroll-up» | Increase zoom |
| Zoom out | «-» or «Ctrl+Shift+H» or «Ctrl+scroll-down» | Decrease zoom |
Git Mode
Navigation: Index > Git Mode
Prefix: Press «Shift+G» to enter git mode
Exit: Press «Escape» to return to root bindings
Git mode provides a simplified interface optimized for creating diagrams quickly.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Show git bindings | «Shift+?» | Display available git mode bindings |
Quick Creation
| Operation | Binding | Description |
|---|---|---|
| Quick git link | «Right-click» or «c» | Create quick connection |
Element Creation
| Operation | Binding | Description |
|---|---|---|
| Add box | «b» | Insert box with edit |
| Add text | «t» | Insert text with edit |
| Add arrow | «a» | Insert arrow |
Element Operations
| Operation | Binding | Description |
|---|---|---|
| Edit element | «Double-click» or «Return» | Edit selected element |
| Delete elements | «Delete» or «x» | Remove selected elements |
| Change arrow direction | «d» | Toggle arrow direction |
Editing Operations
| Operation | Binding | Description |
|---|---|---|
| Undo | «u» | Undo last operation |
Mouse Operations
| Operation | Binding | Description |
|---|---|---|
| Left-click | «Left-click» | Select element |
| Right-click | «Alt+Right-click» | Context menu |
| Motion | «motion» | Track mouse position |
Element Movement
| Operation | Binding | Description |
|---|---|---|
| Move left | «Left» | Move selection left |
| Move right | «Right» | Move selection right |
| Move up | «Up» | Move selection up |
| Move down | «Down» | Move selection down |
Display
| Operation | Binding | Description |
|---|---|---|
| Flip hint lines | «h» | Toggle hint lines |
Selection Mode
Navigation: Index > Selection Mode
Prefix: Press «s» to enter selection mode
Exit: Press «s» or «Escape» to return to root bindings
Selection mode provides interactive rectangle and polygon selection of elements.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Exit selection mode | «s» or «Escape» | Return to normal mode |
| Flip selection mode | «e» | Toggle between add/remove selection mode |
Mouse Operations
| Operation | Binding | Description |
|---|---|---|
| Select motion | «motion» | Track mouse for selection rectangle |
| Select elements | «Left-click» | Select elements within rectangle |
Polygon Selection
| Operation | Binding | Description |
|---|---|---|
| Enter polygon selection | «x» | Enter polygon selection mode |
Polygon Selection Mode
Navigation: Index > Selection Mode > Polygon Selection
Prefix: Press «s» «x» to enter polygon selection
Exit: Press «x» or «Escape» to return to selection mode
Polygon selection allows drawing a free form polygon to select elements.
Mode Control
| Operation | Binding | Description |
|---|---|---|
| Exit polygon selection | «x» or «Escape» | Return to selection mode |
Polygon Drawing
| Operation | Binding | Description |
|---|---|---|
| Polygon select motion | «motion» | Draw selection polygon |
| Polygon deselect motion | «Ctrl+motion» | Draw deselection polygon |
| Complete polygon | «Left-release» | Finish polygon and apply selection |
| Complete polygon (alternate) | «Ctrl+Left-release» | Finish deselection polygon |
Slides
Navigation: Index > Modes > Slides
Prefix: Press «S» to enter slide mode
Exit: Press «Escape» to return to normal mode
Bindings
| binding | Description |
|---|---|
| «n» | next slide |
| «N» | previous slide |
| «g» | first slide |
| «s» | run slideshow |
Bindings while running a slideshow
| binding | Description |
|---|---|
| «n» | next slide |
| «N» | previous slide |
| «s» | slower |
| «f» | faster |
| «p» | pause |
Animation
Navigation: Index > Modes > Animation
Prefix: Press «Alt+A» to enter animation mode
Exit: Press «Escape» to return to normal mode
Bindings
| binding | Description |
|---|---|
| «l» | Load animation |
| «g» | first animation |
| «n» | next animation |
| «N» | previous animation |
| «s» | run script |
Scripts can be configured in the animation file and can be run during presentations.
Animation Script Execution
Navigation: Index > Modes > Animation > Script execution
Prefix: Press «S» «a» enter the automation mode then «s»
Exit: Press «Escape» to exit animatioexit animationanimation scripts bound to alphanumeric keys.
Script Keys
Scripts can be bound to any letter or number key. Press the corresponding key to execute the associated script.
| Key Range | Description |
|---|---|
| «a» through «f» | Execute script bound to that letter |
| «0» through «9» | Execute script bound to that number |
Scripts are configured in the animation file.
Configuration
Definitions
Configuration file
A file containing pointers to file where:
- stencils are defines
- actions and bindings are defined
- asciio options are configured
- routing hooks are defined
- document importers and exporters are defined
Actions
Code that is added to asciio (a plugin in an other term).
Asciio provides many actions but you can write your own and bind it to a keyboard shortcut.
Bindings
Registered keyboards shortcuts that execute actions.
Asciio configuration file
The default configuration is defined in :
- setup/setup.ini
Asciio’s default action binding files
- setup/actions/default_bindings.pl
- setup/Text/actions/vim_bindings.pl (which overrides default bindings)
User configuration file
Your user configuration file is at $HOME/.config/Asciio/Asciio.ini.
CONFIGURATION FORMAT
{
STENCILS =>
[
#'stencils/asciio',
],
ACTION_FILES =>
[
#'actions/xxx.pl',
],
HOOK_FILES =>
[
],
ASCIIO_OBJECT_SETUP =>
[
#$ASCIIO_UI eq 'TUI' ? 'asciio_object/tui.pl' : 'asciio_object/gui.pl' ,
],
IMPORT_EXPORT =>
[
#'import_export/ascii.pl',
],
}
Sections
STENCILS
Contains:
- files defining stencils present in the popup menus
- stencil files that you can drag and drop from
ACTION_FILES
Contains:
- your keyboard bindings
- functionality you want to add to asciio (that you bind keys to), plugins
HOOK_FILES
Contains:
- hooks called after elements have been modified and rendering the drawing starts, mainly used to call CANONIZE_CONNECTIONS.
ASCIIO_OBJECT_SETUP
Contains:
- setup variables that influence asciio’s behavior and appearance
asciio will first read the settings in ‘setup/asciio_object/basic.pl’ then read the settings in the files contained in this section.
Some of the default settings are listed below, refer to ‘setup/asciio_object/basic.pl’ for a complete list
COLOR_SCHEMES => # asciio has two color schemes, and a binding to flip between them
{
'night' =>
{
background => [0.04, 0.04, 0.04],
grid => [0.12, 0.12, 0.12],
grid_2 => [0.22, 0.22, 0.22],
...
},
'system' =>
{
background => [1.00, 1.00, 1.00],
grid => [0.89, 0.92, 1.00],
grid_2 => [0.79, 0.82, 0.90],
ruler_line => [0.33, 0.61, 0.88],
hint_line => [0.5, 0.80, 1],
hint_line2 => [0.4, 0.7, 0.9],
element_background => [1.00, 1.00, 1.00],
element_foreground => [0.00, 0.00, 0.00] ,
selected_element_background => [0.70, 0.95, 1.00],
selection_rectangle => [1.00, 0.00, 1.00],
...
}
},
COPY_OFFSET_X => 1, # x offset for paste
COPY_OFFSET_Y => 1, # y offset for paste
CREATE_BACKUP => 1, # create a '.bak' backup file when set
DISPLAY_GRID => 1, # display the asciio grid
DISPLAY_GRID2 => 1, # display every tenth grid line in grid_2 color
DISPLAY_RULERS => 1, # display the asciio ruler lines
DISPLAY_SETUP_INFORMATION_ACTION => 1, # display which actions are registered
DRAG_SELECTS_ARROWS => 0, # selection rectangle also selects arrows when set
...
RULER_LINES => # default ruler lines
[
...
],
...
IMPORT_EXPORT
Links to files which define import and export functionality, you could use this to save files to another format.
BINDINGS FORMAT
Asciio processes external configuration files that dynamically define the application’s keybindings, keybindings structure, and context menus.
These files are valid Perl scripts, you can defined code to bind to in the files but we recommend you create a module instead.
Action Definition Commands
Use the following commands to define commands:
| Subroutine Name | Purpose | Data Format Expected |
|---|---|---|
| register_action_handlers | Defines actions, and multi-level action groups. | |
| register_action_handlers_with_override | As above but also deletes old shortcuts | list of key-value pairs |
| TOP_LEVEL_GROUP | Defines the content of the top-level grouping used for menu display | shortcut and a list of action |
| GROUP | Used to declare a nested, ordered, action group. | |
| USE_GROUP | binds a shortcut with a group | |
| CONTEXT_MENU | Defines actions that are only accessible via a context menu |
Action Definition Formats
The definitions passed to register_action_handlers can take two primary forms:
- Single Action
- Group Definition
Single Action Definition
Single action definition are declared within a pair of square brackets (a Perl array ref).
| Index | Defines | Type | Purpose |
|---|---|---|---|
| 0 | SHORTCUTS | Scalar or ArrayRef | The keybindings that trigger the action |
| 1 | CODE | CodeRef | The Perl subroutine reference to execute when the shortcut is pressed. |
| 2 | ARGUMENTS | Scalar or ArrayRef | Optional arguments to be passed to the CODE subroutine. |
| 3 | OPTIONS | HashRef | Optional hash of flags or attributes for the binding |
Example of Single Action:
register_action_handlers
(
'Undo' =>
[
['C00-z', '000-u'], # [0] SHORTCUTS
\&App::Asciio::Actions::Unsorted::undo, # [1] CODE
-1, # [2] optional ARGUMENTS
{ ... }, # [3] optional BINDING OPTIONS
],
# ... more bindings
);
Binding Options
- HIDE => 1/0, controls if this binding is shown in the bindings help
GROUP Definition
Used for defining a collection of related commands.
The commands typically share a single shortcut that, when pressed, switches the application’s context to the commands defined within the group.
Group Control Keys
The definition must contain the following control keys at the top-level of the group:
| Key | Type | Purpose |
|---|---|---|
| SHORTCUTS | Scalar or ArrayRef | The keybinding(s) that activate/enter this group |
| ENTER_GROUP | CodeRef,ArrayRef or undef | Optional code to execute when the group is activated. |
| ESCAPE_KEYS | Scalar or ArrayRef | Optional keybinding(s) that deactivate/exit the group |
| ESCAPE_GROUP | CodeRef | Optional code to execute when the group is exited. |
| CAPTURE_KEYS | Pass as sub to ENTER_GROUP if you just want to capture keys | |
| HIDE | Scalar (0 or 1) | Optional atrribute, the group is hidden from bindingsdisplays. |
Group Actions
Following the control keys, an the ordered list of actions:
| Type | Purpose |
|---|---|
| ArrayRef | A Single Action Definition |
| GROUP | A Nested Group Definition |
| USE_GROUP | Command to switches to another group. |
Example of Group Definition:
register_action_handlers
(
'grouping ->' =>
GROUP # create a GROUP
(
# control keys
SHORTCUTS => '000-g',
ESCAPE_KEYS => '000-Escape',
# Single element
'selected elements' => [ '000-g', \&App::Asciio::Actions::ElementsManipulation::group_selected_elements ],
# Nested Group
'Subgroup' => GROUP
(
SHORTCUTS => '000-a',
'Align top' => ['000-t', \&App::Asciio::Actions::Align::align, 'top'],
),
'Enter Other Group' => USE_GROUP('other_group_name'),
),
# ... other actions
);
'group_other_group_name' => GROUP ( ...), # note that 'group_' is needed in the declaration of groups referred to by USE_GROUP
Binding override
You can re-bind an existing shortcut to another command ; Asciio will generate a warning in the console.
Overriding shortcut 'C00-y'
new is 'Redo 2' defined in file '.../actions/override_bindings.pl'
old was 'Redo' defined in file 'actions/default_bindings.pl'
For Developers
Scripting
# Generated by documentation/scripting/multi_wirl.pl
.------.
| box1 |<-----------------------------------.
'------' |
| .------.
| | box3 |
| '------'
| ^
| |
| .------. |
'-------------->| box2 |----------------'
'------'
__________
\ \
\ line 1 \
) line 2 )
/ line 3 /
/_________/
Executing your scripts
transform JSON, via Data::TreeDumper, to Asciio script
The *json_dtd_to_asciio_script’ script is installed with Asciio. It will read a JSON stream from stdin.
It takes the following arguments:
- title
- x position
- y position
- ‘box’, if you want the data to be boxed
- start_level, 0/1: 0 meanss no start tree grlyph
<coordinates_json ./script/json_dtd_to_asciio_script '' 10 10 box 0 | stdin_to_asciio # send json element to running asciio
Simplified scripting interface
The simplified scripting interface is an API which hides some of the scripting details for you.
Examples of scripts, using both the simplified API and full API, can be found in the documentation/scripting directory of the distribution.
Create a new Perl script
Crate a file and add these lines
use strict; use warnings;
use App::Asciio::Scripting ;
This will set some sanity checks on your code and load the simplified scripting interface.
Adding boxes
add 'box1', new_box(TEXT_ONLY =>'box1'), 0, 2 ;
add 'box2', new_box(TEXT_ONLY =>'box2'), 20, 10 ;
add 'box3', new_box(TEXT_ONLY =>'box3'), 40, 5 ;
The simplified scripting interface lets you name your object so you can later connect them together.
Adding connections
connect_elements 'box1', 'box2', 'down' ;
connect_elements 'box2', 'box3' ;
connect_elements 'box3', 'box1', 'up' ;
You can hint Asciio about the direction of your arrows.
Canonizing connections
Asciio tries to route the arrows properly, this is done automatically in the UIs but you need to do it manually in scripts.
optimize ;
Printing and saving the result
save_to "from_script.asciio" ;
ascii_out ;
You can save your work to an asciio file or print it out
Adding multi-wirl arrows
You can write more advanced script where you route multi sections arrows around your elements.
|
|
|
|
|
'----.
|
'----.
|
|
|
|
|
|
<--'
You’ll also need to use the right module; in fact you have access to everything that’s in Asciio from your scrips, it’s just a little bit more work than using the simplified interface.
# documentation/scripting/multi_wirl.pl
use strict; use warnings;
use App::Asciio::Scripting ;
#-----------------------------------------------------------------------------
add 'multi_wirl', new_wirl_arrow([5, 5, 'downright'], [10, 7, 'downright'], [7, 14, 'downleft']), 5, 5 ;
ascii_out ;
Full example
You can find more examples in the documentation/scripting/ library of the project.
# documentation/scripting/multi_wirl.pl
use strict; use warnings;
use App::Asciio::Scripting ;
#-----------------------------------------------------------------------------
add 'text1', new_text(TEXT_ONLY =>'text'), 22, 20 ;
add 'box1', new_box(TEXT_ONLY =>'box1'), 0, 2 ;
add 'box2', new_box(TEXT_ONLY =>'box2'), 20, 10 ;
add 'box3', new_box(TEXT_ONLY =>'box3'), 40, 5 ;
connect_elements 'box1', 'box2', 'down' ;
connect_elements 'box2', 'box3' ;
connect_elements 'box3', 'box1', 'up' ;
connect_elements 'box2', 'text1' ;
my $process = add_type 'process', 'Asciio/Boxes/process', 5, 15 ;
$process->set_text("line 1\nline 2\nline 3") ;
optimize ;
save_to "from_script.asciio" ;
ascii_out ;
Executing your script
From the command line
The script is a normal perl script.
perl my_asciio_script.pl
From within Asciio
Binding: «:!»
Pick the file you want to execute.
Or pass it on the command line
asciio -s full_path_to_script
Via Asciio’s Web server
You can POST scripts via HTTP.
Asciio runs a web server at port 4444; you can change the port with –port other_port.
script commands
POST http://localhost:4444/script script=“add ‘1’, new_box, 0, 0 ;”
You can have multiple commands in your script.
script file
POST http://localhost:4444/script_file script=“path_to_script”
connecting to Asciio Web server
- directly from your application for visualisation (python example)

- via a command line application like xh or httpie.
- piping to stdin_to_asciio script which is installed with asciio (uses xh).
# bash script that adds an element to an asciio instance, offsets it, and deletes it
# create a script to add one element, the script can contain many scripting commands
# httpie has a large startup time, use xh instead
script= ; for i in $(seq 1) ; do script="$script add '1', new_box(TEXT_ONLY =>'$i'), $((($i - 1) * 6)), $((($i - 1) * 4)) ;" ; done
# execute the script
xh -f POST http://localhost:4444/script script="$script"
# offset the element
for i in $(seq 25) ; do sleep .05 ; xh -f POST http://localhost:4444/script script="offset '1', 1, 1 ;" ; done
# delete the element
xh -f POST http://localhost:4444/script script="delete_by_name '1' ;"
Simplified Scripting API
APIs are defined in lib/App/Asciio/Scripting.pm
stop_updating_display
Stops updating the display until start_updating_display is called; this can be used to reduce flickering.
stop_updating_display
start_updating_display
Start updating the display; display will automatically be updated from when this is called. An update is also made.
start_updating_display
create_undo_snapshot
Creates an undo snapshot.
create_undo_snapshot ;
add
Adds a named element:
- element_name
- element, see new_box new_text, … below
- x coordinate
- y coordinate
add 'text1', new_text(TEXT_ONLY =>'text'), 22, 20 ;
delete_by_name
Deletes an element by name
delete_by_name 'text1' ;
delete_selected_elements
Deletes selected elements
delete_selected_elements ;
add_type
Adds a named element:
- element_name
- element_type
- x coordinate
- y coordinate
Returns the element.
my $process = add_type 'process', 'Asciio/Boxes/process', 5, 15 ;
new_box
Creates a new box element. Use it with add.
new_box() ; # default box text
new_box(TEXT_ONLY =>'text') ;
new_text
Creates a new text element. Use it with add.
new_text(TEXT_ONLY =>'text') ;
new_wirl_arrow
Creates a new wirl-arrow element. Use it with add.
Pass wirl arrow section coordinates and directions as arguments.
new_wirl_arrow([5, 5, 'downright'], [10, 7, 'downright'], [7, 14, 'downleft']) ;
move
Moves a namex element to a new coordinate:
- element name
- x position
- y position
move 'text1', 22, 20 ;
offset
Offsets a named element:
- element name
- x offset
- y offset
offset 'text1', 22, 20 ;
change_selected_elements_color
Changes selected elements background or foreground color.
change_selected_elements_color 1, [1, 0, 0] ; # foreground color to red
select_by_name
Selects an elements by name.
select_by_name 'A' ;
select_all_elements
Selects all the elements in Asciio.
select_all_elements ;
deselect_all_elements
Deselects all the elements in Asciio.
deselect_all_elements ;
select_all_script_elements
Selects all the elements added by the script.
select_all_script_elements ;
deselect_all_script_elements
Deselects all the elements added by the script.
deselect_all_script_elements ;
connect_elements
Connects named elements with a wirl-arrow.
connect_elements 'box2', 'text1' ;
optimize
Optimizes the connections.
optimize
delete_all_ruler_lines
Deletes all ruler lines.
delete_all_ruler_lines ;
add_ruler_line
Adds a ruler line.
- axis: ‘vertical’ or ‘horizontal’
- position
add_ruler_line 'vertical, 10 ;
save_to
Saves the diagram to a file in Asciio’s native format.
save_to 'diagram.asciio' ;
to_ascii
Returns the diagram as ASCII.
to_ascii ;
ascii_out
Prints the diagram, as ASCII, to stdout.
ascii_out ;
Modifying Asciio
Bindings
Goals when adding bindings:
-
keep code separate from other bindings code if the new bindings are not very general, ie: code them in their own module
-
align the structures
-
avoid long or generic or numbered name
-
if possible the bindings should be the same as the vim-bindings
- some GUI standards may require different bindings, IE: C00-A to select everything
-
create an equivalent binding set in the vim bindings file
-
documents the bindings
- name, keep them logical, start with an uppercase
- key
- what they do, preferably with some screenshot
-
don’t use control, shift and alt if possible (logical)
-
split groups if they become too large
-
sort by name or key if possible
Capturing groups with overlay

Define overlays
my $click_choice_element = ['Asciio/box', 0] ;
my $box_overlay =
[
[0, 0, '.'],
[1, 0, '-'],
[2, 0, '-'],
[3, 0, '-'],
[4, 0, '.'],
[0, 1, '|'],
[4, 1, '|'],
[0, 2, "'"],
[1, 2, '-'],
[2, 2, '-'],
[3, 2, '-'],
[4, 2, "'"],
] ;
my $text_overlay =
[
[0, 0, 'T.'],
[1, 0, 'e'],
[2, 0, 'x'],
[3, 0, 't'],
] ;
my $arrow_overlay =
[
[2, -2, '.'],
[3, -2, '-'],
[1, -1, '/'],
[0, 0, "'"],
] ;
Declare callbacks
my $click_element_overlay = $box_overlay ;
sub click_choice_add_element { App::Asciio::Actions::Elements::add_element($_[0], $click_choice_element) ; }
sub click_element_choice
{
my ($asciio, $args) = @_ ;
($click_element_overlay, $click_choice_element) = $args->@* ;
$asciio->update_display ;
}
sub click_element_enter { print "enter!!\n" ; my ($asciio) = @_ ; $asciio->set_overlays_sub(\&click_element_overlay) ; $asciio->update_display ; }
sub click_element_escape { my ($asciio) = @_ ; $asciio->set_overlays_sub(undef) ; $asciio->update_display ; }
sub click_element_mouse_motion
{
my ($asciio, $event) = @_ ;
App::Asciio::Actions::Mouse::mouse_motion($asciio, $event) ;
$asciio->update_display() ;
}
sub click_element_overlay
{
my ($asciio) = @_ ;
my @overlays = map { [ $asciio->{MOUSE_X} + $_->[0], $asciio->{MOUSE_Y} + $_->[1], $_->[2] ] } @$click_element_overlay ;
@overlays
}
Declare bindings
register_action_handlers
(
'insert on click' =>
{
SHORTCUTS => '0A0-i',
ENTER_GROUP => \&click_element_enter,
ESCAPE_KEY => '000-Escape',
'click element escape' => [ '000-Escape', \&click_element_escape ],
'click element motion' => [ '000-motion_notify', \&click_element_mouse_motion ],
'click element insert' => [ '000-button-press-1', \&click_choice_add_element ],
'click element arrow' => [ '000-a', \&click_element_choice, [$arrow_overlay, ['Asciio/angled_arrow', 0]] ],
'click element box' => [ '000-b', \&click_element_choice, [$box_overlay, ['Asciio/box', 0]] ],
'click element text' => [ '000-t', \&click_element_choice, [$text_overlay, ['Asciio/text', 0]] ],
},
) ;
Debugging
See the Debugging bindings.
Asiio can output to the console, any call to print will be displayed in it.
You can use Data::TreeDumper to display structured debug output.
You can of course run Asciio in the perl debugger.
Basic introduction
When the borders of two text elements intersect, we generate some compensating characters to cover the borders, resulting in nicer graphics
| ││ │ │
| ││ │ │
-----|---> ──││────│──│─
| ││ │ │
| ││ │ │
v
Look at the text above, their borders are overlapping each other. The text we need to generate is as follows:
| ││ │ │
| ││ │ │
-----+---> ──┼┼────┼──┼─
| ││ │ │
| ││ │ │
v
We need to generate padding characters at their boundaries, then the steps are as follows:
- find the cross point.
- Determine the characters to be filled at the current cross point according to the characters around the cross point.
- Determine whether the current cross point has the expected fill character, if so, keep it, if not, add it, and delete the old fill character.
- remove all filling characters that are not at cross points.
- update drawing.
Detailed steps
Find the cross point
The cross point must be the coverage of characters, and the characters that cover each other are the characters we care about.
The characters we care about refer to commonly used tab characters, or ascii plus dots, etc.
Commonly used symbols include these, of course not only these
'-', '|', '.', '\'', '\\', '/', '+',
'─', '│', '┼', '┤', '├', '┬', '┴', '╭', '╮', '╯', '╰',
'━', '┃', '╋', '┫', '┣', '┳', '┻', '┏', '┓', '┛', '┗',
'═', '║', '╬', '╣', '╠', '╦', '╩', '╔', '╗', '╝', '╚',
'╫', '╪', '╨', '╧', '╥', '╤', '╢', '╡', '╟', '╞', '╜',
'╛', '╙', '╘', '╖', '╕', '╓', '╒'
condition of cross points:
- text elements crossed
- The two characters that intersect each other are the characters we care about
When the condition is found to be met, both characters need to be logged. At the same time, we need to record the characters around the cross point, because they absolutely determine what kind of cross point is generated.
Record the upper, lower, left, and right characters. If you want to achieve diagonal crossing, you also need to record characters at 45 degrees, 135 degrees, 225 degrees, and 315 degrees.
Judgment scene
General situation
First of all, all cross characters are directional, we need to group them by direction and type.
Let me give you an example, if the center has generated a character┼,
Then we can use the method of proof by contradiction, its left side
must be these characters, otherwise it is unreasonable.
'─', '┼', '├', '┬', '┴', '╭', '╰'
These characters all can appear to the left of it(Because their right sides
can be extended to become a line), But if these characters do not appear on
the left side of ┼, then we think it is unreasonable to use this ┼, and
the disproof condition is false.
'-', '|', '.', '\'', '\\', '/', '+',
'─', '│', '┼', '┤', '├', '┬', '┴', '╭', '╮', '╯', '╰',
'━', '┃', '╋', '┫', '┣', '┳', '┻', '┏', '┓', '┛', '┗',
'═', '║', '╬', '╣', '╠', '╦', '╩', '╔', '╗', '╝', '╚',
'╫', '╪', '╨', '╧', '╥', '╤', '╢', '╡', '╟', '╞', '╜',
'╛', '╙', '╘', '╖', '╕', '╓', '╒'
Make assumptions about the occurrence of each possible padding crossing character above, untilSupposed to be true.
│
──│──
│
For the plus sign, the condition for its appearance is that:
- A character in the upper character set appears in the upper direction
- A character in the down direction character set appears in the down direction
- A character in the left-direction character set appears in the left direction
- A character in the right-direction character set appears in the right direction
If these conditions are met, the intermediate characters can be corrected as ┼:
│
──┼──
│
Let’s look at a more complex situation, The intersection below, we know, needs
one ╤ to fill.
═══│════
│
│
For the ╤ sign, the condition for its appearance is that:
- Left is one of the left characters of the double-line character set
- Right is one of the right characters of the double-line character set
- Down is one of the down characters in the single-line character set
- Up cannot be one of the up characters in the single-line character set
Pay attention to the bold part above, because if this condition is true,
then the filling character should be ╪, not ╤.
Improve efficiency
There is no need to perform calculations every time to determine the characters filled in the middle. Whenever a new scene calculation occurs, we can save the calculation result in a cache and read it directly next time without performing logical calculations again.
A hash table is most suitable for this, and the hash key can use a combination of upper, lower, left, and right characters(The oblique lines are the four diagonal directions.).
An additional case needs to be considered separately
││
──││─────
││
││
please see this text, It is expected that we are going to get the following text:
││
──┼┼─────
││
││
As you noticed, there are two plus signs filled.
Let’s take the point that needs to be filled on the left as an example:

We can see that characters in three directions meet the requirements, but characters in one direction do not meet the requirements. But the point on the right is actually also an cross point, it has two characters, one in the foreground and one in the background. The character in the background is ok, so we think it ok!
In summary: If the character next to it is also an cross point, then either the foreground character or the background character of the intersection can meet the requirements.So I said earlier that the foreground and background characters of the cross point all need to be recorded.In fact, there may be more than one character that meets the condition in the background, so all of these characters need to be considered, not just limited to 2 characters.
The case of character coverage
There is another situation that needs to be explained separately,Similar to above but slightly different
╭─────╮
│ ╭─────╮
│ │ │
│ │ │
╰─│ │
╰─────╯
The text we need to get is this:
╭─────╮
│ ╭───┴─╮
│ │ │
│ │ │
╰─┤ │
╰─────╯
This looks like two boxes stacked,According to the above statement, the overlapping parts, both foreground characters and background characters must be considered.**But not like this!**The overlapping foreground characters are spaces, and spaces are not characters in the character set, so they are not considered.
To put it simply: as long as it is not an cross point, only foreground characters are considered.
The definition of the cross point has already been mentioned in the previous chapter
A method to simplify logical judgment
When we determine what characters should be filled in a point, we first consider the characters in the four directions. Then after these characters are considered, characters in three directions are considered, and finally characters in two directions are considered. The advantage of this is that if the characters in the four directions do not meet the conditions, then when judging the characters in the three directions, there is no need to repeatedly consider that a certain character may be a character in the four directions, because it has been ruled out before. Similar logic is used for two-way characters. This can greatly reduce the complexity of logical judgment.
A better judgment algorithm
Use 3 bits to represent the attributes of chars in each direction.
none : 0
ascii : 1
thin : 2
bold : 3
double : 4
dotted : 5
bold dotted : 6
A 32-bit integer can precisely represent all attributes of a character.
┃ 315 ┃ 225 ┃ 135 ┃ 45 ┃right┃left ┃down ┃ up
│3│3│2│2│2│2│2│2┃2│2│2┃2│1│1┃1│1│1┃1│1│1┃1│1│ ┃ │ │ ┃ │ │ ┃ │ │ │
│1│0│9│8│7│6│5│4┃3│2│1┃0│9│8┃7│6│5┃4│3│2┃1│0│9┃8│7│6┃5│4│3┃2│1│0│
───┼─┼─┼─┼─┼─┼─┼─┼─╂─┼─┼─╂─┼─┼─╂─┼─┼─╂─┼─┼─╂─┼─┼─╂─┼─┼─╂─┼─┼─╂─┼─┼─┼───
┼│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │1│ ┃ │1│ ┃ │1│ ┃ │1│ │
┤│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │1│ ┃ │ │ ┃ │1│ ┃ │1│ │
╫│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │1│ ┃ │1│ ┃1│ │ ┃1│ │ │
>│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │1┃ │ │ ┃ │ │ ┃ │ │1│
<│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │1┃ │ │ ┃ │ │1│
+│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │1┃ │ │1┃ │ │1┃ │ │1│
│ │ │ │ │ │ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ ┃ │ │ │
To determine what character a crosspoint should be, we should take the neighbors in the eight directions of this crosspoint.
Then, we need to look at the properties of these eight characters. The judgment logic is as follows:
- The character above takes the properties of the part below.
- The character to the left takes the properties of the part to the right.
- The character below takes the properties of the part above.
- The character to the right takes the properties of the part to the left.
- The character at 45 degrees takes the properties of the 225-degree part.
- The character at 135 degrees takes the properties of the 315-degree part.
- The character at 225 degrees takes the properties of the 45-degree part.
- The character at 315 degrees takes the properties of the 135-degree part.
In this way, after extracting the character attributes from the eight directions and performing bitwise operations, we can concatenate them into a new complete 32-bit integer. By looking up a table, we can determine the character corresponding to this new integer (if it’s 0, then it’s an empty character, indicating no intersecting characters).
This allows us to obtain the character at the center point. There’s no need for complex calculations or caching.
The current code uses this algorithm.
Unicode character classification
- characters of length 1
- characters of length 2
- characters of length 0
The length mentioned here refers to the printed length of the characters, that is, the length seen by the eyes
Characters of length 1
Most unicode characters are characters with a length of 1, such as the commonly used tab character, ascii characters.
a b c d , . ┼ ┬ │
Characters of length 2
Characters with a typographical width of 2 refer primarily to East Asian pictographs and related special punctuation, as well as full-width characters.
你好啊!《》
안녕하세요
こんにちは
They need to occupy two grids in the UI interface. Then aligning them requires special fonts that align 2:1 with width 1 characters.Here is a commonly used font.
https://github.com/be5invis/Sarasa-Gothic/
These characters have a special property called East Asian Width. They are included in the unicode standard, so they can be used as a programming basis.
Links to the unicode standard: https://www.unicode.org/reports/tr11/tr11-40.html
In perl’s unicode documentation, corresponding properties are also provided to use.
This represents a wide character, occupying two spaces:
\p{EA=W}
This represents a full-width character, which also occupies two spaces:
\p{EA=F}
The above information can be found here:
https://perldoc.perl.org/perlunicook
https://perldoc.perl.org/perlunicode
Characters of length 0
In some languages, there are special characters whose string length is 1, but they do not occupy physical space on the interface, they will be attached to the previous characters.they are called nonspacing characters.Occurs in Thai and Arabic, as well as Hebrew
◌ั ◌ึ ◌ุ
Please look at the above characters, they cannot appear alone, they must be used in combination with the previous entity characters, and then they will appear above or below the previous characters.
These characters are called Nonspacing characters in the unicode standard, and then they have the following properties that can be used for programming
\p{gc:Mn}
To support Thai, or Arabic, or Hebrew, like East Asian languages, we also need a special font that can be aligned.In general, the system’s default monospaced font can align them
Overlay
After Asciio draws the elements, a user defined call back is called.
User defined callback
The callback receives an instance of Asciio as the first argument, you can use that instance to get elements, …
The callback return a list of 1character overlay in array references:
- x coordinate
- y coordinate
- character
- optional background color
- optional foreground color
Example list:
[ 0, 0, 'T'],
[ 1, 0, 'e'],
[ 2, 0, 's'],
[ 3, 0, 't'],
Setting and resetting the callback
The callback is set by calling $asciio->set_overlays_sub. The simplest is to do it via a key binding.
'set overlays' =>
[
'0A0-o',
sub
{
my ($asciio) = @_ ;
$asciio->set_overlays_sub
(
sub { [0, 0, 'O'], [1, 0, 'K'] }
) ;
$asciio->update_display ;
}
],
Reset the callback
'reset overlays' => [ '000-o', sub { $_[0]->set_overlays_sub(undef) ; $_[0]->update_display ; } ],
Callback access to canvas
The callback can also have access to the canvas, but don’t
Arguments:
- $asciio
- $UI_type, set to GUI/TUI
- $gc
- $widget_width
- $widget_height
- $character_width
- $character_height
Example: draw and overlay and a filled rectangle above the mouse pointer
sub click_element_overlay
{
my ($asciio, $UI_type, $gc, $widget_width, $widget_height, $character_width, $character_height) = @_ ;
# draw directly
if($UI_type eq 'GUI')
{
my $surface = Cairo::ImageSurface->create('argb32', 50, 50) ;
my $gco = Cairo::Context->create($surface) ;
my $background_color = $asciio->get_color('cross_filler_background') ;
$gco->set_source_rgb(@$background_color) ;
$gco->rectangle(0, 0, $character_width, $character_height) ;
$gco->fill() ;
$gc->set_source_surface($surface, ($asciio->{MOUSE_X} - 1 ) * $character_width, ($asciio->{MOUSE_Y} - 1) * $character_height);
$gc->paint() ;
}
# send a list of characters to draw
my @overlays = map { [ $asciio->{MOUSE_X} + $_->[0], $asciio->{MOUSE_Y} + $_->[1], $_->[2] ] } @$click_element_overlay ;
@overlays
}
Callback hide/show mouse
Hide and show the mouse pointer, useful if you draw objects that are moved around.
sub callback_enter { my ($asciio) = @_ ; $asciio->hide_cursor ; ... }
sub callback_escape { my ($asciio) = @_ ; $asciio->show_cursor ; ... }
Functionality Log
Freeze Element [30 Dec 2025]
Graph Selection [1 Jan 2026]
Contributors
Khemir Nadim ibn Hamouda
https://github.com/nkh
CPAN ID: NKH
Qin Qing
northisland2017@gmail.com
Unicode support, scroll bar, and rhombus object
License and copyright
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself or GPL3.
See Also
SVG conversion: goat
Tree generation: ascii_tree
ASCII Math and other: Diagon
AACircuit, fun!
shaape, quite impressive!
Stencils Asciio ditaa
Source for some of the network stencil Ascii art
*\o_ _o/*
/ * * \
<\ *\o/* />
)
o/* / > *\o
<\ />
__o */\ /\* o__
* /> <\ *
/\* __o_ _o__ */\
* / * * \ *
<\ />
*\o/*
ejm97 __)__
