Email: zach@zfadd.is
Social: @zacharius@refactorcamp.org
Git: github.com | git.zfadd.is

ZacharyFaddis

Oct. 11, 2018, 8:01 p.m.

Literate Programming Presentation

Intro

I recently gave a short presentation at EmacsATX, Austin’s local Emacs Meetup, about the literate progamming functionality baked into two major modes(packages) for Emacs, Org Mode and Babel.

If this is something your interested in learning about I recommend Howardism’s Introduction to Literate Programming as he wrote out a much better guide than I could. However I am including my own material below as I think I do have a couple larger and more fleshed out examlpes of ways that I use the functionality in my own life, namely partial documentation for a binary tree file and my emacs configuration file.

Please keep in mind that this was not made to make much sense without my own commentary and that I’m mainly putting it here as a resource for someone who already knows about literate programming in Org mode, from Howard’s blog, the Org manual, or elsewhere, but wants to see some examples of people actually doing something useful with it. Also I keep promising myself I’ll share more of what I’m doing through this outlet.

If you want to see the original Org file with which I gave the presentation and am exporting to HTML below, you can find it here

Presentation

literate programming: what is it good for

  • literate programming The idea of mixing code and prose in a seamless manner
  • weaving Presenting the prose/code in a format for humans, documentation
  • tangling puting the code together in a way that can be understood by a computer, source code

code blocks in Org Mode

Source code can be easily inserted into an org file to make it obvious that what you are looking at is code. It allows syntax highlighting and even code execution with the package Babel.

All Source code should be inserted inside a source block.

<s TAB
Create Template of a source block After this you must type the language being use after BEGINSRC

  • Commands for buffer
    C-c C-e
    org export
    C-s
    toggle export scope
    C-c C-v C-t
    tangle all code blocks in file that have tangling enabled
    C-c C-x p
    set property for section
  • commands inside source block
    C-c ’
    open a new buffer for you to type your code into. When this buffer is saved your code will appear inside the source block
    C-c C-c
    execute code block, must give permission by language in your config file
    C-c C-v C-v
    expand noweb references and show in new buffer, which can’t be modified
  • header arguements
    :file
    output results to file
    :tangle
    whether to allow tangling and where to store it
    no
    default, code block wont be tangled
    yes
    allow tangling, will be written to file with same name but with but with language specific file extension
    filename
    block will be written to specified filename
    :results
    how code will be evaluated and results presented
    • collection options(can only use one of these)
      value
      functional mode, Default, returns what the code returns
      output
      scripting mode, returns what the code prints
    • type of output to return(choose one)
      table
      format as org table
      list
      format as org list
      scalar, verbatim
      return results verbatim
      file
      interpret as path to file. inserts a link to the file
    :dir
    execute source block from specified directory
    :var
    pass in variable to
    :exports
    how block will act when exporting
    code
    default, only export code
    results
    export the results of executing a code block
    both
    return code and results
  • capturing output

    Executing code will result in a the ouput being printed under a RESULTS property tag. Babel will try to format the ouput for you but you can configure it yourself with the :results header

           ls /home/z
    
         file $args
    
  • Arguments to code blocks
    return x**2
    
    81
    
    
           print(listl)
    
           ls
    
  • weaving and tangling code

    the header arguement noweb allows you to weave multiple code blocks together

    print('Hello World!')
    
    age = 1
    lifespan = 10
    while age <= lifespan:
        print"Happy Birthday, you are ", age, "years old!"
        age += 1
    print('Goodbye cruel world!') 
    
    print('Hello World!')
    
    age = 1
    lifespan = 10
    
    print('Goodbye cruel world!') 
    

weaving together init files with org mode and babel

Binary Tree

A hierarchical data structure in which each node contains pointers for up to two children nodes, refered to as left and right node.

  • properties
    Maximum nodes at level n
    2(n-1)
    Maximum nodes in tree of height n
    2^
    Minimum possible height of tree with n nodes
    ceil(Log2(n+1))
  • O(n) of common operations, assuming tree is height balanced
    Search
    O(Log n)
    Insert
    O(Log n)
    Delete
    O(Log n)
    Traversal
    O(Log n)
class BiTree():

    def __init__(self, data):
        self.data = data
        self.lBranch = None
        self.rBranch = None

    def set_right(self, node):
        self.rBranch = node


    def set_left(self, node):
        self.lBranch = node

    def insert(self, data):
    
        if data == self.data:
            raise ValueError('data already in tree')
    
        if data < self.data:
            if self.lBranch == None:
                self.lBranch = BiTree(data)
            else:
                self.lBranch.insert(data)
    
        if data > self.data:
            if self.rBranch == None:
                self.rBranch = BiTree(data)
            else:
                self.rBranch.insert(data)

    def inOrderTraversal(self):
        if self.lBranch:
            self.lBranch.inOrderTraversal()
    
        print(self.data)
    
        if self.rBranch:
            self.rBranch.inOrderTraversal()

    def preOrderTraversal(self):
        print(self.data)
    
        if self.lBranch:
            self.lBranch.preOrderTraversal()
    
        if self.rBranch:
            self.rBranch.preOrderTraversal()

    def postOrderTraversal(self):
        if self.lBranch:
            self.lBranch.postOrderTraversal()
    
        if self.rBranch:
            self.rBranch.postOrderTraversal()
        
        print(self.data)
