[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/org-real ac799d3 040/160: Merge into single file
From: |
ELPA Syncer |
Subject: |
[elpa] externals/org-real ac799d3 040/160: Merge into single file |
Date: |
Wed, 6 Oct 2021 16:58:11 -0400 (EDT) |
branch: externals/org-real
commit ac799d3077455ad896124fc36a30c1259ba05bf8
Author: Tyler Grinn <tylergrinn@gmail.com>
Commit: Tyler Grinn <tylergrinn@gmail.com>
Merge into single file
Merged org-real-box.el into org-real.el
---
org-real-box.el | 560 --------------------------------------------------------
org-real-pkg.el | 5 -
org-real.el | 517 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 515 insertions(+), 567 deletions(-)
diff --git a/org-real-box.el b/org-real-box.el
deleted file mode 100644
index 710c78a..0000000
--- a/org-real-box.el
+++ /dev/null
@@ -1,560 +0,0 @@
-;;; org-real-box.el --- Keep track of real things as org-mode links -*-
lexical-binding: t -*-
-
-;; Author: Tyler Grinn <tylergrinn@gmail.com>
-;; Version: 0.1.0
-;; File: org-real-box.el
-;; Package-Requires: ((emacs "26.1"))
-;; Keywords: tools
-;; URL: https://gitlab.com/tygrdev/org-real
-
-;;; Commentary:
-
-;; Box class definition and related methods
-
-;;; Code:
-
-;;;; Patch! 0.0.1 -> 0.1.0+
-;;;; Will be removed in version 1.0.0+
-
-(and (fboundp 'org-real--merge) (fmakunbound 'org-real--merge))
-(and (fboundp 'org-real--map-immediate) (fmakunbound 'org-real--map-immediate))
-(and (fboundp 'org-real--next) (fmakunbound 'org-real--next))
-(and (fboundp 'org-real--merge-into) (fmakunbound 'org-real--merge-into))
-(and (fboundp 'org-real--add-matching) (fmakunbound 'org-real--add-matching))
-(and (fboundp 'org-real--flex-add) (fmakunbound 'org-real--flex-add))
-(and (fboundp 'org-real--expand) (fmakunbound 'org-real--expand))
-(and (fboundp 'org-real--draw) (fmakunbound 'org-real--draw))
-(and (fboundp 'org-real--get-width) (fmakunbound 'org-real--get-width))
-(and (fboundp 'org-real--get-height) (fmakunbound 'org-real--get-height))
-(and (fboundp 'org-real--get-top) (fmakunbound 'org-real--get-top))
-(and (fboundp 'org-real--get-left) (fmakunbound 'org-real--get-left))
-
-;;;; Requirements:
-
-(require 'eieio)
-(require 'cl-lib)
-
-;;;; Variables from org-real.el
-
-(eval-when-compile
- (defvar org-real-padding)
- (defvar org-real-margin))
-
-;;;; Class definitions
-
-(defclass org-real-box-collection ()
- ((box :initarg :box
- :type org-real-box)
- (next :initarg :next
- :type org-real-box-collection))
- "A collection of `org-real-box'es.")
-
-(defclass org-real-box ()
- ((name :initarg :name
- :type string)
- (rel :initarg :rel
- :type string)
- (rel-box :initarg :rel-box
- :type org-real-box)
- (x-order :initarg :x-order
- :initform 0
- :type number)
- (y-order :initarg :y-order
- :initform 0
- :type number)
- (in-front :initarg :in-front
- :initform nil
- :type boolean)
- (behind :initarg :behind
- :initform nil
- :type boolean)
- (parent :initarg :parent
- :type org-real-box)
- (children :initarg :children
- :initform (org-real-box-collection)
- :type org-real-box-collection)
- (primary :initarg :primary
- :initform nil
- :type boolean))
- "A representation of a box in 3D space.")
-
-
-;;;; Exports
-
-(cl-defmethod org-real--make-instance ((_ (subclass org-real-box)) containers)
- "Create an instance of `org-real-box' from CONTAINERS.
-
-CONTAINERS is a list of plists containing at least a :name
-property and optionally a :rel property."
- (when-let* ((world (org-real-box))
- (base-container (pop containers))
- (base (org-real-box :name (plist-get base-container :name))))
- (oset base :parent world)
- (with-slots (children) world
- (setq children (org-real--add-to-list children base)))
- (if containers
- (org-real--make-instance-helper containers world base))
- world))
-
-(cl-defmethod org-real--merge (boxes)
- "Merge BOXES into a single box."
- (if (< (length boxes) 2)
- (if (= 0 (length boxes))
- (org-real-box)
- (car boxes))
- (let ((world (org-real-box)))
- (while boxes
- (org-real--merge-into (pop boxes) world))
- world)))
-
-;;;; Drawing
-
-(cl-defmethod org-real--draw ((box org-real-box) offset)
- "Insert an ascii drawing of BOX into the current buffer.
-
-OFFSET is the starting line to start insertion."
- (let ((children (with-slots (children) box (org-real--get-all children))))
- (if (slot-boundp box :name)
- (with-slots (name behind (align-bottom in-front) (dashed behind)
primary) box
- (let* ((top (+ offset (org-real--get-top box)))
- (left (org-real--get-left box))
- (width (org-real--get-width box))
- (height (org-real--get-height box)))
- (cl-flet ((draw (coords str &optional primary)
- (forward-line (- (car coords)
(line-number-at-pos)))
- (move-to-column (cdr coords) t)
- (if primary
- (put-text-property 0 (length str) 'face
'org-real-primary
- str))
- (insert str)
- (delete-char (length str))))
- (draw (cons top left)
- (concat "┌" (make-string (- width 2) (if dashed #x254c
#x2500)) "┐"))
- (if align-bottom
- (draw (cons (+ top height) left)
- (concat "┴" (make-string (- width 2) (if dashed #x254c
#x2500)) "┴"))
- (draw (cons (+ top height -1) left)
- (concat "└" (make-string (- width 2) (if dashed #x254c
#x2500)) "┘")))
- (draw (cons (+ top 1 (cdr org-real-padding))
- (+ left 1 (car org-real-padding)))
- name
- primary)
- (let ((r (+ top 1))
- (c1 left)
- (c2 (+ left width -1)))
- (dotimes (_ (- height (if align-bottom 1 2)))
- (draw (cons r c1) (if dashed "╎" "│"))
- (draw (cons r c2) (if dashed "╎" "│"))
- (setq r (+ r 1))))))))
- (mapc
- (lambda (child) (org-real--draw child offset))
- children)))
-
-(cl-defmethod org-real--get-width ((box org-real-box))
- "Get the width of BOX."
- (let* ((base-width (+ 2 ; box walls
- (* 2 (car org-real-padding))))
- (width (+ base-width
- (if (slot-boundp box :name)
- (with-slots (name) box (length name))
- 0)))
- (children (with-slots (children) box (org-real--get-all children))))
- (if (not children)
- width
- (let* ((column-indices (cl-delete-duplicates
- (mapcar (lambda (child) (with-slots (x-order)
child x-order)) children)))
- (columns (mapcar
- (lambda (c)
- (seq-filter
- (lambda (child)
- (with-slots (x-order) child
- (= c x-order)))
- children))
- column-indices))
- (column-widths (mapcar
- (lambda (column)
- (apply 'max (mapcar 'org-real--get-width
column)))
- columns))
- (children-width (seq-reduce
- (lambda (total width)
- (+ total (car org-real-margin) width))
- column-widths
- (* -1 (car org-real-margin)))))
- (if (> width (+ (* 2 (car org-real-margin)) children-width))
- width
- (+ base-width children-width))))))
-
-(cl-defmethod org-real--get-height ((box org-real-box))
- "Get the height of BOX."
- (let* ((in-front (with-slots (in-front) box in-front))
- (height (+ (if in-front
- (* -1 (cdr org-real-margin))
- 0)
- 3 ; box walls + text
- (cdr org-real-padding)
- (cdr org-real-margin)))
- (children (with-slots (children) box (org-real--get-all children))))
- (if (not children)
- height
- (let* ((row-indices (cl-delete-duplicates
- (mapcar (lambda (child) (with-slots (y-order) child
y-order)) children)))
- (rows (mapcar
- (lambda (r)
- (seq-filter
- (lambda (child)
- (with-slots (y-order) child
- (= r y-order)))
- children))
- row-indices))
- (row-heights (mapcar
- (lambda (row)
- (apply 'max (mapcar 'org-real--get-height row)))
- rows)))
- (+ height (seq-reduce '+ row-heights 0))))))
-
-(cl-defmethod org-real--get-top ((box org-real-box))
- "Get the top row index of BOX."
- (if (not (slot-boundp box :parent))
- 0
- (with-slots (parent x-order y-order) box
- (let* ((offset (+ 2 (cdr org-real-padding) (cdr org-real-margin)))
- (top (+ offset (org-real--get-top parent)))
- (above (seq-filter
- (lambda (child)
- (with-slots ((child-x x-order) (child-y y-order)) child
- (and (= x-order child-x)
- (< child-y y-order))))
- (org-real--get-all (with-slots (children) parent
children))))
- (directly-above (and above (seq-reduce
- (lambda (max child)
- (with-slots ((max-y y-order)) max
- (with-slots ((child-y y-order))
child
- (if (> child-y max-y)
- child
- max))))
- above
- (org-real-box :y-order -9999))))
- (above-height (and directly-above (apply 'max
- (mapcar
- 'org-real--get-height
- (seq-filter
- (lambda (child)
- (= (with-slots
(y-order) directly-above y-order)
- (with-slots
(y-order) child y-order)))
- (org-real--get-all
- (with-slots
(children) parent children))))))))
- (if directly-above
- (+ (org-real--get-top directly-above)
- above-height)
- (with-slots (rel rel-box) box
- (if (and (slot-boundp box :rel)
- (or (string= "to the left of" rel)
- (string= "to the right of" rel)))
- (org-real--get-top rel-box)
- top)))))))
-
-(cl-defmethod org-real--get-left ((box org-real-box))
- "Get the left column index of BOX."
- (if (not (slot-boundp box :parent))
- 0
- (with-slots (parent x-order y-order) box
- (let* ((left (+ 1
- (car org-real-padding)
- (org-real--get-left parent)))
- (to-the-left (seq-filter
- (lambda (child)
- (with-slots ((child-y y-order) (child-x x-order))
child
- (and (= y-order child-y)
- (< child-x x-order))))
- (org-real--get-all (with-slots (children) parent
children))))
- (directly-left (and to-the-left
- (seq-reduce
- (lambda (max child)
- (with-slots ((max-x x-order)) max
- (with-slots ((child-x x-order)) child
- (if (> child-x max-x)
- child
- max))))
- to-the-left
- (org-real-box :x-order -9999)))))
- (if directly-left
- (+ (org-real--get-left directly-left)
- (org-real--get-width directly-left)
- (car org-real-margin))
- (with-slots (rel rel-box) box
- (if (and (slot-boundp box :rel)
- (or (string= "above" rel)
- (string= "below" rel)))
- (org-real--get-left rel-box)
- left)))))))
-
-;;;; Utility expressions
-
-(cl-defmethod org-real--get-all ((collection org-real-box-collection))
- "Get all boxes in COLLECTION as a sequence."
- (with-slots (box next) collection
- (append (if (slot-boundp collection :box) (list box))
- (if (slot-boundp collection :next) (org-real--get-all next)))))
-
-(cl-defmethod org-real--add-to-list ((collection org-real-box-collection)
- (box org-real-box))
- "Add BOX to COLLECTION and return new COLLECTION."
- (if (slot-boundp collection :box)
- (org-real-box-collection
- :box box
- :next collection)
- (oset collection :box box)
- collection))
-
-(cl-defmethod org-real--make-instance-helper (containers parent (prev
org-real-box))
- "Help create a 3D representation of CONTAINERS.
-
-PREV must already existing in PARENT."
- (let* ((container (pop containers))
- (rel (plist-get container :rel))
- (box (org-real-box :name (plist-get container :name))))
- (when prev
- (oset box :rel (plist-get container :rel))
- (oset box :rel-box prev)
- (with-slots
- ((cur-x x-order)
- (cur-y y-order)
- (cur-behind behind)
- (cur-in-front in-front))
- box
- (with-slots
- ((prev-x x-order)
- (prev-y y-order)
- (prev-behind behind)
- (prev-in-front in-front))
- prev
- (cond ((or (string= rel "in") (string= rel "on"))
- (setq cur-x prev-x)
- (setq cur-y prev-y)
- (setq cur-behind prev-behind))
- ((string= rel "behind")
- (setq cur-x prev-x)
- (setq cur-y prev-y)
- (setq cur-behind t))
- ((string= rel "in front of")
- (setq cur-x prev-x)
- (setq cur-y 9999)
- (setq cur-behind prev-behind)
- (setq cur-in-front t))
- ((string= rel "above")
- (setq cur-x prev-x)
- (setq cur-y (- prev-y 1))
- (setq cur-behind prev-behind))
- ((string= rel "below")
- (setq cur-x prev-x)
- (setq cur-y (+ 1 prev-y))
- (setq cur-behind prev-behind)
- (setq cur-in-front prev-in-front))
- ((string= rel "to the left of")
- (setq cur-x (- prev-x 1))
- (setq cur-y prev-y)
- (setq cur-behind prev-behind)
- (setq cur-in-front prev-in-front))
- ((string= rel "to the right of")
- (setq cur-x (+ 1 prev-x))
- (setq cur-y prev-y)
- (setq cur-behind prev-behind)
- (setq cur-in-front prev-in-front))))))
-
- (if (and prev (member rel '("in" "on" "behind" "in front of")))
- (progn
- (oset box :parent prev)
- (oset prev :children (org-real--add-to-list (with-slots (children)
prev children) box))
- (if containers
- (org-real--make-instance-helper containers prev box)
- (oset box :primary t)))
- (oset box :parent parent)
- (oset parent :children (org-real--add-to-list (with-slots (children)
parent children) box))
- (if containers
- (org-real--make-instance-helper containers parent box)
- (oset box :primary t)))))
-
-(cl-defmethod org-real--map-immediate (fn (box org-real-box))
- "Map a function FN across all immediate relatives of BOX, including BOX.
-
-Any box with a :rel-box slot equivalent to BOX will be passed to
-FN."
- (progn
- (funcall fn box)
- (mapc
- (lambda (box) (org-real--map-immediate fn box))
- (org-real--next box t))))
-
-(cl-defmethod org-real--next ((box org-real-box) &optional exclude-children)
- "Retrieve any boxes for which the :rel-box slot is BOX.
-
-If EXCLUDE-CHILDREN, only retrieve sibling boxes."
- (let ((relatives (append (if exclude-children '() (org-real--get-all
- (with-slots (children)
box children)))
- (if (slot-boundp box :parent)
- (org-real--get-all
- (with-slots
- (children)
- (with-slots (parent) box parent)
- children))
- '()))))
- (seq-filter
- (lambda (relative)
- (and (slot-boundp relative :rel-box)
- (string= (with-slots
- (name)
- (with-slots (rel-box) relative rel-box)
- name)
- (with-slots (name) box name))))
- relatives)))
-
-(cl-defmethod org-real--expand ((box org-real-box))
- "Get a list of all boxes, including BOX, that are children of BOX."
- (with-slots (children) box
- (apply 'append (list box) (mapcar 'org-real--expand (org-real--get-all
children)))))
-
-(cl-defmethod org-real--merge-into ((from org-real-box) (to org-real-box))
- "Merge FROM box into TO box."
- (let ((from-boxes (reverse (org-real--expand from)))
- (to-boxes (reverse (org-real--expand to))))
- (unless (seq-some
- (lambda (from-box)
- (seq-some
- (lambda (to-box)
- (when (and (slot-boundp from-box :name)
- (slot-boundp to-box :name)
- (string= (with-slots (name) from-box name)
- (with-slots (name) to-box name)))
- (org-real--add-matching from-box to-box to)
- t))
- to-boxes))
- from-boxes)
- (org-real--flex-add from to to))))
-
-(cl-defmethod org-real--add-matching ((box org-real-box)
- (match org-real-box)
- (world org-real-box))
- "Add BOX to WORLD after finding a matching box MATCH already in WORLD.
-
-MATCH is used to set the :rel-box and :parent slots on children
-of BOX."
- (with-slots
- (parent
- (match-y y-order)
- (match-x x-order)
- (match-behind behind)
- (match-in-front in-front))
- match
- (let ((next-boxes (org-real--next box)))
- (mapc
- (lambda (next)
- (with-slots
- (rel
- (next-y y-order)
- (next-x x-order)
- (next-behind behind)
- (next-in-front in-front))
- next
- (cond
- ((string= rel "above")
- (setq next-y match-y)
- (org-real--map-immediate
- (lambda (child)
- (with-slots ((child-y y-order)) child
- (when (>= child-y match-y)
- (setq child-y (+ 1 child-y)))))
- match)
- (setq next-x match-x)
- (setq next-behind match-behind))
- ((string= rel "below")
- (setq next-y (+ 1 match-y))
- (org-real--map-immediate
- (lambda (child)
- (with-slots ((child-y y-order)) child
- (when (> child-y match-y)
- (setq child-y (+ 1 child-y)))))
- match)
- (setq next-x match-x)
- (setq next-behind match-behind))
- ((string= rel "to the right of")
- (setq next-x (+ 1 match-x))
- (org-real--map-immediate
- (lambda (child)
- (with-slots ((child-x x-order)) child
- (when (> child-x match-x)
- (setq child-x (+ 1 child-x)))))
- match)
- (setq next-y match-y)
- (setq next-behind match-behind)
- (setq next-in-front match-in-front))
- ((string= rel "to the left of")
- (setq next-x match-x)
- (org-real--map-immediate
- (lambda (child)
- (with-slots ((child-x x-order)) child
- (when (>= child-x match-x)
- (setq child-x (+ 1 child-x)))))
- match)
- (setq next-y match-y)
- (setq next-behind match-behind)
- (setq next-in-front match-in-front)))
-
- (oset next :rel-box match)
- (if (member rel '("in" "on" "behind" "in front of"))
- (org-real--flex-add next match world)
- (oset next :parent parent)
- (oset parent :children (org-real--add-to-list
- (with-slots (children) parent children)
- next)))
- (org-real--add-matching next next world)))
- next-boxes))))
-
-(cl-defmethod org-real--flex-add ((box org-real-box)
- (parent org-real-box)
- (world org-real-box))
- "Add BOX to a PARENT box already existing in WORLD.
-
-This function ignores the :rel slot and adds BOX in such a way
-that the width of WORLD is kept below 80 characters if possible."
- (with-slots ((siblings children)) parent
- (let* ((cur-width (org-real--get-width world))
- (siblings (org-real--get-all siblings))
- (last-sibling (and siblings (seq-reduce
- (lambda (max sibling)
- (with-slots
- ((max-x x-order)
- (max-y y-order))
- max
- (with-slots
- ((sibling-x x-order)
- (sibling-y y-order))
- sibling
- (if (> sibling-y max-y)
- sibling
- (if (and (= max-y sibling-y)
(> sibling-x max-x))
- sibling
- max)))))
- (seq-filter
- (lambda (sibling)
- (not (with-slots (in-front) sibling
in-front)))
- siblings)
- (org-real-box :y-order -9999)))))
- (oset box :parent parent)
- (oset parent :children (org-real--add-to-list (with-slots (children)
parent children) box))
- (when (and last-sibling (not (with-slots (in-front) box in-front)))
- (with-slots
- ((last-sibling-y y-order)
- (last-sibling-x x-order))
- last-sibling
- (oset box :y-order last-sibling-y)
- (oset box :x-order (+ 1 last-sibling-x))
- (let ((new-width (org-real--get-width world)))
- (when (and (> new-width cur-width) (> new-width 80))
- (oset box :y-order (+ 1 last-sibling-y))
- (oset box :x-order 0))))))))
-
-
-
-(provide 'org-real-box)
-
-;;; org-real-box.el ends here
diff --git a/org-real-pkg.el b/org-real-pkg.el
deleted file mode 100644
index 7745852..0000000
--- a/org-real-pkg.el
+++ /dev/null
@@ -1,5 +0,0 @@
-(define-package
- "org-real"
- "0.1.0"
- "Keep track of real things as org-mode links"
- '((emacs "26.1")))
diff --git a/org-real.el b/org-real.el
index 45309d6..a7f3c8d 100644
--- a/org-real.el
+++ b/org-real.el
@@ -19,8 +19,9 @@
;;;; Requirements
+(require 'eieio)
(require 'org-element)
-(require 'cl-extra)
+(require 'cl-lib)
(require 'org-real-box)
@@ -56,7 +57,519 @@ vertical padding"
'("in" "on" "behind" "in front of" "above" "below" "to the left of" "to the
right of")
"List of available prepositions for things.")
-;;;; Utility expressions
+;;;; Class definitions
+
+(defclass org-real-box-collection ()
+ ((box :initarg :box
+ :type org-real-box)
+ (next :initarg :next
+ :type org-real-box-collection))
+ "A collection of `org-real-box'es.")
+
+(defclass org-real-box ()
+ ((name :initarg :name
+ :type string)
+ (rel :initarg :rel
+ :type string)
+ (rel-box :initarg :rel-box
+ :type org-real-box)
+ (x-order :initarg :x-order
+ :initform 0
+ :type number)
+ (y-order :initarg :y-order
+ :initform 0
+ :type number)
+ (in-front :initarg :in-front
+ :initform nil
+ :type boolean)
+ (behind :initarg :behind
+ :initform nil
+ :type boolean)
+ (parent :initarg :parent
+ :type org-real-box)
+ (children :initarg :children
+ :initform (org-real-box-collection)
+ :type org-real-box-collection)
+ (primary :initarg :primary
+ :initform nil
+ :type boolean))
+ "A representation of a box in 3D space.")
+
+
+(cl-defmethod org-real--make-instance ((_ (subclass org-real-box)) containers)
+ "Create an instance of `org-real-box' from CONTAINERS.
+
+CONTAINERS is a list of plists containing at least a :name
+property and optionally a :rel property."
+ (when-let* ((world (org-real-box))
+ (base-container (pop containers))
+ (base (org-real-box :name (plist-get base-container :name))))
+ (oset base :parent world)
+ (with-slots (children) world
+ (setq children (org-real--add-to-list children base)))
+ (if containers
+ (org-real--make-instance-helper containers world base))
+ world))
+
+(cl-defmethod org-real--merge (boxes)
+ "Merge BOXES into a single box."
+ (if (< (length boxes) 2)
+ (if (= 0 (length boxes))
+ (org-real-box)
+ (car boxes))
+ (let ((world (org-real-box)))
+ (while boxes
+ (org-real--merge-into (pop boxes) world))
+ world)))
+
+;;;; Drawing
+
+(cl-defmethod org-real--draw ((box org-real-box) offset)
+ "Insert an ascii drawing of BOX into the current buffer.
+
+OFFSET is the starting line to start insertion."
+ (let ((children (with-slots (children) box (org-real--get-all children))))
+ (if (slot-boundp box :name)
+ (with-slots (name behind (align-bottom in-front) (dashed behind)
primary) box
+ (let* ((top (+ offset (org-real--get-top box)))
+ (left (org-real--get-left box))
+ (width (org-real--get-width box))
+ (height (org-real--get-height box)))
+ (cl-flet ((draw (coords str &optional primary)
+ (forward-line (- (car coords)
(line-number-at-pos)))
+ (move-to-column (cdr coords) t)
+ (if primary
+ (put-text-property 0 (length str) 'face
'org-real-primary
+ str))
+ (insert str)
+ (delete-char (length str))))
+ (draw (cons top left)
+ (concat "┌" (make-string (- width 2) (if dashed #x254c
#x2500)) "┐"))
+ (if align-bottom
+ (draw (cons (+ top height) left)
+ (concat "┴" (make-string (- width 2) (if dashed #x254c
#x2500)) "┴"))
+ (draw (cons (+ top height -1) left)
+ (concat "└" (make-string (- width 2) (if dashed #x254c
#x2500)) "┘")))
+ (draw (cons (+ top 1 (cdr org-real-padding))
+ (+ left 1 (car org-real-padding)))
+ name
+ primary)
+ (let ((r (+ top 1))
+ (c1 left)
+ (c2 (+ left width -1)))
+ (dotimes (_ (- height (if align-bottom 1 2)))
+ (draw (cons r c1) (if dashed "╎" "│"))
+ (draw (cons r c2) (if dashed "╎" "│"))
+ (setq r (+ r 1))))))))
+ (mapc
+ (lambda (child) (org-real--draw child offset))
+ children)))
+
+(cl-defmethod org-real--get-width ((box org-real-box))
+ "Get the width of BOX."
+ (let* ((base-width (+ 2 ; box walls
+ (* 2 (car org-real-padding))))
+ (width (+ base-width
+ (if (slot-boundp box :name)
+ (with-slots (name) box (length name))
+ 0)))
+ (children (with-slots (children) box (org-real--get-all children))))
+ (if (not children)
+ width
+ (let* ((column-indices (cl-delete-duplicates
+ (mapcar (lambda (child) (with-slots (x-order)
child x-order)) children)))
+ (columns (mapcar
+ (lambda (c)
+ (seq-filter
+ (lambda (child)
+ (with-slots (x-order) child
+ (= c x-order)))
+ children))
+ column-indices))
+ (column-widths (mapcar
+ (lambda (column)
+ (apply 'max (mapcar 'org-real--get-width
column)))
+ columns))
+ (children-width (seq-reduce
+ (lambda (total width)
+ (+ total (car org-real-margin) width))
+ column-widths
+ (* -1 (car org-real-margin)))))
+ (if (> width (+ (* 2 (car org-real-margin)) children-width))
+ width
+ (+ base-width children-width))))))
+
+(cl-defmethod org-real--get-height ((box org-real-box))
+ "Get the height of BOX."
+ (let* ((in-front (with-slots (in-front) box in-front))
+ (height (+ (if in-front
+ (* -1 (cdr org-real-margin))
+ 0)
+ 3 ; box walls + text
+ (cdr org-real-padding)
+ (cdr org-real-margin)))
+ (children (with-slots (children) box (org-real--get-all children))))
+ (if (not children)
+ height
+ (let* ((row-indices (cl-delete-duplicates
+ (mapcar (lambda (child) (with-slots (y-order) child
y-order)) children)))
+ (rows (mapcar
+ (lambda (r)
+ (seq-filter
+ (lambda (child)
+ (with-slots (y-order) child
+ (= r y-order)))
+ children))
+ row-indices))
+ (row-heights (mapcar
+ (lambda (row)
+ (apply 'max (mapcar 'org-real--get-height row)))
+ rows)))
+ (+ height (seq-reduce '+ row-heights 0))))))
+
+(cl-defmethod org-real--get-top ((box org-real-box))
+ "Get the top row index of BOX."
+ (if (not (slot-boundp box :parent))
+ 0
+ (with-slots (parent x-order y-order) box
+ (let* ((offset (+ 2 (cdr org-real-padding) (cdr org-real-margin)))
+ (top (+ offset (org-real--get-top parent)))
+ (above (seq-filter
+ (lambda (child)
+ (with-slots ((child-x x-order) (child-y y-order)) child
+ (and (= x-order child-x)
+ (< child-y y-order))))
+ (org-real--get-all (with-slots (children) parent
children))))
+ (directly-above (and above (seq-reduce
+ (lambda (max child)
+ (with-slots ((max-y y-order)) max
+ (with-slots ((child-y y-order))
child
+ (if (> child-y max-y)
+ child
+ max))))
+ above
+ (org-real-box :y-order -9999))))
+ (above-height (and directly-above (apply 'max
+ (mapcar
+ 'org-real--get-height
+ (seq-filter
+ (lambda (child)
+ (= (with-slots
(y-order) directly-above y-order)
+ (with-slots
(y-order) child y-order)))
+ (org-real--get-all
+ (with-slots
(children) parent children))))))))
+ (if directly-above
+ (+ (org-real--get-top directly-above)
+ above-height)
+ (with-slots (rel rel-box) box
+ (if (and (slot-boundp box :rel)
+ (or (string= "to the left of" rel)
+ (string= "to the right of" rel)))
+ (org-real--get-top rel-box)
+ top)))))))
+
+(cl-defmethod org-real--get-left ((box org-real-box))
+ "Get the left column index of BOX."
+ (if (not (slot-boundp box :parent))
+ 0
+ (with-slots (parent x-order y-order) box
+ (let* ((left (+ 1
+ (car org-real-padding)
+ (org-real--get-left parent)))
+ (to-the-left (seq-filter
+ (lambda (child)
+ (with-slots ((child-y y-order) (child-x x-order))
child
+ (and (= y-order child-y)
+ (< child-x x-order))))
+ (org-real--get-all (with-slots (children) parent
children))))
+ (directly-left (and to-the-left
+ (seq-reduce
+ (lambda (max child)
+ (with-slots ((max-x x-order)) max
+ (with-slots ((child-x x-order)) child
+ (if (> child-x max-x)
+ child
+ max))))
+ to-the-left
+ (org-real-box :x-order -9999)))))
+ (if directly-left
+ (+ (org-real--get-left directly-left)
+ (org-real--get-width directly-left)
+ (car org-real-margin))
+ (with-slots (rel rel-box) box
+ (if (and (slot-boundp box :rel)
+ (or (string= "above" rel)
+ (string= "below" rel)))
+ (org-real--get-left rel-box)
+ left)))))))
+
+;;;; `org-real-box' utility expressions
+
+(cl-defmethod org-real--get-all ((collection org-real-box-collection))
+ "Get all boxes in COLLECTION as a sequence."
+ (with-slots (box next) collection
+ (append (if (slot-boundp collection :box) (list box))
+ (if (slot-boundp collection :next) (org-real--get-all next)))))
+
+(cl-defmethod org-real--add-to-list ((collection org-real-box-collection)
+ (box org-real-box))
+ "Add BOX to COLLECTION and return new COLLECTION."
+ (if (slot-boundp collection :box)
+ (org-real-box-collection
+ :box box
+ :next collection)
+ (oset collection :box box)
+ collection))
+
+(cl-defmethod org-real--make-instance-helper (containers parent (prev
org-real-box))
+ "Help create a 3D representation of CONTAINERS.
+
+PREV must already existing in PARENT."
+ (let* ((container (pop containers))
+ (rel (plist-get container :rel))
+ (box (org-real-box :name (plist-get container :name))))
+ (when prev
+ (oset box :rel (plist-get container :rel))
+ (oset box :rel-box prev)
+ (with-slots
+ ((cur-x x-order)
+ (cur-y y-order)
+ (cur-behind behind)
+ (cur-in-front in-front))
+ box
+ (with-slots
+ ((prev-x x-order)
+ (prev-y y-order)
+ (prev-behind behind)
+ (prev-in-front in-front))
+ prev
+ (cond ((or (string= rel "in") (string= rel "on"))
+ (setq cur-x prev-x)
+ (setq cur-y prev-y)
+ (setq cur-behind prev-behind))
+ ((string= rel "behind")
+ (setq cur-x prev-x)
+ (setq cur-y prev-y)
+ (setq cur-behind t))
+ ((string= rel "in front of")
+ (setq cur-x prev-x)
+ (setq cur-y 9999)
+ (setq cur-behind prev-behind)
+ (setq cur-in-front t))
+ ((string= rel "above")
+ (setq cur-x prev-x)
+ (setq cur-y (- prev-y 1))
+ (setq cur-behind prev-behind))
+ ((string= rel "below")
+ (setq cur-x prev-x)
+ (setq cur-y (+ 1 prev-y))
+ (setq cur-behind prev-behind)
+ (setq cur-in-front prev-in-front))
+ ((string= rel "to the left of")
+ (setq cur-x (- prev-x 1))
+ (setq cur-y prev-y)
+ (setq cur-behind prev-behind)
+ (setq cur-in-front prev-in-front))
+ ((string= rel "to the right of")
+ (setq cur-x (+ 1 prev-x))
+ (setq cur-y prev-y)
+ (setq cur-behind prev-behind)
+ (setq cur-in-front prev-in-front))))))
+
+ (if (and prev (member rel '("in" "on" "behind" "in front of")))
+ (progn
+ (oset box :parent prev)
+ (oset prev :children (org-real--add-to-list (with-slots (children)
prev children) box))
+ (if containers
+ (org-real--make-instance-helper containers prev box)
+ (oset box :primary t)))
+ (oset box :parent parent)
+ (oset parent :children (org-real--add-to-list (with-slots (children)
parent children) box))
+ (if containers
+ (org-real--make-instance-helper containers parent box)
+ (oset box :primary t)))))
+
+(cl-defmethod org-real--map-immediate (fn (box org-real-box))
+ "Map a function FN across all immediate relatives of BOX, including BOX.
+
+Any box with a :rel-box slot equivalent to BOX will be passed to
+FN."
+ (progn
+ (funcall fn box)
+ (mapc
+ (lambda (box) (org-real--map-immediate fn box))
+ (org-real--next box t))))
+
+(cl-defmethod org-real--next ((box org-real-box) &optional exclude-children)
+ "Retrieve any boxes for which the :rel-box slot is BOX.
+
+If EXCLUDE-CHILDREN, only retrieve sibling boxes."
+ (let ((relatives (append (if exclude-children '() (org-real--get-all
+ (with-slots (children)
box children)))
+ (if (slot-boundp box :parent)
+ (org-real--get-all
+ (with-slots
+ (children)
+ (with-slots (parent) box parent)
+ children))
+ '()))))
+ (seq-filter
+ (lambda (relative)
+ (and (slot-boundp relative :rel-box)
+ (string= (with-slots
+ (name)
+ (with-slots (rel-box) relative rel-box)
+ name)
+ (with-slots (name) box name))))
+ relatives)))
+
+(cl-defmethod org-real--expand ((box org-real-box))
+ "Get a list of all boxes, including BOX, that are children of BOX."
+ (with-slots (children) box
+ (apply 'append (list box) (mapcar 'org-real--expand (org-real--get-all
children)))))
+
+(cl-defmethod org-real--merge-into ((from org-real-box) (to org-real-box))
+ "Merge FROM box into TO box."
+ (let ((from-boxes (reverse (org-real--expand from)))
+ (to-boxes (reverse (org-real--expand to))))
+ (unless (seq-some
+ (lambda (from-box)
+ (seq-some
+ (lambda (to-box)
+ (when (and (slot-boundp from-box :name)
+ (slot-boundp to-box :name)
+ (string= (with-slots (name) from-box name)
+ (with-slots (name) to-box name)))
+ (org-real--add-matching from-box to-box to)
+ t))
+ to-boxes))
+ from-boxes)
+ (org-real--flex-add from to to))))
+
+(cl-defmethod org-real--add-matching ((box org-real-box)
+ (match org-real-box)
+ (world org-real-box))
+ "Add BOX to WORLD after finding a matching box MATCH already in WORLD.
+
+MATCH is used to set the :rel-box and :parent slots on children
+of BOX."
+ (with-slots
+ (parent
+ (match-y y-order)
+ (match-x x-order)
+ (match-behind behind)
+ (match-in-front in-front))
+ match
+ (let ((next-boxes (org-real--next box)))
+ (mapc
+ (lambda (next)
+ (with-slots
+ (rel
+ (next-y y-order)
+ (next-x x-order)
+ (next-behind behind)
+ (next-in-front in-front))
+ next
+ (cond
+ ((string= rel "above")
+ (setq next-y match-y)
+ (org-real--map-immediate
+ (lambda (child)
+ (with-slots ((child-y y-order)) child
+ (when (>= child-y match-y)
+ (setq child-y (+ 1 child-y)))))
+ match)
+ (setq next-x match-x)
+ (setq next-behind match-behind))
+ ((string= rel "below")
+ (setq next-y (+ 1 match-y))
+ (org-real--map-immediate
+ (lambda (child)
+ (with-slots ((child-y y-order)) child
+ (when (> child-y match-y)
+ (setq child-y (+ 1 child-y)))))
+ match)
+ (setq next-x match-x)
+ (setq next-behind match-behind))
+ ((string= rel "to the right of")
+ (setq next-x (+ 1 match-x))
+ (org-real--map-immediate
+ (lambda (child)
+ (with-slots ((child-x x-order)) child
+ (when (> child-x match-x)
+ (setq child-x (+ 1 child-x)))))
+ match)
+ (setq next-y match-y)
+ (setq next-behind match-behind)
+ (setq next-in-front match-in-front))
+ ((string= rel "to the left of")
+ (setq next-x match-x)
+ (org-real--map-immediate
+ (lambda (child)
+ (with-slots ((child-x x-order)) child
+ (when (>= child-x match-x)
+ (setq child-x (+ 1 child-x)))))
+ match)
+ (setq next-y match-y)
+ (setq next-behind match-behind)
+ (setq next-in-front match-in-front)))
+
+ (oset next :rel-box match)
+ (if (member rel '("in" "on" "behind" "in front of"))
+ (org-real--flex-add next match world)
+ (oset next :parent parent)
+ (oset parent :children (org-real--add-to-list
+ (with-slots (children) parent children)
+ next)))
+ (org-real--add-matching next next world)))
+ next-boxes))))
+
+(cl-defmethod org-real--flex-add ((box org-real-box)
+ (parent org-real-box)
+ (world org-real-box))
+ "Add BOX to a PARENT box already existing in WORLD.
+
+This function ignores the :rel slot and adds BOX in such a way
+that the width of WORLD is kept below 80 characters if possible."
+ (with-slots ((siblings children)) parent
+ (let* ((cur-width (org-real--get-width world))
+ (siblings (org-real--get-all siblings))
+ (last-sibling (and siblings (seq-reduce
+ (lambda (max sibling)
+ (with-slots
+ ((max-x x-order)
+ (max-y y-order))
+ max
+ (with-slots
+ ((sibling-x x-order)
+ (sibling-y y-order))
+ sibling
+ (if (> sibling-y max-y)
+ sibling
+ (if (and (= max-y sibling-y)
(> sibling-x max-x))
+ sibling
+ max)))))
+ (seq-filter
+ (lambda (sibling)
+ (not (with-slots (in-front) sibling
in-front)))
+ siblings)
+ (org-real-box :y-order -9999)))))
+ (oset box :parent parent)
+ (oset parent :children (org-real--add-to-list (with-slots (children)
parent children) box))
+ (when (and last-sibling (not (with-slots (in-front) box in-front)))
+ (with-slots
+ ((last-sibling-y y-order)
+ (last-sibling-x x-order))
+ last-sibling
+ (oset box :y-order last-sibling-y)
+ (oset box :x-order (+ 1 last-sibling-x))
+ (let ((new-width (org-real--get-width world)))
+ (when (and (> new-width cur-width) (> new-width 80))
+ (oset box :y-order (+ 1 last-sibling-y))
+ (oset box :x-order 0))))))))
+
+
+;;;; General utility expressions
(defun org-real--find-last-index (pred sequence)
"Return the index of the last element for which (PRED element) is non-nil in
SEQUENCE."
- [elpa] externals/org-real 0974b67 023/160: Make changes to satisfy elc compiler, (continued)
- [elpa] externals/org-real 0974b67 023/160: Make changes to satisfy elc compiler, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 4c2915a 033/160: Updated README, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 89d616e 024/160: Check compilation during ci/cd pipeline, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real ed47eaa 048/160: Using stored values for computing top left width and height, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real c1a21a5 050/160: Added 'on top of' preposition; update customization vars, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 180d374 014/160: Standardized pretty printing for org-real-world and opening a link, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 356767c 034/160: Added org-real-pkg for multifile package, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real dd03f41 025/160: Initial release, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 0b764c7 022/160: get-width compares children with margins included, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real a5df40f 026/160: Bump version, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real ac799d3 040/160: Merge into single file,
ELPA Syncer <=
- [elpa] externals/org-real 7d9d67d 044/160: Rearranging, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 2ebeb5c 046/160: Updated readme, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 8445765 047/160: Added customization group, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real cb64694 051/160: Added children when following a link, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 01899e9 052/160: More edge cases, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real b9a7e8a 053/160: Removed existing containers from completion candidates, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 8b6a4e1 054/160: Added org-real-flex-width custom variable, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 91b96a1 057/160: Renamed org-real-include-children to org-real-include-context, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 35aa1c1 062/160: Updated readme, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 43f349e 067/160: Typos, ELPA Syncer, 2021/10/06