From: Felix Dietrich <felix.dietrich@sperrhaken.name>
To: Samuel Wales <samologist@gmail.com>
Cc: help-gnu-emacs@gnu.org
Subject: Re: buffer substring of only visible text
Date: Wed, 21 Sep 2022 13:34:24 +0200 [thread overview]
Message-ID: <8735clm05b.fsf@sperrhaken.name> (raw)
In-Reply-To: <CAJcAo8t_+GAgS-jyv=yd=-VFVYJJ5cwqrDvkJtMNOba2t+OU_g@mail.gmail.com> (Samuel Wales's message of "Tue, 20 Sep 2022 18:08:03 -0700")
Hello Samuel,
Samuel Wales <samologist@gmail.com> writes:
> i want to copy visible text from a region in a buffer, into a string.
> if any invisible regions are in the region, i want them to not be in
> the string. that is, i want the visible intervals in the copied
> region to be merely appended. when i INSERT the resulting string into
> the new buffer, i want any text properties that i specify to still
> exist. htmlize.el has a function, buffer-substring-no-invisible,
> which does not include any text properties at all. it works, but i'd
> like to include at least one text property, which i want to specify.
>
> i am looking for a know a cookbook formula to do this really
> straightforwardly.
I do not know any cookbook solution for this problem, but you have
already found a (fairly short and straightforward) function that almost
does what you described; with a few minor modifications you should be
able to get what you want (almost untested):
#+begin_src emacs-lisp
(defun my/buffer-substring-with-properties (start end props)
;; Copy the specified property from the specified region of the
;; buffer to the target string. We cannot rely on Emacs to copy the
;; property because we want to handle properties coming from both
;; text properties and overlays.
(let ((text (buffer-substring-no-properties start end)))
(dolist (p props)
(htmlize-copy-prop p start end text))
text))
(defun my/buffer-substring-no-invisible (beg end &optional props)
;; Like buffer-substring-no-properties, but don't copy invisible
;; parts of the region. Where buffer-substring-no-properties
;; mandates an ellipsis to be shown, htmlize-ellipsis is inserted.
(let ((pos beg)
visible-list invisible show last-show next-change)
;; Iterate over the changes in the `invisible' property and filter
;; out the portions where it's non-nil, i.e. where the text is
;; invisible.
(while (< pos end)
(setq invisible (get-char-property pos 'invisible)
next-change (htmlize-next-change pos 'invisible end)
show (htmlize-decode-invisibility-spec invisible))
(cond ((eq show t)
(push (my/buffer-substring-with-properties pos next-change
props)
visible-list))
((and (eq show 'ellipsis)
(not (eq last-show 'ellipsis))
;; Conflate successive ellipses.
(push htmlize-ellipsis visible-list))))
(setq pos next-change last-show show))
(htmlize-concat (nreverse visible-list))))
#+end_src
The function ‘my/buffer-substring-no-invisible’ only adds an additional
parameter PROPS to ‘htmlize-buffer-substring-no-invisible’ and replaces
the call to ‘htmlize-get-text-with-display’ with a call to
‘my/buffer-substring-with-properties’ that takes the PROPS parameter to
copy not only the two fixed properties ‘display’ and ‘htmlize-link’, as
does ‘htmlize-get-text-with-display’, but allow specifying the desired
properties to copy when calling the function.
Text that has the ‘invisible’ property may be replaced with an ellipsis
(depending on ‘buffer-invisibility-spec’). If you preferred there
rather be no ellipsis, adjust the cond-form or bind ‘htmlize-ellipsis’
to the empty string "".
As the comment at the top of ‘htmlize-copy-prop’ suggests, Emacs may
provide more efficient means to copy text properties if you do not need
the overlay properties. I cannot help you with the details of that,
though, but maybe the sections on text and overlay properties in the
Emacs Lisp handbook can provide you with the necessary clues [1][2].
Footnotes:
[1] (info "(elisp) Text Properties")
<https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Properties.html>
[2] (info "(elisp) Overlay Properties")
<https://www.gnu.org/software/emacs/manual/html_node/elisp/Overlay-Properties.html>
--
Felix Dietrich
next prev parent reply other threads:[~2022-09-21 11:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-21 1:08 buffer substring of only visible text Samuel Wales
2022-09-21 1:34 ` Emanuel Berg
2022-09-21 11:34 ` Felix Dietrich [this message]
2022-09-21 22:57 ` Samuel Wales
2022-09-28 17:59 ` Felix Dietrich
2022-09-22 9:14 ` Michael Heerdegen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8735clm05b.fsf@sperrhaken.name \
--to=felix.dietrich@sperrhaken.name \
--cc=help-gnu-emacs@gnu.org \
--cc=samologist@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).