Xah Lee, 2010-12-26, 2011-02-20, 2011-02-21
This pages shows you how to write a emacs lisp command that does multi-pair find & replace on current buffer, and also print a report in another buffer of the replacements done.
This is convenient because you can do find & replace in one-shot and don't have to manually go thru interactive find & replace for each occurrence, but lets you have a glace on possible errors from the report.
In my writings, i use angle brackets for book titles and article titles. For example:
• 〈The Rise of “Worse is Better”〉 (1991) … • 《The Unix-Hater's Handbook》 (1994) …
The double angle bracket is for book titles, the single is for article titles. (See: Intro to Chinese Punctuation with Computer Language Syntax Perspectives.)
When a page is a book list, i'd prefer the book names to be colored so it is more readable. So, i want a html tag like this:
• <span class="atlt">The Rise of “Worse is Better”</span> (1991) … • <span class="bktl">The Unix-Hater's Handbook</span> (1994) …
With proper CSS, the titles will be colored, and the brackets also added. Here's what it looks like:
The CSS code is this:
span.bktl, span.atlt {color:#006400} span.bktl:before{content:"《";color:black} span.bktl:after{content:"》";color:black} span.atlt:before{content:"〈";color:black} span.atlt:after{content:"〉";color:black}
(See: HTML/CSS Tutorial.)
It is very tedious to replace each angle bracket to the html tag version, even using Emacs Keyboard Macro feature. I'd like to have the changes done by just pressing a button.
Here's a solution. I was surprised, that it actually only took me about 15 min to write it.
(defun title-bracket-to-html-tag () "Replace all 《…》 to <span class=\"bktl\">…</span> in current buffer. Also, replace 〈…〉 to <span class=\"atlt\">…</span>. The bracket 《》 is used for book titles. The bracket 〈〉 is used for other titles (article, film, music…). Generate a report of the replaced strings in a separate buffer." (interactive) (let (changedItems) (setq case-replace nil ) ;; changedItems is a list of changed strings, to be printed at the end (setq changedItems '()) (save-excursion (goto-char (point-min)) (while (search-forward-regexp "《\\([^》]+?\\)》" nil t) (setq changedItems (cons (match-string 1) changedItems ) ) (replace-match "<span class=\"bktl\">\\1</span>" t) ) (goto-char (point-min)) (while (search-forward-regexp "〈\\([^〉]+?\\)〉" nil t) (setq changedItems (cons (match-string 1) changedItems ) ) (replace-match "<span class=\"atlt\">\\1</span>" t) ) ) (with-output-to-temp-buffer "*changed items*" (mapcar (lambda (myTitle) (princ myTitle) (princ "\n") ) changedItems) ) ))
The code is not that complex. If you know Emacs Lisp Basics, then you can understand it.
You can try the code. Put the following content in a buffer:
• 〈Defective C++〉 (2007), by Yossi Kreinin. @ yosefk.com. • 《The Unix-Hater's handbook》 (1994), by Simson Garfinkel, Daniel Weise, Steven Strassmann, and Don Hopkins. The entire book is available at mit.edu. (ℤ local copy) • 〈The Rise of “Worse is Better”〉 (1991), by Richard P Gabriel. @ dreamsongs.com Richard Gabrielw is a well known figure in lisp community, the starter of what's now known as XEmacs. He's the recipient of ACM's 1998 Fellows Award and the 2004 Allen Newell Award. 〈The Rise of “Worse is Better”〉 is probably the first article that analyzed the strategy of software success from a evolutionary biology perspective. • 〈Extreme Programming Explained〉 (2008), by Yossi Kreinin. @ yosefk.com • 〈Java: Slow, ugly and irrelevant〉 (2001-01-08), by Simson Garfinkel. @ salon.com (ℤ local copy) • 〈Optimization: Your Worst Enemy〉, (1999), by Joseph M Newcomer. @ flounder.com (ℤ local copy) • 〈Will it rot my students' brains if they use Mathematica?〉 (2002-05), by Theodore W Gray. @ theodoregray.com (ℤ local copy) Theodore is the author of Mathematica frontend. The article discusses educational math software, video games, and violence. • 〈Go To Statement Considered Harmful〉 (1968), by Edsger W Dijkstra. Source; (ℤ local copy) • 〈Skin Cancer〉 (2000), by Greg Knauss. @ suck.com. (ℤ Local copy) A satire on Netscape browser and the “Skin” phenomenon. • 〈Censorzilla〉 (2004), by Jamie Zawinski. @ jwz.org (ℤ local copy) Jamie is a notorious programer of xemacs and Netscape web browser, has written a webpage that contains codes from Netscape browser before its Open Source release. Note the profanity laiden comments and what they say. It gives a indication of the pain and fucked-up-ness of computing industry. • 〈Let's Make Unix Not Suck〉 (1999), by Miguel De Icaza. @ primates.ximian.com Miguel de Icazaw is the man behind Linux's Gnome project and Mono project. This article is written in the era when unixes do not really have a desktop or any concept of coherent development framework. It was controversial. • 《Code Complete: A Practical Handbook of Software Construction》, by Steve C McConnell amazon. Throw away all your Design Patterns or eXtreme Programming books. If you want a scientific book on software development analysis, read this book instead. Steve McConnellw. «a author of many software engineering textbooks including Code Complete, Rapid Development, and Software Estimation. In 1998, McConnell was named as one of the three most influential people in the software industry by Software Development Magazine, along with Bill Gates and Linus Torvalds.»
Then call “title-bracket-to-html-tag”. It will generate a output on a separate pane showing you all the changed items. Here's the output:
Let's Make Unix Not Suck Censorzilla Skin Cancer Go To Statement Considered Harmful Will it rot my students' brains if they use Mathematica? Optimization: Your Worst Enemy Java: Slow, ugly and irrelevant Extreme Programming Explained The Rise of “Worse is Better” The Rise of “Worse is Better” Defective C++ Code Complete: A Practical Handbook of Software Construction The Unix-Hater's handbook
Showing the changed items is important, because your text may have a mis-matched bracket. You can have a quick glance in the output and see if something is incorrect. This is also why keyboard macros isn't a good solution here.
Here's a short explanation of the code.
All the functions in this code are very basic and is frequently used for text processing jobs. You can just use this function as a template to write your own.
(The book list above is from: The Tech Geekers & Software Engineering.)
Emacs is beautiful!
I quote Wikipedia often. Often, in a quote there are many citation marks like this: [1], [12], …. They don't make sense when quoting it. So, i have a command to remove them.
(defun remove-square-brackets () "Delete any text of the form “[…]”, including the brackets. Work on text selection or current line. Print out in *changed items* buffer of all removed text. For example, if text is on the line: the project was officially announced as Blu-ray Disc [11][12], and … then, after the call the line becomes: the project was officially announced as Blu-ray Disc, and … ." (interactive) (let (bdr p1 p2 inputStr resultStr changedItems) (setq bdr (get-selection-or-unit 'line) ) (setq inputStr (elt bdr 0) p1 (elt bdr 1) p2 (elt bdr 2) ) (setq changedItems '()) (setq resultStr (with-temp-buffer (insert inputStr) (goto-char 1) (while (search-forward-regexp "\\(\\[[0-9]+?\\]\\)" nil t) (setq changedItems (cons (match-string 1) changedItems ) ) (replace-match "" t) ) (buffer-string)) ) (delete-region p1 p2) (insert resultStr) (with-output-to-temp-buffer "*changed items*" (mapcar (lambda (myTitle) (princ myTitle) (princ "\n") ) changedItems) ) ) )
In the above, i used a convenient custom function “get-selection-or-unit 'line”. You don't have to use that. See: Emacs Lisp: Using thing-at-point.
For about 10 examples of using multi-pair find & replace, See: Emacs Lisp Multi-Pair Find & Replace Applications.