Sparkly — Create multiline sparks ▁▂▆▄▃▇▅ (Emacs package)
Below you find the latest version of (1) the package's README and (2) its main source file.
For the git repository and issue tracker, see the project's page on sr.ht.
For more packages, see Software.
README.org
A note on spacing
Visual spacing between the lines of multiline sparks can vary from none to tiny to pronounced.
- When none, you can't quite see where one line ends and the other begins.
This may or may not be desirable, depending on taste and use case. - A division between columns might also be noticeable.
The monospace font being used is the main reason for such differences. Try them out.
In browsers, interline spacing might look particularly large.
Overview
With Sparkly you can create multiline sparks such as these ones:
(sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06)) => "\ ▁ ▄ ▁ ▅ █ █ █ ▄ █ █ ▁ █ █▇ ▇ █ █▃ █ █ █▁ ██ █ █ ▇▅ ██ █ █ ██ ██ █ █ ██ ██ ▂ █ ▃ ██ ██ ██ █▂ █ ██ ██ █ █▁ █ ██ ██ ██ ▆ ▃ ██ █ ██ ██ █ ██▄█ ██ ██▃██ ▆█ █▆ ██ █ ██▇██ █ ████ ██ ████████▂█████▄█ █████ █ ████ ██ ████████████████▃█████ █▄████▇ ██ ▆▇██████████████████████▂███████ ██ ▃████████████████████████████████▇██▆"
which you could also fit in, say, exactly four lines:
(sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06) :lns 4) => "\ ▆ ▅▂ ▂ ▄ ▇▁ █ ▃ █▅ ██ █ █ ▇▇ ██ ▃ █ ▃ █▅ ██▄██▃▅▇▁▆▅▃██▁█ ██▅██ █ ██▇█ ██ ▁▅▅████████████████▆█████▃█▇█████▂██▂"
or just one, making it a "traditional sparkline":
(sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06) :lns 1) => "\ _▁▁█▅▃▇▇▃▃▄▂▄▃▃▇▄▂▇▂▆▆▃█▆▁▅▂█▄▄▅▂▁▇▅_"
Parameters can be adjusted. If, for example, we run the following:
(sparkly-vs '(5 10 20)) (sparkly-vs '(5 10 20) :fit t) (sparkly-vs '(5 10 20) :lns 2) (sparkly-vs '(5 10 20) :lns 2 :lim 1) (sparkly-vs '(2 2.5 3) :fac 1)
we get, respectively, these (shown side by side for comparison):
▄ █ ▄█ ▂█ ▄█ █ ███ ▅██ ▆██ ▄██ ▂▄█ ███
See sparkly-vs below for more details.
Installation
See my page Software for the most up-to-date instructions on how to download and install any of my Emacs packages.
Having downloaded and installed the package and its dependencies, adapt the configurations below to your init.el
file.
(use-package sparkly :demand t)
Alternatively, if you don't have use-package
:
(require 'sparkly)
Summary of callables
Here's an overview of this package's callables:
Function | Summary |
---|---|
sparkly-vi | Insert vertical sparks from LIST at line below point. |
sparkly-vs | Create vertical multiline sparks string from LIST. |
sparkly-see-readme | Open sparkly's README.org file. |
sparkly-see-news | See the News in sparkly's README.org file. |
They're described in more detail below.
Functions
Vertical multiline sparks
Given a list, create its corresponding vertical multiline sparks.
- sparkly-vi inserts the string
- sparkly-vs returns the string
sparkly-vi (list &optional key-1 value-1 key-2 value-2 ...)
Insert vertical sparks from LIST at line below point.
Return nil. See sparkly-vs for KEYS.
If aggressive-indent-mode
is on, turn it off while inserting.
Autodetect where point is before inserting, and open lines
accordingly.
sparkly-vs (list &optional key-1 value-1 key-2 value-2 ...)
Create vertical multiline sparks string from LIST.
All elements of LIST must be numbers. Negative ones will be
flattened to zero.
The following KEYS are available:
KEY | Explanation | Default |
---|---|---|
:fac |
Stretching factor | 0.125 |
:lns |
Number of lines | nil |
:fit |
Whether to round up | nil |
:lim |
Maximum number of lines | nil |
Constraints:
:fac
and:lns
are mutually exclusive- values of
:fac
,:lns
, and:lim
must be positive numbers - value of
:fit
must be a boolean
Details:
:fac
is a stretching factor to apply to all numbers of the list.:lns
is the exact number of lines to be occupied by the maximum
number of the list.:fit
is whether to round up:lns
to the next integer.:lim
is the maximum number of lines allowed;
this is particularly useful if the input is variable and you want
to impose a ceiling on how many lines it might end up displaying.
Here's how these values are parsed from input:
- First, if
:lns
is nil, then:
- If
:fac
is nil, set it to ⅛ (= .125). - Set
:lns
as (* max:fac
), where max is the LIST's maximum.
- If
- Then, if
:fit
is t, round up:lns
to the next integer. - Then, if
:lim
is non-nil, set:lns
to the minimum value between
:lim
and:lns
. - Finally, set
:fac
to (/:lns
max 1.0)
This value of :fac
is then applied to all the numbers.
;;;; The 4 fills half of the line: 4 = ½*8 (sparkly-vs '(2 3 4)) => "▂▃▄" ;;;; Stretched so that 4 reaches the top of the line (sparkly-vs '(2 3 4) :fit t) => "▄▆█" ;;;; Same as above, because automatically numlines=1 (sparkly-vs '(2 3 4) :lns 1) => "▄▆█" ;;;; Stretched to fill three lines (sparkly-vs '(2 3 4) :lns 3) => "\ ▂█ ▄██ ███" ;;;; Stretched to max-value-of-seq lines (sparkly-vs '(2 3 4) :fac 1) => "\ █ ██ ███ ███" ;;;; The 9s automatically span to a second line (sparkly-vs '(3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 1 9 7 1 6 9 3 9 9 3 7 5 1 0 5 8 2 0 9 7 4 9 4 4 5 9 2 3 0 7 8 1 6 4 0 6 2 8 6)) => "\ ▁ ▁ ▁ ▁ ▁ ▁ ▁▁ ▁ ▁ ▁ ▃▁▄▁▅█▂▆▅▃▅██▇█▃▂▃█▄▆▂▆▄▃▃█▃▂▇█▅_▂██▄▁█▇▁▆█▃██▃▇▅▁_▅█▂_█▇▄█▄▄▅█▂▃_▇█▁▆▄_▆▂█▆" ;;;; Here it automatically uses 13 lines: 97 = (12+⅛)*8 (sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06)) ;;;; ⮯ => "\ ▁ ▄ ▁ ▅ █ █ █ ▄ █ █ ▁ █ █▇ ▇ █ █▃ █ █ █▁ ██ █ █ ▇▅ ██ █ █ ██ ██ █ █ ██ ██ ▂ █ ▃ ██ ██ ██ █▂ █ ██ ██ █ █▁ █ ██ ██ ██ ▆ ▃ ██ █ ██ ██ █ ██▄█ ██ ██▃██ ▆█ █▆ ██ █ ██▇██ █ ████ ██ ████████▂█████▄█ █████ █ ████ ██ ████████████████▃█████ █▄████▇ ██ ▆▇██████████████████████▂███████ ██ ▃████████████████████████████████▇██▆" ;;;; We can stretch it so that 97 reaches the top of the 13th line (sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06) :fit t) ;;;; ⮯ => "\ ▃ ▄ █ █ ▇ ▂ █ █ █ █▅ ▅ █ █ █ ▇ █ ██ █ █ ▄▂ ██ █ █ █▆ ██ █ █ ██ ██ █ █▅ ██ ██ █ █ ██ ██ ▆ █ ▇ ██ ██ ██ ▁ █▆ █ ██ ██ █ █▅ █ ██ ██ ██ ▁█ ▆▁ ██ █ ██▂██ █ ██▇█ ██ ██▆██▂██ ██▂██ █ █████ █ ████ ██ ████████▄█████▆█ █████ █ ████▁ ██ ████████████████▄█████ █▅█████ ██ ▇███████████████████████▃███████ ██ ▃███████████████████████████████████▆" ;;;; Here we fit the max value (97) to exactly four lines (sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06) :lns 4) ;;;; ⮯ => "\ ▆ ▅▂ ▂ ▄ ▇▁ █ ▃ █▅ ██ █ █ ▇▇ ██ ▃ █ ▃ █▅ ██▄██▃▅▇▁▆▅▃██▁█ ██▅██ █ ██▇█ ██ ▁▅▅████████████████▆█████▃█▇█████▂██▂" ;;;; And here we fit it to a single line (sparkly-vs '(3 14 15 92 65 35 89 79 32 38 46 26 43 38 32 79 50 28 84 19 71 69 39 93 75 10 58 20 97 49 44 59 23 07 81 64 06) :lns 1) ;;;; ⮯ => "\ _▁▁█▅▃▇▇▃▃▄▂▄▃▃▇▄▂▇▂▆▆▃█▆▁▅▂█▄▄▅▂▁▇▅_" ;;;; "Natural" sizes with :fac 1 (let* ((π float-pi) ; 3.141592653589793 (e float-e) ; 2.718281828459045 (m (* π e)) ; 8.539734222673566 (s (+ π e)) ; 5.859874482048838 (q (/ π e)) ; 1.155727349790922 (d (- π e)) ; 0.423310825130748 (l (list π e 0 m s 0 q d 0 4 2 0))) (sparkly-vs l :fac 1)) => "\ ▄ █ █ █▇ ██ ▁ ██ █ █▆ ██ █ ██ ██ ▁ ██ ██_██_█▃_██_" ;;;; Additional simple examples ;;;;; Naturally uses 2.5 lines (sparkly-vs '(5 10 20)) => "\ ▄ ▂█ ▅██" ;;;;; Still 2.5 lines (sparkly-vs '(5 10 20) :lim 3) => "\ ▄ ▂█ ▅██" ;;;;; Stretched to exactly 3 (sparkly-vs '(5 10 20) :fit t) => "\ █ ▄█ ▆██" (sparkly-vs '(5 10 20) :lns 3) => "\ █ ▄█ ▆██" ;;;;; Compressed to exactly 2 (sparkly-vs '(5 10 20) :lim 2) => "\ █ ▄██" (sparkly-vs '(5 10 20) :lns 2) => "\ █ ▄██" ;;;;; Compressed to exactly 1 (sparkly-vs '(5 10 20) :lns 1) => "▂▄█" ;;;; Special cases ;;;;; Arg :lns need not be an integer (sparkly-vs '(1 6 2) :lns 1) => "▁█▃" (sparkly-vs '(1 6 2) :lns .6) => "▁▅▂" (sparkly-vs '(1 6 2) :lns .001) => "___" (sparkly-vs '(1 6 2) :lns (sqrt 2)) => "\ ▃ ▂█▄" ;<-- max value 6 occupies ~√2 lines (sparkly-vs '(1 6 2) :lns float-pi) => "\ ▁ █ █ ▄██" ;<-- max value 6 occupies ~π lines ;;;;; Zero shows as an underscore (sparkly-vs '( 0 2 4)) => "_▂▄" (sparkly-vs '( 2 0 4)) => "▂_▄" (sparkly-vs '( 2 4 0)) => "▂▄_" ;;;;; Negative numbers are flattened to zero (sparkly-vs '(-5 2 4)) => "_▂▄" (sparkly-vs '( 2 -5 4)) => "▂_▄" (sparkly-vs '( 2 4 -5)) => "▂▄_" ;;;;; Empty list returns empty string (sparkly-vs '()) => "" (sparkly-vs '() :lns 2) => "" (sparkly-vs '() :lim 2) => "" (sparkly-vs '() :fit t) => "" ;;;; Errors (sparkly-vs [5 20] :lns 4 :fac 1) !!> error ; not a list (sparkly-vs '(5 20) :lns 4 :fac 1) !!> error ; mutually exclusive (sparkly-vs '(5 20) :fit 2) !!> error ; not a boolean (sparkly-vs '(5 20) :lns 0) !!> error ; ≤ 0 (sparkly-vs '(5 20) :fac 0) !!> error (sparkly-vs '(5 20) :lim 0) !!> error (sparkly-vs '(5 20) :lns -1) !!> error (sparkly-vs '(5 20) :fac -1) !!> error (sparkly-vs '(5 20) :lim -1) !!> error
Commands
See README
Commands to open sparkly's README.org. Optionally, find things in it.
sparkly-see-readme (&optional heading narrow)
Open sparkly's README.org file.
Search for the file in sparkly.el's directory.
If found, open it read-only.
If optional argument HEADING is passed, try to navigate to the
heading after opening it. HEADING should be a string.
If optional argument NARROW is non-nil, narrow to that heading.
This argument has no effect if HEADING is nil or not found.
sparkly-see-news ()
See the News in sparkly's README.org file.
Contributing
See my page Software for information about how to contribute to any of my Emacs packages.
News
0.2.0
Release
License
This project follows the REUSE Specification (FAQ), which in turn is built upon SPDX.
Therefore, license and copyright information can be found in:
- each file's comment header, or
- an adjacent file of the same name with the additional extension
.license
, or - the
.reuse/dep5
file
The full text of the licenses can be found in the LICENSES
subdirectory.
sparkly.el
Structure
;;; sparkly.el --- Create multiline sparks ▁▂▆▄▃▇▅ -*- lexical-binding: t -*- ;;; Commentary: ;;;; For all the details, please do see the README ;;; Code: ;;;; Libraries ;;;; Package metadata ;;;; Customizable variables ;;;; Functions ;;;;; Description macro ;;;;; Vertical multiline sparks ;;;; Commands ;;;;; See README ;;;; Wrapping up ;;; sparkly.el ends here
Contents
;;; sparkly.el --- Create multiline sparks ▁▂▆▄▃▇▅ -*- lexical-binding: t -*- ;; SPDX-FileCopyrightText: © flandrew <https://flandrew.srht.site/listful> ;;--------------------------------------------------------------------------- ;; Author: flandrew ;; Created: 2023-11-12 ;; Updated: 2025-01-09 ;; Keywords: extensions ;; Homepage: <https://flandrew.srht.site/listful/software.html> ;;--------------------------------------------------------------------------- ;; Package-Version: 0.2.0 ;; Package-Requires: ((emacs "25.1") (dash "2.18") (s "1.4")) ;;--------------------------------------------------------------------------- ;; SPDX-License-Identifier: GPL-3.0-or-later ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published ;; by the Free Software Foundation, either version 3 of the License, ;; or (at your option) any later version. ;; ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this file. If not, see <https://www.gnu.org/licenses/>. ;;; Commentary: ;; ;; With Sparkly you can create multiline sparks: ;; ;; ▆ ▅▂ ▂ ▄ ▇▁ █ ▃ ;; █▅ ██ █ █ ▇▇ ██ ▃ █ ▃ █▅ ;; ██▄██▃▅▇▁▆▅▃██▁█ ██▅██ █ ██▇█ ██ ;; ▁▅▅████████████████▆█████▃█▇█████▂██▂ ;; ;;;; For all the details, please do see the README ;; ;; Open it easily with: ;; (find-file-read-only "README.org") <--- C-x C-e here¹ ;; ;; or from any buffer: ;; M-x sparkly-see-readme ;; ;; or read it online: ;; <https://flandrew.srht.site/listful/sw-emacs-sparkly.html> ;; ;; ¹ or the key that ‘eval-last-sexp’ is bound to, if not C-x C-e. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Code: ;;;; Libraries (require 's) (require 'dash) (require 'lisp-mnt) ; ‘lm-summary’, ‘lm-homepage’, ‘lm-version’, ‘lm-header’ ;;;; Package metadata (defvar sparkly--name "Sparkly") (defvar sparkly--dot-el (format "%s.el" (file-name-sans-extension (eval-and-compile (or load-file-name buffer-file-name))))) (defvar sparkly--readme-org (expand-file-name "README.org" (file-name-directory sparkly--dot-el))) (defvar sparkly--summary (lm-summary sparkly--dot-el)) (defvar sparkly--homepage (lm-homepage sparkly--dot-el)) (defvar sparkly--version (lm-with-file sparkly--dot-el (or (lm-header "package-version") (lm-version)))) ;;;; Customizable variables (defgroup sparkly nil (format "%s." sparkly--summary) :group 'extensions :link '(emacs-library-link :tag "Lisp file" "sparkly.el") :link `(file-link :tag "README.org" ,sparkly--readme-org) :link `(url-link :tag "Homepage" ,sparkly--homepage)) ;;;; Functions ;;;;; Description macro (defmacro sparkly--describe (str) "Describe with string STR the contents under this heading. Think of it as a docstring for the headings of your elisp files. For the full docstring, look for ‘orgreadme-fy-describe’ in the package ‘orgreadme-fy’." (declare (indent 0)) (unless (stringp str) (user-error "‘sparkly--describe’ must receive a string"))) ;;;;; Vertical multiline sparks (sparkly--describe "Given a list, create its corresponding vertical multiline sparks. - ‘sparkly-vi’ inserts the string - ‘sparkly-vs’ returns the string") (defun sparkly-vi (list &rest args) "Insert vertical sparks from LIST at line below point. Return nil. See ‘sparkly-vs’ for KEYS. If ‘aggressive-indent-mode’ is on, turn it off while inserting. Autodetect where point is before inserting, and open lines accordingly. \(fn LIST &optional KEY-1 VALUE-1 KEY-2 VALUE-2 ...)" (sparkly--smart-insert (apply #'sparkly-vs list args))) (defun sparkly-vs (list &rest args) "Create vertical multiline sparks string from LIST. All elements of LIST must be numbers. Negative ones will be flattened to zero. The following KEYS are available: | KEY | Explanation | Default | |------+-------------------------+---------| | `:fac' | Stretching factor | 0.125 | | `:lns' | Number of lines | nil | | `:fit' | Whether to round up | nil | | `:lim' | Maximum number of lines | nil | Constraints: - `:fac' and `:lns' are mutually exclusive - values of `:fac', `:lns', and `:lim' must be positive numbers - value of `:fit' must be a boolean Details: - `:fac' is a stretching factor to apply to all numbers of the list. - `:lns' is the exact number of lines to be occupied by the maximum number of the list. - `:fit' is whether to round up `:lns' to the next integer. - `:lim' is the maximum number of lines allowed; this is particularly useful if the input is variable and you want to impose a ceiling on how many lines it might end up displaying. Here's how these values are parsed from input: - First, if `:lns' is nil, then: - If `:fac' is nil, set it to ⅛ (= .125). - Set `:lns' as (* max `:fac'), where max is the LIST's maximum. - Then, if `:fit' is t, round up `:lns' to the next integer. - Then, if `:lim' is non-nil, set `:lns' to the minimum value between `:lim' and `:lns'. - Finally, set `:fac' to (/ `:lns' max 1.0) This value of `:fac' is then applied to all the numbers. \(fn LIST &optional KEY-1 VALUE-1 KEY-2 VALUE-2 ...)" (if (null list) "" (-let [(lns . fac) (apply #'sparkly--parse list args)] (let* ((num2ls (lambda (num) (let ((norm (round (* 8 fac num)))) (--map (number-to-string (let ((Δ (- norm (* 8 it)))) (if (>= Δ 8) 8 (if (<= Δ 0) 0 Δ)))) (-iota (ceiling lns)))))) (sparkl (-map num2ls list)) (sparkn (apply #'-zip-lists sparkl)) (sparka (-zip-pair (-map #'number-to-string (-iota 9)) (-map #'string " ▁▂▃▄▅▆▇█"))) (sparks (--map (s-replace-all sparka (s-join "" it)) sparkn))) ;; The bottom line (and only it) will have underscores for 0 (setcar sparks (s-replace " " "_" (car sparks))) ;; We can now remove trailing spaces on all lines and finish (--tree-mapreduce (s-trim-right it) (concat it "\n" acc) (nreverse sparks)))))) (defun sparkly--parse (list &rest args) "Parse LIST and KEYS. Return (LNS . FAC). See ‘sparkly-vs’ for KEYS. \n(fn LIST &optional KEY-1 VALUE-1 KEY-2 VALUE-2 ...)" (-let [(&plist :fac :fit :lim :lns) args] ;; Check for errors (or (listp list) (error "%s must be a list" list)) (or (booleanp fit) (error "%s must be a boolean" fit)) (and lns fac (error "%s and %s are mutually exclusive" lns fac)) (dolist (var (list lns fac lim)) (or (null var) (and (numberp var) (> var 0)) (error "%s, if given, must be a positive number" var))) ;; Produce output (let ((max (-max list))) (or lns (setq fac (or fac (/ 1.0 8)) lns (* max fac))) (when fit (setq lns (ceiling lns))) (when lim (setq lns (min lim lns))) (setq fac (/ lns max 1.0)) (cons lns fac)))) (defun sparkly--smart-insert (string) "Insert STRING into line after point without indenting." (save-excursion (atomic-change-group (unless (bolp) (forward-line)) (unless (eolp) (open-line 1)) (if (and (fboundp 'aggressive-indent-mode) (bound-and-true-p aggressive-indent-mode)) (prog2 (aggressive-indent-mode -1) (insert string) (aggressive-indent-mode 1)) (insert string))))) ;;;; Commands ;;;;; See README (sparkly--describe "Commands to open sparkly's README.org. Optionally, find things in it.") ;;;###autoload (defun sparkly-see-readme (&optional heading narrow) "Open sparkly's README.org file. Search for the file in sparkly.el's directory. If found, open it read-only. If optional argument HEADING is passed, try to navigate to the heading after opening it. HEADING should be a string. If optional argument NARROW is non-nil, narrow to that heading. This argument has no effect if HEADING is nil or not found." (interactive) (let ((readme sparkly--readme-org)) (if (file-exists-p readme) (let ((pr (make-progress-reporter (format "Opening %s ... " (abbreviate-file-name readme))))) (find-file-read-only readme) (when heading (sparkly--goto-org-heading heading narrow)) (progress-reporter-done pr)) (message "Couldn't find %s's README.org" sparkly--name)))) ;;;###autoload (defun sparkly-see-news () "See the News in sparkly's README.org file." (interactive) (sparkly-see-readme "News" 'narrow) (sparkly--display-org-subtree)) (defun sparkly--display-org-subtree () "Selectively display org subtree." (let ((cmds '(outline-hide-subtree outline-show-children outline-next-heading outline-show-branches))) (and (fboundp (nth 0 cmds)) (fboundp (nth 1 cmds)) (fboundp (nth 2 cmds)) (fboundp (nth 3 cmds)) (mapc #'funcall cmds)))) (defun sparkly--goto-org-heading (heading &optional narrow) "Navigate to org HEADING and optionally NARROW to it." (let* ((hrx (format "^[*]+ %s" heading)) (pos (save-match-data (save-excursion (save-restriction (widen) (goto-char (point-max)) (re-search-backward hrx nil t 1)))))) (when pos (widen) (goto-char pos) (if (and narrow (fboundp 'org-narrow-to-subtree)) (org-narrow-to-subtree) (recenter-top-bottom 1)) (when (fboundp 'outline-show-subtree) (outline-show-subtree)) (when (fboundp 'org-flag-drawer) (save-excursion (forward-line 1) (org-flag-drawer t)))))) ;;;; Wrapping up (provide 'sparkly) ;; Local Variables: ;; coding: utf-8 ;; indent-tabs-mode: nil ;; sentence-end-double-space: nil ;; outline-regexp: ";;;;* " ;; End: ;;; sparkly.el ends here