atomontage / xterm-color

ANSI & xterm-256 color text property translator for Emacs
BSD 2-Clause "Simplified" License
218 stars 20 forks source link

Support org-babel #40

Open NightMachinery opened 3 years ago

NightMachinery commented 3 years ago

image

I have this function which applies the text properties correctly to the result blocks:

  (defun night/babel-ansi ()
    (when-let ((beg (org-babel-where-is-src-block-result nil nil)))
      (save-excursion
        (goto-char beg)
        (when (looking-at org-babel-result-regexp)
          (let* (
                 (end (org-babel-result-end))
                 (colored (xterm-color-filter (delete-and-extract-region beg end)))
                 )
            (insert colored))))))
  (add-hook 'org-babel-after-execute-hook 'night/babel-ansi)

But because they are wrapped in example blocks, the colors are stripped. This 'bug' does not exist if I use ansi-color:

  (defun night/babel-ansi1 ()
    (when-let ((beg (org-babel-where-is-src-block-result nil nil)))
      (save-excursion
        (goto-char beg)
        (when (looking-at org-babel-result-regexp)
          (let ((end (org-babel-result-end))
                (ansi-color-context-region nil))
            (ansi-color-apply-on-region beg end))))))

image

But ansi-color does not support true colors. Any ideas? Thanks!

NightMachinery commented 3 years ago

image

Using :wrap results seems to work, though I'm not sure if this will not have consequences elsewhere.

NightMachinery commented 3 years ago

One problem with :wrap results is that the the inserted content is not quoted for org-mode, and this can cause re-evals of the block to keep inserting new result blocks.

NightMachinery commented 3 years ago

I hacked together a solution which uses normal :wrap example to use org's builtin quoting, and then replaces the block with results:

(defun night/babel-ansi2 ()
    (interactive)
    (when-let ((beg (org-babel-where-is-src-block-result nil nil)))
      (save-excursion
        (goto-char beg)
        (when (looking-at org-babel-result-regexp)
          (let* (
                 (end (org-babel-result-end)))

            ;; (z ectty (delete-and-extract-region (+ beg 7)
            ;;                                     (+ beg 14)))

            (when (search-forward "#+begin_example" nil t)
              (replace-match "#+begin_results" nil t))
            (while (search-forward "#+end_example" nil t))
            (replace-match "#+end_results" nil t)
            ;; (replace-string "#+end_example" "#+end_results" t beg end)

            (let* ((colored (xterm-color-filter (delete-and-extract-region beg end))))
              (goto-char beg)
              (insert colored)))))))

Seems to work well: image image

NightMachinery commented 3 years ago

Update: You might prefer to escape the output manually with ... | command sd '^(\s*(?:\x1b\[33m)?)(\*|#)' '$1,$2', as the default escaping does not handle colored headings etc.