import sys
sys.path.append('/home/z/bin')
from biTree import BiTree

tree = BiTree(10)
tree.insert(5)
tree.insert(100)
tree.insert(25)
tree.insert(1)
tree.insert(500)
tree.insert(8)

print('In Order traversal: ')
tree.inOrderTraversal()

print('Pre Order traversal: ')
tree.preOrderTraversal()

print('Post Order traversal: ')
tree.postOrderTraversal()

  In Order traversal: 
  1
  5
  8
  10
  25
  100
  500
  Pre Order traversal: 
  10
  5
  1
  8
  100
  25
  500
  • insertion
    def insert(self, data):
    
        if data == self.data:
            raise ValueError('data already in tree')
    
        if data < self.data:
            if self.lBranch == None:
                self.lBranch = BiTree(data)
            else:
                self.lBranch.insert(data)
    
        if data > self.data:
            if self.rBranch == None:
                self.rBranch = BiTree(data)
            else:
                self.rBranch.insert(data)
    
  • Traversals

    There are a number of ways to iterate through, or traverse, a tree

    • In Order

      visit the left branch, then the current node, and finally the right branch

      def inOrderTraversal(self):
          if self.lBranch:
              self.lBranch.inOrderTraversal()
      
          print(self.data)
      
          if self.rBranch:
              self.rBranch.inOrderTraversal()
      
    • Pre Order

      vist the current node, then left tree, and finally the right tree

      def preOrderTraversal(self):
          print(self.data)
      
          if self.lBranch:
              self.lBranch.preOrderTraversal()
      
          if self.rBranch:
              self.rBranch.preOrderTraversal()
      
    • Post Order

      vist the left tree, then the right tree, and finally the parent node

      def postOrderTraversal(self):
          if self.lBranch:
              self.lBranch.postOrderTraversal()
      
          if self.rBranch:
              self.rBranch.postOrderTraversal()
              
          print(self.data)
      

