[[file:https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg]] #+TITLE: Conlanging layer #+AUTHOR: Lucien “P’undrak” Cartier-Tilet #+PROPERTY: header-args :noweb yes :exports code #+PROPERTY: header-args:dot :tangle no :exports code [[img/conlang_flag.png]] * Table of Contents :TOC_4_gh:noexport: - [[#description][Description]] - [[#features][Features]] - [[#graphviz-trees][Graphviz trees]] - [[#install][Install]] - [[#licence][Licence]] - [[#documentation][Documentation]] - [[#functionalities][Functionalities]] - [[#graphviz-trees-generation][Graphviz trees generation]] * Description This layer adds features for conlanging. ** Features - Generate graphviz trees based on Elisp trees - Replace some text by its runic equivalent (supports the Mattér and Eittlandic languages) - Adds phonetics to Proto-Ñyqy text - Provides custom shortcuts ** Graphviz trees The ~conlanging~ layer provides one public function called ~conlanging/tree-to-dot~. It accepts as its sole argument a list of strings or lists, such as the following: #+NAME: vowels-example #+BEGIN_SRC emacs-lisp :noweb yes (setq-local vowels '("[vowel]" ("[back]" ("[tense]" ("[high]" ("ü")) ("{high}" ("ö"))) ("{tense}" ("[high]" ("u")) ("{high}" ("o")))) ("{back}" ("[tense]" ("[high]" ("y")) ("{high}" ("ë"))) ("{tense}" ("[high]" ("i")) ("{high}" ("e")))))) #+END_SRC When passed in the above mentioned function, and the result itself is passed through graphviz, we get the following result: #+NAME: tree-vowels #+BEGIN_SRC emacs-lisp :exports results :noweb yes :cache yes <> (conlanging/tree-to-dot vowels) #+END_SRC #+BEGIN_SRC dot :file img/vowels-example.png :var input=tree-vowels :exports results $input #+END_SRC #+NAME: arbre:vow #+ATTR_HTML: :alt Exemple d’arbre de voyelles #+RESULTS: [[file:img/vowels-example.png]] This example tree is only a binary tree, but a single node can have up to ten children. See some examples in the [[https://labs.phundrak.com/phundrak/langue-phundrak-fr/blob/master/proto-nyqy.org][Ñyqy source file]]. It is planned to merge [[https://labs.phundrak.com/phundrak/distinctive-features-chooser][this project]] into this layer in order to facilitate the creation of trees based on distinctive features. * Install To install this layer, either clone this project in your =~/.emacs.d/private/= folder, or symlink it from there to your actual clone location. Then, add =conlanging= in your dotspacemacs file in the =dotspacemacs-configuration-layers= list: #+begin_src emacs-lisp (setq-default dotspacemacs-configuration-layers '(conlanging)) #+end_src You can then reload your configuration file with ~SPC f e R~, or restart Emacs with ~SPC q r~ or ~SPC q R~. * Licence All the code included in this repository is licensed under the GPLv3 license. See [[file:LICENCE]]. * Documentation The following is the documentation of the source code of the ~conlanging~ layer. It is divided in two main parts, describing the two main files of the layer: ~funcs.el~ and ~keybindings.el~. First of all, let’s simply describe the ~layer.el~ file. #+BEGIN_SRC emacs-lisp :tangle layers.el (configuration-layer/declare-layer 'conlanging) #+END_SRC And that’s enough for the ~layer.el~ file! Now, onto the ~funcs.el~ file. ** Functionalities :PROPERTIES: :HEADER-ARGS: :tangle funcs.el :END: Here will be detailed the functionalities of the ~conlanging~ layer. It can be divided in several parts. *** Graphviz trees generation As described above, it is possible to create graphviz trees from Elisp trees made from lists. This feature is coded in two functions: one that creates the tree itself, and one that generates nodes. The first one that generates nodes is declared as a private function (actually, it’s just prefixed with ~conlanging//~ following Spacemacs’ [[https://www.spacemacs.org/doc/CONVENTIONS.html#spacemacs-core-and-layer][naming convention]]). #+BEGIN_SRC emacs-lisp (defun conlanging//declare-node (t-node-text t-node-generation) "Declares a node in the graphviz source code. The node’s identifier will be `t-node-generation', and it will bear the label `t-node-text'." (format "%d[label=\"%s\"];" t-node-generation t-node-text)) #+END_SRC This can result in a graphviz node declared like so: #+BEGIN_SRC dot 231[label="This is a label"]; #+END_SRC All nodes generated by the function have a unique identifier in the form of a number, and its content is only defined by its label. By default, the tree created from the graphviz code gives a tree from top to bottom with the label not surrounded by anything. Let’s declare our whole function: #+BEGIN_SRC emacs-lisp (defun conlanging/tree-to-dot (t-tree &optional t-current-generation t-previous-generation) "Translates an Elisp t-tree with any number of children per node to a corresponding graphviz file that can be executed from dot. Arguments: - `t-tree': t-tree to convert - `t-current-generation': generation number, incremented when changing from a node to another node from the same generation, multiplied by 10 when going from a node to one of its children. - `t-previous-generation': generation number from previous named node" (cond ((null t-previous-generation) ;; first call (concat "graph{graph[dpi=300];node[shape=plaintext];graph[bgcolor=\"transparent\"];" (conlanging//declare-node (car t-tree) 0) (conlanging/tree-to-dot (cdr t-tree) 1 0) "}")) ((null t-tree) "") ;; last call in this branch ((atom (car t-tree)) ;; '("text" () () ()) manage the label (concat (conlanging//declare-node (car t-tree) t-current-generation) ;; make link (concat (number-to-string t-previous-generation) " -- " (number-to-string t-current-generation) ";") (conlanging/tree-to-dot (cdr t-tree) (+ 1 (* 10 t-current-generation)) t-current-generation))) ((listp (car t-tree)) ;; '(() () ()) manage the branches (concat (conlanging/tree-to-dot (car t-tree) ;; child of current node t-current-generation t-previous-generation) (conlanging/tree-to-dot (cdr t-tree) (+ 1 t-current-generation) t-previous-generation))))) #+END_SRC