;; -*- lexical-binding: t; -*- ;;; The Object Prototype ( defun publication-object ( ) ( let ( ( object-projects ( list ) ) ( org-publish-project-alist ( list ) ) ( success-report "Build complete!" ) ) ( list :object-compose ( lambda ( ) ( setq org-publish-project-alist ( list object-projects ) ) ) :object-get-projects ( lambda ( project-data ) ( setq object-projects ( append project-data object-projects ) ) ) :object-report ( lambda ( ) ( print org-publish-project-alist ) ( print success-report ) ) ) ) ) ;;; The Object Interface ( defun object-compose ( publication-instance ) ( funcall ( plist-get publication-instance :object-compose ) ) ) ( defun object-get-projects ( publication-instance project-data ) ( funcall ( plist-get publication-instance :object-get-projects ) project-data ) ) ( defun object-report ( publication-instance ) ( funcall ( plist-get publication-instance :object-report ) ) ) ;;; The User Logic ( defun atypical-header-p ( project-data ) ( let ( ( element-1 ( pop project-data ) ) ( element-2 ( pop project-data ) ) ( error-1 "First element is not a string: " ) ( error-2 "Second element is not a keyword: " ) ) ( condition-case error ( cond ( ( not ( stringp element-1 ) ) ( signal 'scan-error ( concat error-1 element-1 ) ) ) ( ( not ( keywordp element-2 ) ) ( signal 'scan-error ( concat error-2 element-2 ) ) ) ) ( scan-error ( print ( cdr error ) ) ) ) ) ) ( defun export-project-alist ( publication-instance ) ( object-compose publication-instance ) ( object-report publication-instance ) ) ( defun get-component ( project-data ) ( let ( ( component ( nth 2 project-data ) ) ) ( print component ) component ) ) ( defun has-component-p ( project-data ) ( let ( ( component-keyword ':components ) ( second ( nth 1 project-data ) ) ) ( eq component-keyword second ) ) ) ( defun import-data ( publication-instance project-data ) ( object-get-projects publication-instance project-data ) ) ( defun too-short-p ( project-data ) ( let ( ( minimal-length 2 ) ) ( < ( length project-data ) minimal-length ) ) ) ;;; The User Interface ( defun publish ( publication-instance &rest project-data-wrapped ) ( let ( ( project-data ( car project-data-wrapped ) ) ) ( pcase project-data ( ( guard ( too-short-p project-data ) ) nil ) ( ( guard ( atypical-header-p project-data ) nil ) ) ( ( pred has-component-p project-data ) ( let ( ( component ( get-component project-data ) ) ( head ( nth 0 project-data ) ) ( tail ( nthcdr 3 project-data ) ) ) ( list head ( publish publication-instance component ) ( publish publication-instance tail ) ) ) ) ( _ ( progn ( import-data publication-instance project-data ) ( export-project-alist publication-instance ) ) ) ) ) )