emacs config

   (org-babel-load-file "~/.emacs.d/config.org")
  • Emacs
    • Package Management

      load the package manager, package, add several archives for package to pull from

        ;(require 'package)
      
        ;  (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
        ;  (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
        ;  (add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/"))
      
        ;  (setq package-enable-at-startup nil)
         ; (package-initialize)
      
    • Personal Info
           (setq user-full-name "Zachary Faddis"
                 user-mail-address "zach@zfadd.is")
      
    • Display
      • Theme
          (load-theme 'nimbus)
        
      • Line Numbers
          (global-linum-mode 1)
        
      • Line Limit

        Limit Line Length to 80. Whenever I exceed 80 chars insert a newline at 80 and move the offending word to the next line

          (setq-default auto-fill-function 'do-auto-fill)
          (setq-default fill-column 80)
        
      • Minimal UI
              (scroll-bar-mode -1)
              (tool-bar-mode -1)
              (tooltip-mode -1)
              (menu-bar-mode -1)
        
      • Highlight Current Line
              (global-hl-line-mode)
        
      • Highlight Matching Parathese
              ;; Show matching parens
              (setq show-paren-delay 0)
              (show-paren-mode 1)
        
      • Use icons when available
              (require 'all-the-icons)
        
    • Files

      save backups in ~/.emacs/backups

              
           (setq backup-directory-alist
                `((".*" . , "~/.emacs.d/backups")))
           (setq auto-save-file-name-transforms
                `((".*" ,"~/.emacs.d/backups" t)))
      
    • Prompts

      change yes/no to y/n

             (fset 'yes-or-no-p 'y-or-n-p) 
      
    • Default Browser
           (setq browse-url-browser-function 'browse-url-firefox)
      
  • Org Mode
        (require 'org)
    
    • File Hooks

      use org mode for any file ending in .org, .txt, or .orgarchive

           (add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))
      
    • Todo

      Change the todo sequence and set shortcuts

           (setq org-todo-keywords
                  '((sequence "TODO(t)" "NEXT(n)" "DATE(d)" "|" "FIN(f)" "CANCEL(c)")))
      

      Log the time a todo item is set to a finished state

           (setq org-log-into-drawer t)
      
    • Time

      Stuff the times of a headline into a drawer

           (setq org-log-done 'time)
      
    • Agenda
          (setq org-agenda-start-on-weekday nil)
      
          (setq org-agenda-start-with-clockreport-mode t)
      
          (setq org-agenda-files
                '("~/life/business.txt" 
                 "~/life/maintenance.txt" 
                 "~/life/social.txt" 
                 "~/life/experience.txt"))
      
      
          (setq org-agenda-custom-commands
                '(("z" "Agenda and NEXT items"
                   ((agenda "" (
                                (org-agenda-span 1)))
                    (todo "NEXT" )
                    (agenda "" (
                                (org-agenda-start-day "+1d")
                                (org-agenda-span 10)))))))
      
          (setq org-agenda-prefix-format
                '((agenda . " %i %-12:c%?-12t% s %b")
                  (timeline . "  % s")
                  (todo . " %i %-12:c %b")
                  (tags . " %i %-12:c")
                  (search . " %i %-12:c"))) 
      
    • search/agenda context detail
           (setq org-show-context-detail
                 '((agenda . local)
                   (default . lineage)))
      
    • Key Bindings
          (global-set-key "\C-cl" 'org-store-link)
          (global-set-key "\C-ca" 'org-agenda)
          (global-set-key "\C-cb" 'org-iswitchb)
      
    • Scheduling
      
      
    • Display

      Make red anything surround by *’s

          (add-to-list 'org-emphasis-alist
                       '("*" (:foreground "red")
                         ))
      

      Use Bullets for headings

           (require 'org-bullets)
           (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
      
    • Export

      export settings

           (setq org-export-with-smart-quotes t)
           (setq org-export-wth-emphasize t)
           (setq org-export-with-author t)
           (setq org-export-with-broken-links t)
           (setq org-export-with-date t)
           (setq org-export-with-email t)
           (setq org-export-time-stamp-file nil)
           (setq org-export-with-title t)
           (setq org-export-wth-toc nil)
           (setq org-export-with-section-numbers nil)
      
      • HTML

        html settings

             (setq org-html-doctype "html5")
             (setq org-html-link-home "zfadd.is")
        
    • Templates
           (add-to-list 'org-structure-template-alist
                        (list "c" (concat":PROPERTIES:\n"
                                          ":EMAIL:?\n"
                                          ":PHONE:\n"
                                          ":ADDRESS:\n"
                                          ":BIRTHDAY:\n"
                                          ":WEB:\n"
                                          ":END:")))
      
      
    • Source Blocks
      • Use syntax highlighting for source blocks
          (setq org-src-fontify-natively t)
      
      • preserve indention when tangling code

               (setq org-src-preserve-indentation t)
        
      • hide blocks by default

             (setq org-hide-block-startup t)     
        
    • Babel
      • Allow languages

             (org-babel-do-load-languages
              'org-babel-load-languages
              '((ledger . t)
                (shell . t)
                (python . t)
                (emacs-lisp . t)))
        
  • Evil
      (require 'evil)
      (evil-mode t)
    
    • Disable in cretain modes
           (add-to-list 'evil-emacs-state-modes 'elfeed-search-mode)
           (add-to-list 'evil-emacs-state-modes 'elfeed-show-mode)
           (add-to-list 'evil-emacs-state-modes 'magit-status)
      
  • Novel
    • File hooks

      Use nov-mode for any file with extension .epub

           (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
      
  • Web Mode

    Package to give syntax highlighting for html, css, and various templating languages used by different frameworks

        (require 'web-mode)
    
    • File Hooks

      Use web-mode for any file that ends with extension .html

           (add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
      

      Use the Django syntax highlighting engine for any file ending in html

         
           (setq web-mode-engines-alist
              '(("django" . "\\.html\\'")))
      
  • Ledger
    • File Hooks

      Start any file that ends with .ledger in ledger mode

         (add-to-list 'auto-mode-alist '("\\.ledger$" . ledger-mode))
      
    • Display

      Automatically align amount to 52nd collumn

         (setq ledger-post-auto-adjust-amounts t)
      
  • Beeminder
      (add-to-list 'load-path "/home/z/.emacs.d/beeminder/")
      ;(require 'request)
      ;(require 'anaphora)
      (require 'cl)
      (require 'beeminder)
      (setq beeminder-username "zacharius")
      (setq beeminder-auth-token "e5j8yjZJQyxVZ6qX228x")
    
  • Declutter
      (add-to-list 'load-path "/home/z/.emacs.d/declutter")
      (require 'declutter)
    
  • NeoTree
      ;; NeoTree
      (require 'neotree)
      (setq neo-theme (if (display-graphic-p) 'icons 'arrow))
    
  • Magit
      (add-to-list 'load-path "/home/z/.emacs.d/magit/lisp")
      (require 'magit)
    
      (with-eval-after-load 'info
        (info-initialize)
        (add-to-list 'Info-directory-list
                     "~/.emacs.d/magit/Documentation/"))
    
    • keybindings
           (global-set-key (kbd "C-x g") 'magit-status)
      
  • Ibuffer
        (global-set-key (kbd "C-x C-b") 'ibuffer) ;; Use Ibuffer for Buffer List
        (setq ibuffer-saved-filter-groups
              '(("buffer groups"
                ("emacs-config" (filename . ".emacs.d"))
                ("documentation" (filename . "knxw"))
                ("organization" (or (filename . "life")
                                    (name . "\*Org Agenda\*")))
                ("writings" (filename . "lit"))
                ("projects" (filename . "prj"))
                ("games" (filename . "games")))))
    
        (add-hook 'ibuffer-mode-hook
                  '(lambda ()
                     (ibuffer-switch-to-saved-filter-groups "buffer groups")))
    
        (setq ibuffer-expert t)
    
    
  • Ido
        (setq ido-enable-flex-matching t)
        (setq ido-everywhere t)
        (ido-mode 1)
    
  • Python
        (elpy-enable)