I'm building a blog with org-mode publish. But I'm wanting to edit the default style given by org-mode, that edition implies wrap some tags in other tags (like divs tags). So the way I am building this is based some ideas (check the link below).
e.g. The below function it's adding a class attribute to the body tag, and it works! (The idea is based on this question)
(defun my-html-body-onload-filter (output backend info)
"Add class to<body> tag, if any."
(when (and (eq backend 'html)
(string-match "<body>\n" output))
(replace-match "<body class='uk-container-small uk-align-center uk-text-justify'> \n" nil nil output))
)
So the thing I want to do right now, it's wrap img tags in other tags. I'm not a elisp programmer but I'm trying to build a function to reach some solution. So the actual problem is this: I have this:
<img src="images/photo.jpg" alt="">
I need to wrap img tags so I can see the next output:
<div uk-lightbox="animation: slide">
<a href="images/photo.jpg">
<img src="images/photo.jpg" alt="">
</a>
</div>
So far I created this little function to extract the src value:
(defun xe ()
(interactive)
(search-forward "<img src=\"")
(defvar x-start (point))
(search-forward "\"")
(backward-char)
(defvar x-end (point))
(kill-ring-save x-start x-end)
)
But I feel like lost, because I don't know much about elisp... so if anyone knows how to keep going (or has the solution) to solve this problem, I would be happy:)
Well Hello there, This was my final solution:
I created this function(Note: as you can see this function is not optimized but works, maybe I will edit this answer to post the final optimized solution):
(defun wrap-img-tags ()
(setq text-to-search-1 "<img src=\"")
(goto-char (point-min))
(setq ntimes (count-matches text-to-search-1))
(if (> ntimes 0)
(cl-loop repeat ntimes do ;; this is like a for loop
(search-forward "<img src=\"" nil t)
(setq x-start (point))
(search-forward "\"")
(backward-char)
(setq x-end (point))
(kill-ring-save x-start x-end)
(beginning-of-line)
(insert (format "\n<div uk-lightbox=\"animation: slide\">
<a href=\"%s\">\n" (car kill-ring)))
(indent-for-tab-command)
(forward-line)
(insert (format "</a>\n</div>"))
)
nil
)
)
Additionally I wanted to add a class attribute on some tags, so I created this next function:
(defun add-class-to-tag (tag class)
"Add class attribute with the class variable value.
TAG: Tag to modify.
CLASS: Class in string form to add."
; (interactive "sTag:\nsClass:")
(setq text-to-search (format "<%s" tag))
(goto-char (point-min))
(setq does-it-have-class-attribute t)
(cl-loop repeat (how-many text-to-search) do ;; this is like a for loop
(search-forward text-to-search)
(setq x-start (point))
(setq does-it-have-class-attribute (search-forward
"class=\""
(line-end-position)
t ; if fails return nil
))
(if (not does-it-have-class-attribute)
(progn
(insert (format " class=\"%s\"" class))
(setq does-it-have-class-attribute nil)
)
(progn ; else
(search-forward "\"")
(backward-char)
(insert (format " %s" class))
))
)
)
Finally I execute it on a pre final processor of the created html files: (The below function idea was taken from this blog)
(defun org-blog-publish-to-html (plist filename pub-dir)
"Same as `org-html-publish-to-html' but modifies html before finishing."
(let ((file-path (org-html-publish-to-html plist filename pub-dir)))
(with-current-buffer (find-file-noselect file-path)
(wrap-img-tags);; Here I'm executing the first solution
(add-class-to-tag "h2" "uk-heading-bullet")
(add-class-to-tag "section" "uk-card uk-card-body uk-align-center uk-text-justify")
(add-class-to-tag "h1" "uk-h2 uk-panel uk-padding uk-background-secondary uk-light uk-margin-left uk-margin-right")
(save-buffer)
(kill-buffer))
file-path))
And that's it! It works :)
Additionally I would modify the wrap-img-tags function to wrap any kind of tags with other desired tags!
PD: If this answer was helpful to you, please up vote. I spent around three days researching and testing to reach to this solution. Thank you!