From 85390b8e71376aa101efd0b241751c65d8f1aff4 Mon Sep 17 00:00:00 2001 From: ronny abraham Date: Wed, 25 Mar 2026 03:46:09 +0200 Subject: [PATCH] add parser for begin_image_row blocks --- config.el | 1 + ronny/parser.el | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 ronny/parser.el diff --git a/config.el b/config.el index fbfd599..bd38df0 100644 --- a/config.el +++ b/config.el @@ -158,6 +158,7 @@ ;; --- ronny core --- (load! "ronny/core") +(load! "ronny/parser") ;; Doom keybindings under SPC m C (map! :map org-mode-map diff --git a/ronny/parser.el b/ronny/parser.el new file mode 100644 index 0000000..795cefb --- /dev/null +++ b/ronny/parser.el @@ -0,0 +1,109 @@ +;;; 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 +;;
+;; +;; +;;
+;; +;; 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