6

I have some legal text that is peppered with digressions and interpolations in parentheses, so many that it is hard to keep track of the main text.

Pasting the text into emacs at least allows me to match parentheses easily, but it occurs to me that it would be handy to be able to hide all text in parentheses. I don't want to delete the text, because then I would have to replace it all at the end.

Here's an example of the desired output.

Before:

The doctor (who was a friend of mine) had graduated from John Hopkins (a well-known school) in 2003 (and as a result of his time there was something of an expert on Baltimore) before moving to Ireland (his grandmother was Irish) in 2008.

After: The doctor had graduated from John Hopkins in 2003 before moving to Ireland in 2008.

Can emacs be made do this without a ton of elisp? I note a number of other questions related to folding, but they seem to be line-oriented (hiding functions in code, or sections in LaTeX etc.) rather than word-oriented.

SlowLearner
  • 245
  • 2
  • 6
  • 1
    What do you want to have happen when Emacs searches for a closing parentheses and finds an opening parentheses instead, or when Emacs finds a second opening parentheses before it finds a closing parentheses? Think of Emacs starting at the top of the buffer -- searching first for an opening parenthesis (recording its position) and then searching for a closing parentheses (recording its position), and then placing an `invisible` text property or overlay between those two positions; then repeat. You will undoubtedly find some cases of broken/mismatched parentheses, or nested parenthesis. – lawlist Nov 16 '16 at 22:54
  • 1
    @lawlist all you need to do is to use `forward-sexp`, if you were looking at a parenthesis before invoking `forward-sexp`, then you may be sure you'll end up with either closing parenthesis, or you'll get "unbalanced parenthesis" error, in which case you can skip a character forward and try again. – wvxvw Nov 16 '16 at 23:17
  • @SlowLearner: I don't think it exists out of the box, but it wouldn't require a ton of lisp code either. Using `foward-sexp` in conjunction with `hs-make-overlay` with invisible property would get you basic functionality in less than a dozen of lines. – wvxvw Nov 16 '16 at 23:27

1 Answers1

3

A quick answer. If I get time I'll try to add a bit more later.

  1. Download isearch-prop.el, and load it.

  2. Use this command to make (...) invisible:

    (defun hide/show-parenthetical-text (&optional show)
      "Remove parentheses and text between them.
    With a prefix arg, show all invisible text."
      (interactive "P")
      (if show
          (isearchp-make-zones-visible `((,(point-min) ,(point-max))))
        (let ((isearchp-dim-outside-search-area-flag  nil))
          (isearchp-regexp-define-contexts (point-min) (point-max) 'invisible "([^)]*)"))))
Drew
  • 75,699
  • 9
  • 109
  • 225
  • Instead of downloading and hand installing `isearch-prop` you can also use the package manager: `M-x install-package isearch-prop` – erikstokes Nov 17 '16 at 01:28
  • @erikstokes: Sure. And there is no doubt a simpler bit of code to do what is requested. But this was ready-to-hand, so quick to offer. – Drew Nov 17 '16 at 02:37
  • Thank you for a prompt and potentially very useful response. This magically hides the text, leaving spaces where the hidden text is. However, it does not seem to want to show it again - once hidden, calling the function has no effect. Is there something obvious I should check to make sure that it's not just me that's the problem? – SlowLearner Nov 17 '16 at 08:16
  • Use `C-u` with command `foo` to **show** again what was made invisible. (It shows everything that might be invisible, however it was made invisible.) And it doesn't/shouldn't show spaces where the hidden text is. It just hides that text (no spaces). Try it in the Emacs manual (`C-h r`), for example. – Drew Nov 17 '16 at 16:13