Quill is a nim js library for making text editors, it is made completely in nim and is designed to be easy to use.
Example
The example can be found at https://thatrandomperson5.github.io/Quill/example
Docs
Docs can be found at https://thatrandomperson5.github.io/Quill/quill
Installing
nimble install https://github.com/thatrandomperson5/Quill
Guide
We first need to add some css to our main html file:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/thatrandomperson5/quill@master/js/quill.css">
After that we can start coding. A quill has a structure to get it to work:
- Create the quill
- Set any default text
- Add onDraw
- Main html generation
- Sector entering or forced redraw
- Init extentions and then quill
Here is a basic example:
# From tests import quill, dom var myquill = newQuill(document.getElementById("quill"), "70vh") # create the quill with height of 70 myquill.text = "Hello world" # Set the default text myquill.onDraw = proc (q: var Quill, str: cstring, isDel: bool) = # Main html generation let txt = document.createElement("span") txt.appendChild document.createTextNode(str) q.draw(txt) myquill.init() # Start the quill
Note: There is no reason to redraw if you don't use insert(), will be explained in more detail later on.
This is the most basic quill! But it does not do anything, so is there anything diffrent then a normal textarea? Well, the draw proc takes html, so you can color and style as much as you want! Try making the span a random color! You can also use the features described below to help you.
Insert and sectors
You can have a insert() call in your ondraw proc. This adds text, for example an indent, to your quill. This inserts at the current cursor position, if you want to add text a diffrent way, use the text= proc.
There are also sectors, which reduce the text passed to onDraw. Say for example your quill only needed to process words and you have this sentance: hello world good souls. Normally your draw proc would get passed the whole thing each time, but when processing "world", your code does not need anything from "hello". So, when you detect a space, you would enter a sector using enter(). This would mean if the word "hello" was changed to "hi" you would get passed "hi" instead of "hi world good souls". This feature is mainly for efficiency, and a full example can be found in the tests folder.
Note: Why is my inserted text not showing? You have to have a myquill.forceRedraw() at the end to make it show.
Warning: forceRedraw() and enter() must be the last call in your draw proc, also note that enter() replaces forceRedraw().
Gutter
To add a gutter (numbers on the side), just add the code below:
# After import quill import quill/ext/gutters # Right before myquill.init() myquill.initGutter()
Types
Quill = ref object internalElm: Element onDraw*: QuillOnDraw sectors: seq[int] current: int plen: int
QuillOnDraw = (var Quill, cstring, bool) -> void
QuillOnSegment = (Quill, cstring) -> seq[cstring]
Vars
documentElement: Element
Procs
proc enter(q: var Quill; pos: int) {....raises: [Exception], tags: [RootEffect].}
-
Enter a new sector at pos relative to the current sector
Note: Must be the last call in a onDraw
proc eventElement(q: Quill): Element {....raises: [], tags: [].}
- For extentions, like quill/ext/gutters
proc forceRedraw(q: var Quill) {....raises: [Exception], tags: [RootEffect].}
- Force the redrawing of quill q
proc init(q: var Quill) {....raises: [Exception], tags: [RootEffect].}
- "Turns on" the quill, nothing will work or show properly until this is called
proc insert(q: var Quill; text: cstring) {....raises: [], tags: [].}
- Insert text at users current position
proc newQuill(e: Element; height: cstring = "30vh"): Quill {....raises: [], tags: [].}
-
Create a new quill of height height and make all needed elements
Note: Might not look right without the proper css
proc text(q: Quill): cstring {....raises: [], tags: [].}
- Get the text/value of a quill, directly what the user inputed
proc text=(q: var Quill; replacment: cstring) {....raises: [], tags: [].}
- Set the text of a quill (as an user input, so you cannot set html tags)
proc visualElement(q: Quill): Element {....raises: [], tags: [].}
- For extentions, like quill/ext/gutters