;;; ronny/parser.el -*- lexical-binding: t; -*- ;; extract links from HTML ;; take exported HTML like ;; some text ;; other text ;; ;; turn it to Lisp data ;; (("url1" . "some text") ;; ("url2" . "other text")) ;; ;; arguments ;; html ;; ;; 1a create a local variable items, initiall empty (nil) ;; 2a create a temporary scratch buffer to search through the HTML text safely ;; 2b put the HTML string into that temporary buffer ;; 2c go to the start of the buffer ;; 3a loop through links ;; 3b search for links of the form ;; CAPTION ;; 4a store each link and build a pair ("url" . "caption") and push it into 'items' ;; 5a reverse the order because push built the list backwards, so restore original order (defun ronny-parser--extract-html-links (html) "Extract (url . caption) pairs from exported HTML links." (let (items) ;; 1a (with-temp-buffer ;; 2a (insert html) ;; 2b (goto-char (point-min)) ;; 2c (while (re-search-forward ;; 3a "\\([^<]+\\)" ;; 3b nil t) (push (cons (match-string 1) (match-string 2)) items))) ;; 4a (nreverse items))) ;; 5a ;; convert parsed links into final HTML ;; ;; take list data of the form ;; (("url1" . "caption1") ;; ("url2" . "caption2")) ;; ;; and turn it into ;;
;;
shy cat
;;
happy cat
;;
;; ;; arguments: ;; items -> list of (url . caption) pairs ;; ;; 1a create the row container leave %s as the place whre all image items go ;; ;; 2a build all items ;; map over each item ;; convert it to a string ;; join them together ;; ;; 2b for each item process one pair at a time ;; 2c split pair into url and caption ;; ;; 2d build image block ;; 2e join with newlines (defun ronny-parser--build-image-row-html (items) "Build custom image row HTML from ITEMS." (format ;; 1a "
\n%s\n
" ;; 1a (mapconcat ;; 2a (lambda (item) ;; 2b (let ((url (car item)) ;; 2c (caption (cdr item))) ;; 2c (format ;; 2d "
%s
" url url caption))) items ;; 2e "\n"))) ;; 2e ;; filter the exported special block ;; this is the function Org calls during export ;; if HTML export, transform it. otherwise leave it alone ;; ;; arguments: ;; text - exported text for the special block ;; backend - export target (html, latex, etc) ;; info - export metadata ;; ;; 1a check backend and only do custom logic for HTML ;; 2a extra links. parse the block's HTML and get (url . caption) list ;; 2b if links found rebuild block as custom image row ;; otherwise return original text (defun ronny-parser-filter-image-row (text backend info) "Replace an exported image_row special block with custom HTML." (if (org-export-derived-backend-p backend 'html) ;; 1a (let ((items (ronny-parser--extract-html-links text))) ;; 2a (if items ;; 2b (ronny-parser--build-image-row-html items) ;; 2b text)) ;; 2b text)) ;; register the filter with Org ;; after export machinery is loaded use this function for special blocks ;; ;; 1a ox is Org export. prevents errors if export code is not loaded yet ;; 1b add the function to the list of special-block filters (with-eval-after-load 'ox ;; 1a (add-to-list 'org-export-filter-special-block-functions ;; 1b #'ronny-parser-filter-image-row)) ;; 1b