6

Sometimes I want parts of the text within an org buffer to be 'masked' by default. The reason is that I may want to look at that file with someone looking over my shoulder, where they should be able to see most of what's there, but some information I'd rather they not, a name for example.

One way I've discovered to do this is to use a faux link. So this:

On Jan. 30, Mary Smith contacted me with concerns about the project's budget.

is entered as this:

On Jan. 30, [[Mary Smith][**********]] contacted me with concerns about the project's budget.

and displays like this:

On Jan. 30, ********** contacted me with concerns about the project's budget.

There's an added benefit that hovering over the 'link' shows the hidden text. It's a little kludgy, but it meets my needs. Obviously isn't for information that requires a high degree of security, and that's not what I'm after.

My question is whether there is maybe a better way to go about this. A better solution should make it easy to format text so that it's hidden AND to access the original, hidden text.

Dave Braze
  • 161
  • 4
  • Welcome to Emacs.SE! We generally try to stick to one discrete question per post, so I removed your second question. Let me suggest that you ask it in a separate post, but probably wait until you get an answer to this one. – Dan Feb 23 '17 at 16:04
  • Interesting use case. Are there specific problems you have with your current solution? You could write a command to match certain strings or patterns and hide them with an overlay, but that is pretty much what org-mode is doing with your current work-around. – glucas Feb 23 '17 at 18:59
  • This does bring up a need for a comprehensive solution for masking based on symbols, tree structure, and other customizable conditions. Much like the narrowing and widening solution, it may have to be a solution broader than just hiding agenda entries. For example, hiding table entries, hiding contacts, hiding dates, etc. Thanks for asking. – Emacs User Feb 23 '17 at 19:41
  • @glucas no real problems with it other than, maybe that it does not scale very well. A related case for me, is the need to mask all cells in a specific column of a table, as hinted by Emacs User. Certainly, I could apply my present solution on a cell-wise basis, but it would be nice to be able to mask and unmask an entire column quickly and easily. For the inline text case, the solution you propose below, using highlight-regexp, but I think a bit more unwieldy than what I'm doing now. I was thinking more on the lines of *text* /markup/ syntax. But maybe I've already got the optimal solution. – Dave Braze Feb 23 '17 at 20:37
  • Another option: Maybe you can hijack one of the existing org markup characters, e.g. +strike-through+ to instead mask, by customizing `org-emphasis-alist`. That don't give you an easy way to turn the masking on and off, though. – glucas Feb 23 '17 at 20:59
  • I don't have time today to look into how `org-toggle-link-display` works, but you could modify that functionality (or create a new function and whatever else) to hide/reveal a portion or all of the link components. – lawlist Feb 24 '17 at 02:22

3 Answers3

3

Another quick workaround might be to use highlight-regexp with a face that masks the text.

For example, define a new face that is just black on black:

(defface mask '((t (:background "black" :foreground "black"))) nil)

Then in any buffer you can use M-s h r or M-s h p (highlight-regexp or highlight-phrase) to match some text and "highlight" with the mask face. You can remove the mask with M-s h u, unhighlight-regexp.

Update

As @db48x suggested in the comments, you can define your own markup syntax and a corresponding regexp. For example, maybe you want to use %%this should be masked%% and a regexp to highlight text surrounded by %% delimiters.

One caveat with this approach, though: other kinds of highlighting might reveal the masked text. For example if you mark the region or turn on hl-line-mode you might inadvertently reveal something.

glucas
  • 20,175
  • 1
  • 51
  • 83
  • Thank you. This is an interesting possibility, but for my use-case it may be difficult to write a simple regexp to catch all strings in a buffer that I'd want masked. – Dave Braze Feb 23 '17 at 20:41
  • 1
    Take a look in the Emacs manual for the Interactive Highlighting section. You don't need to write one regexp to match everything, you just call the highlight commands multiple times to highlight / unhighlight different patterns. There is also support for saving the set of highlight expressions in to the file and re-applying them the next time you visit the file. – glucas Feb 23 '17 at 20:43
  • Ok. I'll check. – Dave Braze Feb 23 '17 at 20:46
  • 1
    Or you could arrange for the information you want to redact to be surrounded by a unique syntax, so that you could write a simple regexp to match it. – db48x Feb 24 '17 at 00:49
2

Put such text in drawers - which have very similar functionality. They are not hidden because of the fear from shoulder surfers, but they are considered to be unsightly, under the covers stuff so nearly always hidden. Drawers seem more idiomatic in org-mode.

See https://www.gnu.org/software/emacs/manual/html_node/org/Drawers.html

You could then define a column mode to display such properties, or just press TAB on the drawer to expand it.

Jeeves
  • 611
  • 4
  • 5
0

In the end, I'm going to stick with my original solution of using faux links to mask text. It's pretty simple and it does serve my needs.

Thanks everyone for your help and creative thinking on the subject.

Dave Braze
  • 161
  • 4