<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>sacha chua :: enterprise 2.0 consultant, storyteller, geek &#187; code</title>
	<atom:link href="http://sachachua.com/wp/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://sachachua.com/wp</link>
	<description>I help people connect through blogs, wikis, other Web 2.0 tools. I'm also writing a book about Emacs.</description>
	<pubDate>Thu, 21 Aug 2008 04:07:41 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>Emacs BBDB magic: Greeting people with nicknames</title>
		<link>http://sachachua.com/wp/2006/07/20/emacs-bbdb-magic-greeting-people-with-nicknames/</link>
		<comments>http://sachachua.com/wp/2006/07/20/emacs-bbdb-magic-greeting-people-with-nicknames/#comments</comments>
		<pubDate>Thu, 20 Jul 2006 17:06:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[elisp]]></category>

		<category><![CDATA[emacs]]></category>

		<category><![CDATA[gnus]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2006.07.20.php#anchor-1</guid>
		<description><![CDATA[<p>I use Gnus to read my mail within the Emacs text editor. One of the
advantages of using a mail client that's infinitely programmable is
that you can add all sorts of little tweaks to it. Gnus can be
integrated with Emacs' Big Brother Database (BBDB), a semi-structured
text database in which I store all sorts of weird notes. This little
hack takes the nick field of the database and automatically inserts a
greeting. If someone signs himself as Mikong, I should call him that
instead of Joseph Michael. Similarly, I sign my messages as Sacha, not
Sandra Jean. This little tidbit makes it easier to remember to call
people by their nicknames.</p>

<pre class="example">
(defun sacha/gnus-add-nick-to-message ()
  "Inserts \"Hello, NICK!\" in messages based on the recipient's nick field."
  (interactive)
  (save-excursion
    (let ((bbdb-get-addresses-headers (list (assoc 'recipients bbdb-get-addresses-headers)))
          nicks)
      (setq nicks
            (delq nil
                  (mapcar (lambda (rec) (bbdb-record-getprop rec 'nick))
                          (bbdb-update-records
                           (bbdb-get-addresses nil gnus-ignored-from-addresses 'gnus-fetch-field)
                           nil
                           nil))))
      (goto-char (point-min))
      (when (and nicks
                 (re-search-forward "--text follows this line--" nil t))
        (forward-line 1)
        (insert "Hello, "
                (mapconcat 'identity nicks ", ")
                "!\n\n")))))

(defadvice gnus-post-news (after sacha activate)
  (sacha/gnus-add-nick-to-message))
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/gnus" rel="tag">gnus</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a>, <a href="http://www.technorati.com/tag/elisp" rel="tag">elisp</a></p>

<p>Random Japanese sentence: ÃƒÂ¨Ã‚Â™Ã‚ÂŽÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¥Ã‚Â¤Ã‚Â§ÃƒÂ£Ã‚ÂÃ‚ÂÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ§Ã‚ÂŒÃ‚Â«ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â†ÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ£Ã‚Â‚Ã‚Â‰ÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ¥Ã‚ÂÃ‚ÂŒÃƒÂ£Ã‚ÂÃ‚Â˜ÃƒÂ£Ã‚Â‚Ã‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â†ÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ§Ã‚ÂŒÃ‚Â«ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¥Ã‚Â°Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â•ÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ¨Ã‚Â™Ã‚ÂŽÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚Â‚Ã‚Â‚ÃƒÂ£Ã‚Â‚Ã‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â€Ã‚Â‚	You may as well call a cat a small tiger as call a tiger a big cat.</p>
]]></description>
			<content:encoded><![CDATA[<p>I use Gnus to read my mail within the Emacs text editor. One of the
advantages of using a mail client that's infinitely programmable is
that you can add all sorts of little tweaks to it. Gnus can be
integrated with Emacs' Big Brother Database (BBDB), a semi-structured
text database in which I store all sorts of weird notes. This little
hack takes the nick field of the database and automatically inserts a
greeting. If someone signs himself as Mikong, I should call him that
instead of Joseph Michael. Similarly, I sign my messages as Sacha, not
Sandra Jean. This little tidbit makes it easier to remember to call
people by their nicknames.</p>

<pre class="example">
(defun sacha/gnus-add-nick-to-message ()
  "Inserts \"Hello, NICK!\" in messages based on the recipient's nick field."
  (interactive)
  (save-excursion
    (let ((bbdb-get-addresses-headers (list (assoc 'recipients bbdb-get-addresses-headers)))
          nicks)
      (setq nicks
            (delq nil
                  (mapcar (lambda (rec) (bbdb-record-getprop rec 'nick))
                          (bbdb-update-records
                           (bbdb-get-addresses nil gnus-ignored-from-addresses 'gnus-fetch-field)
                           nil
                           nil))))
      (goto-char (point-min))
      (when (and nicks
                 (re-search-forward "--text follows this line--" nil t))
        (forward-line 1)
        (insert "Hello, "
                (mapconcat 'identity nicks ", ")
                "!\n\n")))))

(defadvice gnus-post-news (after sacha activate)
  (sacha/gnus-add-nick-to-message))
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/gnus" rel="tag">gnus</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a>, <a href="http://www.technorati.com/tag/elisp" rel="tag">elisp</a></p>

<p>Random Japanese sentence: ÃƒÂ¨Ã‚Â™Ã‚ÂŽÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¥Ã‚Â¤Ã‚Â§ÃƒÂ£Ã‚ÂÃ‚ÂÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ§Ã‚ÂŒÃ‚Â«ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â†ÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ£Ã‚Â‚Ã‚Â‰ÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ¥Ã‚ÂÃ‚ÂŒÃƒÂ£Ã‚ÂÃ‚Â˜ÃƒÂ£Ã‚Â‚Ã‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â†ÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ§Ã‚ÂŒÃ‚Â«ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¥Ã‚Â°Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â•ÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ¨Ã‚Â™Ã‚ÂŽÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚Â‚Ã‚Â‚ÃƒÂ£Ã‚Â‚Ã‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â€Ã‚Â‚	You may as well call a cat a small tiger as call a tiger a big cat.</p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2006/07/20/emacs-bbdb-magic-greeting-people-with-nicknames/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Year in Bookmarks</title>
		<link>http://sachachua.com/wp/2005/12/16/the-year-in-bookmarks/</link>
		<comments>http://sachachua.com/wp/2005/12/16/the-year-in-bookmarks/#comments</comments>
		<pubDate>Fri, 16 Dec 2005 22:37:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[del.icio.us]]></category>

		<category><![CDATA[emacs]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.12.16.php#anchor-1</guid>
		<description><![CDATA[<table class="muse-table" border="2" cellpadding="5">
  <tbody>
    <tr>
      <td>Top 10 tags for 2005</td>
      <td><a href="http://del.icio.us/sachac/productivity">productivity</a>(104) <a href="http://del.icio.us/sachac/web2.0">web2.0</a>(88) <a href="http://del.icio.us/sachac/digitalpinay">digitalpinay</a>(88) <a href="http://del.icio.us/sachac/social">social</a>(84) <a href="http://del.icio.us/sachac/useful">useful</a>(83) <a href="http://del.icio.us/sachac/business">business</a>(80) <a href="http://del.icio.us/sachac/blogs">blogs</a>(70) <a href="http://del.icio.us/sachac/research">research</a>(69) <a href="http://del.icio.us/sachac/lifehacks">lifehacks</a>(68) <a href="http://del.icio.us/sachac/blogging">blogging</a>(60)</td>
    </tr>
  </tbody>
</table>

<p>Check out <a href="http://sacha.free.net.ph/notebook/wiki/2005.12.16.php">my year in bookmarks</a> for more detail. =) If you want me to analyze yours, just save <a href="http://del.icio.us/api/posts/all">http://del.icio.us/api/posts/all</a> to all.xml and run this Ruby script. You can also e-mail me (<a href="mailto:sacha@plannerlove.com">sacha@plannerlove.com</a>) your all.xml if you don't want to go through the hassle yourself.</p>

<p>Much fun!</p>

<pre class="example">
#!/usr/bin/ruby

require 'rexml/document'
require 'date'

include REXML

YEAR = 2005
USER = "sachac"
doc = Document::new(File::new('all.xml'))

month_hash = {}
month_total = {}
tag_total = {}
doc.elements[1].elements.each {
  &#124;x&#124;
  date = DateTime::parse(x.attributes['time'])
  if (date.year == YEAR)
    x.attributes['tag'].split(' ').each {
      &#124;tag&#124;
      month_hash[date.month] &#124;&#124;= {}
      month_hash[date.month][tag] &#124;&#124;= 0
      month_hash[date.month][tag] += 1
      tag_total[tag] &#124;&#124;= 0
      tag_total[tag] += 1
    }
    month_total[date.month] &#124;&#124;= 0
    month_total[date.month] += 1
  end
}

s = "Top 10 tags for " + YEAR.to_s + " &#124;"
tag_total.sort_by { &#124;tag,total&#124; -total }.slice(0, 10).each { &#124;tag,total&#124;
  s += ' <a href="http://del.icio.us/' + USER + '/' + tag + "\">" + tag + "</a>(" + total.to_s + ")"
}
puts s

month_hash.sort.each { &#124;month,tags&#124;
  s = Date::MONTHNAMES[month] + "<br/>(" + month_total[month].to_s + " bookmarks) &#124;"
  tags.sort_by { &#124;tag,total&#124; -total }.each {
    &#124;tag,total&#124;
    s += ' <a href="http://del.icio.us/' + USER + '/' + tag + "\">" + tag + "</a>(" + total.to_s + ")"
  }
  puts s
}
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/ruby" rel="tag">ruby</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a>, <a href="http://www.technorati.com/tag/del.icio.us" rel="tag">del.icio.us</a></p>
]]></description>
			<content:encoded><![CDATA[<table class="muse-table" border="2" cellpadding="5">
  <tbody>
    <tr>
      <td>Top 10 tags for 2005</td>
      <td><a href="http://del.icio.us/sachac/productivity">productivity</a>(104) <a href="http://del.icio.us/sachac/web2.0">web2.0</a>(88) <a href="http://del.icio.us/sachac/digitalpinay">digitalpinay</a>(88) <a href="http://del.icio.us/sachac/social">social</a>(84) <a href="http://del.icio.us/sachac/useful">useful</a>(83) <a href="http://del.icio.us/sachac/business">business</a>(80) <a href="http://del.icio.us/sachac/blogs">blogs</a>(70) <a href="http://del.icio.us/sachac/research">research</a>(69) <a href="http://del.icio.us/sachac/lifehacks">lifehacks</a>(68) <a href="http://del.icio.us/sachac/blogging">blogging</a>(60)</td>
    </tr>
  </tbody>
</table>

<p>Check out <a href="http://sacha.free.net.ph/notebook/wiki/2005.12.16.php">my year in bookmarks</a> for more detail. =) If you want me to analyze yours, just save <a href="http://del.icio.us/api/posts/all">http://del.icio.us/api/posts/all</a> to all.xml and run this Ruby script. You can also e-mail me (<a href="mailto:sacha@plannerlove.com">sacha@plannerlove.com</a>) your all.xml if you don't want to go through the hassle yourself.</p>

<p>Much fun!</p>

<pre class="example">
#!/usr/bin/ruby

require 'rexml/document'
require 'date'

include REXML

YEAR = 2005
USER = "sachac"
doc = Document::new(File::new('all.xml'))

month_hash = {}
month_total = {}
tag_total = {}
doc.elements[1].elements.each {
  |x|
  date = DateTime::parse(x.attributes['time'])
  if (date.year == YEAR)
    x.attributes['tag'].split(' ').each {
      |tag|
      month_hash[date.month] ||= {}
      month_hash[date.month][tag] ||= 0
      month_hash[date.month][tag] += 1
      tag_total[tag] ||= 0
      tag_total[tag] += 1
    }
    month_total[date.month] ||= 0
    month_total[date.month] += 1
  end
}

s = "Top 10 tags for " + YEAR.to_s + " |"
tag_total.sort_by { |tag,total| -total }.slice(0, 10).each { |tag,total|
  s += ' <a href="http://del.icio.us/' + USER + '/' + tag + "\">" + tag + "</a>(" + total.to_s + ")"
}
puts s

month_hash.sort.each { |month,tags|
  s = Date::MONTHNAMES[month] + "<br/>(" + month_total[month].to_s + " bookmarks) |"
  tags.sort_by { |tag,total| -total }.each {
    |tag,total|
    s += ' <a href="http://del.icio.us/' + USER + '/' + tag + "\">" + tag + "</a>(" + total.to_s + ")"
  }
  puts s
}
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/ruby" rel="tag">ruby</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a>, <a href="http://www.technorati.com/tag/del.icio.us" rel="tag">del.icio.us</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/12/16/the-year-in-bookmarks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby: Turn bash.org quotes into a fortune file</title>
		<link>http://sachachua.com/wp/2005/12/08/ruby-turn-bashorg-quotes-into-a-fortune-file/</link>
		<comments>http://sachachua.com/wp/2005/12/08/ruby-turn-bashorg-quotes-into-a-fortune-file/#comments</comments>
		<pubDate>Thu, 08 Dec 2005 23:27:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.12.08.php#anchor-6</guid>
		<description><![CDATA[<p>The following code turns XML quotes from bash.org (a popular IRC quotes server) into a fortune-cookie file.
Handy for using with <a href="http://sachachua.com/notebook/emacs/flashcard.el">../emacs/flashcard.el</a> and my <a href="http://sachachua.com/notebook/emacs/flashcard-config.el">../emacs/flashcard-config.el</a>, which pops up a fortune
every time I get a correct answer.</p>

<p>bash-org-to-fortune.rb:</p>

<pre class="example">
require 'rss/1.0'
require 'cgi'
require 'net/http'
host = Net::HTTP.new('bash.org', 80)
if ARGV[0] then
   resp, data = host.get('http://bash.org/xml/?top&#038;below=' + ARGV[0], nil)
else
   resp, data = host.get('http://bash.org/xml/?top', nil)
end
parsed = RSS::Parser.parse(data, false)
parsed.items.each { &#124;x&#124; puts CGI::unescapeHTML(x.description.gsub('<br />', "\n")); puts "%\n" }
</pre>

<p>Call like this:</p>

<pre class="example">
ruby bash-org-to-fortune.rb > bash; strfile bash; fortune bash

# or to get the top quotes with score < 1000
ruby bash-org-to-fortune.rb 1000 > bash; strfile bash; fortune bash
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/ruby" rel="tag">ruby</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a>, <a href="http://www.technorati.com/tag/programming" rel="tag">programming</a></p>
]]></description>
			<content:encoded><![CDATA[<p>The following code turns XML quotes from bash.org (a popular IRC quotes server) into a fortune-cookie file.
Handy for using with <a href="http://sachachua.com/notebook/emacs/flashcard.el">../emacs/flashcard.el</a> and my <a href="http://sachachua.com/notebook/emacs/flashcard-config.el">../emacs/flashcard-config.el</a>, which pops up a fortune
every time I get a correct answer.</p>

<p>bash-org-to-fortune.rb:</p>

<pre class="example">
require 'rss/1.0'
require 'cgi'
require 'net/http'
host = Net::HTTP.new('bash.org', 80)
if ARGV[0] then
   resp, data = host.get('http://bash.org/xml/?top&below=' + ARGV[0], nil)
else
   resp, data = host.get('http://bash.org/xml/?top', nil)
end
parsed = RSS::Parser.parse(data, false)
parsed.items.each { |x| puts CGI::unescapeHTML(x.description.gsub('<br />', "\n")); puts "%\n" }
</pre>

<p>Call like this:</p>

<pre class="example">
ruby bash-org-to-fortune.rb > bash; strfile bash; fortune bash

# or to get the top quotes with score < 1000
ruby bash-org-to-fortune.rb 1000 > bash; strfile bash; fortune bash
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/ruby" rel="tag">ruby</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a>, <a href="http://www.technorati.com/tag/programming" rel="tag">programming</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/12/08/ruby-turn-bashorg-quotes-into-a-fortune-file/feed/</wfw:commentRss>
		</item>
		<item>
		<title>semi-form letters: hooray for open source!</title>
		<link>http://sachachua.com/wp/2005/07/10/semi-form-letters-hooray-for-open-source/</link>
		<comments>http://sachachua.com/wp/2005/07/10/semi-form-letters-hooray-for-open-source/#comments</comments>
		<pubDate>Mon, 11 Jul 2005 03:35:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.07.10.php#anchor-3</guid>
		<description><![CDATA[<p>I needed to write 31 thank-you-for-attending-my-send-off-party e-mail
messages. Instead of having a generic letter that I'd send to lots of
people all listed in To: or Bcc:, I decided to personalize it a bit by
including their nicknames, two-year goals, and a personal message I'd
add to each letter in different places.</p>

<p>Fortunately, my mail client was up to the task. One of the benefits of
having both your contact information and your mail client in an
easily-programmable environment is that you can hack together a quick
program to do exactly what you want.</p>

<p>I had typed everyone's two-year-plans into my contact information
manager's Notes field following a special format. It was the work of a
few minutes to record and run a macro that extracted the data and
created a signature for each person who attended my send-off party.</p>

<p>I then wrote a couple of short functions that looped over the
currently displayed contact records and drafted messages for each of
them following a template.</p>

<p>This resulted in 31 drafts I could edit and send without hassles. Much
fun!</p>

<p>For future reference (and for the handful of Emacs geeks or learners
in the audience), here's the code I used to make it all happen:</p>

<pre class="example">
(defun sacha/bbdb-send-form-mail (bbdb-record &#038;optional subject template)
  "Compose a form message to the people indicated by the current BBDB record(s)."
  (interactive (list (if (bbdb-do-all-records-p)
                         (mapcar 'car bbdb-records)
                       (bbdb-current-record))
                     (read-string "Subject: ")
                     (read-string "Template (<NICK>): ")))
  (if (consp bbdb-record)
      (let ((records bbdb-record))
        (while records
          (sacha/bbdb-send-form-mail-1 (car records) subject template)
          (setq records (cdr records))))
    (sacha/bbdb-send-form-mail-1 bbdb-record subject template)))

(defun sacha/bbdb-send-form-mail-1  (bbdb-record &#038;optional subject template)
  "Compose a form message for one person."
    (if bbdb-inside-electric-display
      (bbdb-electric-throw-to-execute
       (list 'sacha/bbdb-send-form-mail bbdb-record subject)))
  ;; else...
  (cond ((null bbdb-record) (error "record unexists"))
        ((null (bbdb-record-net bbdb-record))
         (message "%s record unhas a network addresses." (or (bbdb-record-name bbdb-record) "Unknown")))
        (t (bbdb-send-mail-internal (bbdb-dwim-net-address bbdb-record)
                                    subject (list bbdb-record))
           (goto-char (point-min))
           (when (re-search-forward "--text follows this line--" nil t)
             (forward-line 1)
             (insert template)
             (goto-char (point-min))
             (while (search-forward "<NICK>" nil t)
               (replace-match (or (bbdb-record-getprop bbdb-record 'nick)
                                  (bbdb-record-name bbdb-record))
                              t t))
             (when (bbdb-record-getprop bbdb-record 'signature)
               (goto-char (point-max))
               (insert "\n")
               (let ((p (point)))
                 (insert (bbdb-record-getprop bbdb-record 'signature))
                 (fill-region-as-paragraph p (point))))
             (goto-char (point-min))
             (if (re-search-forward "^Subject: $" nil t) (end-of-line))))))
</pre>

<p>I used M-x local-set-key to bind sacha/bbdb-send-form-mail to M. * M
then applies the function to all displayed records.
<a href="http://sachachua.com/notebook/emacs/miniedit.el">../emacs/miniedit.el</a> makes it easy to edit long strings in the
minibuffer, and that made the template much easier to write.</p>

<p>Emacs totally rocks. Nothing else has ever given me this much power.</p>

<p>ÃƒÂ¨Ã‚Â‡Ã‚ÂªÃƒÂ¥Ã‚Â‹Ã‚Â•ÃƒÂ¨Ã‚Â»Ã‚ÂŠÃƒÂ¨Ã‚Â£Ã‚Â½ÃƒÂ©Ã‚Â€Ã‚Â ÃƒÂ£Ã‚ÂÃ‚Â¯ÃƒÂ¤Ã‚ÂºÃ‚ÂºÃƒÂ©Ã‚Â–Ã‚Â“ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ¥Ã‚ÂŠÃ‚Â´ÃƒÂ¥Ã‚ÂƒÃ‚ÂÃƒÂ¨Ã‚Â€Ã‚Â…ÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ¤Ã‚Â»Ã‚Â£ÃƒÂ£Ã‚Â‚Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â”ÃƒÂ£Ã‚ÂƒÃ‚Â¥ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚Â‚Ã‚Â¿ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚ÂÃ‚ÂŒÃƒÂ§Ã‚ÂµÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â¿ÃƒÂ¨Ã‚Â¾Ã‚Â¼ÃƒÂ£Ã‚ÂÃ‚Â¾ÃƒÂ£Ã‚Â‚Ã‚ÂŒÃƒÂ£Ã‚ÂÃ‚ÂŸÃƒÂ£Ã‚ÂƒÃ‚Â­ÃƒÂ£Ã‚ÂƒÃ‚ÂœÃƒÂ£Ã‚ÂƒÃ‚ÂƒÃƒÂ£Ã‚ÂƒÃ‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ£Ã‚Â‚Ã‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ¨Ã‚Â¡Ã‚ÂŒÃƒÂ£Ã‚Â‚Ã‚ÂÃƒÂ£Ã‚Â‚Ã‚ÂŒÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚Â€Ã‚Â‚	Car manufacturing is carried out by computer-programmed robots in place of human workers.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I needed to write 31 thank-you-for-attending-my-send-off-party e-mail
messages. Instead of having a generic letter that I'd send to lots of
people all listed in To: or Bcc:, I decided to personalize it a bit by
including their nicknames, two-year goals, and a personal message I'd
add to each letter in different places.</p>

<p>Fortunately, my mail client was up to the task. One of the benefits of
having both your contact information and your mail client in an
easily-programmable environment is that you can hack together a quick
program to do exactly what you want.</p>

<p>I had typed everyone's two-year-plans into my contact information
manager's Notes field following a special format. It was the work of a
few minutes to record and run a macro that extracted the data and
created a signature for each person who attended my send-off party.</p>

<p>I then wrote a couple of short functions that looped over the
currently displayed contact records and drafted messages for each of
them following a template.</p>

<p>This resulted in 31 drafts I could edit and send without hassles. Much
fun!</p>

<p>For future reference (and for the handful of Emacs geeks or learners
in the audience), here's the code I used to make it all happen:</p>

<pre class="example">
(defun sacha/bbdb-send-form-mail (bbdb-record &optional subject template)
  "Compose a form message to the people indicated by the current BBDB record(s)."
  (interactive (list (if (bbdb-do-all-records-p)
                         (mapcar 'car bbdb-records)
                       (bbdb-current-record))
                     (read-string "Subject: ")
                     (read-string "Template (<NICK>): ")))
  (if (consp bbdb-record)
      (let ((records bbdb-record))
        (while records
          (sacha/bbdb-send-form-mail-1 (car records) subject template)
          (setq records (cdr records))))
    (sacha/bbdb-send-form-mail-1 bbdb-record subject template)))

(defun sacha/bbdb-send-form-mail-1  (bbdb-record &optional subject template)
  "Compose a form message for one person."
    (if bbdb-inside-electric-display
      (bbdb-electric-throw-to-execute
       (list 'sacha/bbdb-send-form-mail bbdb-record subject)))
  ;; else...
  (cond ((null bbdb-record) (error "record unexists"))
        ((null (bbdb-record-net bbdb-record))
         (message "%s record unhas a network addresses." (or (bbdb-record-name bbdb-record) "Unknown")))
        (t (bbdb-send-mail-internal (bbdb-dwim-net-address bbdb-record)
                                    subject (list bbdb-record))
           (goto-char (point-min))
           (when (re-search-forward "--text follows this line--" nil t)
             (forward-line 1)
             (insert template)
             (goto-char (point-min))
             (while (search-forward "<NICK>" nil t)
               (replace-match (or (bbdb-record-getprop bbdb-record 'nick)
                                  (bbdb-record-name bbdb-record))
                              t t))
             (when (bbdb-record-getprop bbdb-record 'signature)
               (goto-char (point-max))
               (insert "\n")
               (let ((p (point)))
                 (insert (bbdb-record-getprop bbdb-record 'signature))
                 (fill-region-as-paragraph p (point))))
             (goto-char (point-min))
             (if (re-search-forward "^Subject: $" nil t) (end-of-line))))))
</pre>

<p>I used M-x local-set-key to bind sacha/bbdb-send-form-mail to M. * M
then applies the function to all displayed records.
<a href="http://sachachua.com/notebook/emacs/miniedit.el">../emacs/miniedit.el</a> makes it easy to edit long strings in the
minibuffer, and that made the template much easier to write.</p>

<p>Emacs totally rocks. Nothing else has ever given me this much power.</p>

<p>ÃƒÂ¨Ã‚Â‡Ã‚ÂªÃƒÂ¥Ã‚Â‹Ã‚Â•ÃƒÂ¨Ã‚Â»Ã‚ÂŠÃƒÂ¨Ã‚Â£Ã‚Â½ÃƒÂ©Ã‚Â€Ã‚Â ÃƒÂ£Ã‚ÂÃ‚Â¯ÃƒÂ¤Ã‚ÂºÃ‚ÂºÃƒÂ©Ã‚Â–Ã‚Â“ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ¥Ã‚ÂŠÃ‚Â´ÃƒÂ¥Ã‚ÂƒÃ‚ÂÃƒÂ¨Ã‚Â€Ã‚Â…ÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ¤Ã‚Â»Ã‚Â£ÃƒÂ£Ã‚Â‚Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â”ÃƒÂ£Ã‚ÂƒÃ‚Â¥ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚Â‚Ã‚Â¿ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚ÂÃ‚ÂŒÃƒÂ§Ã‚ÂµÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â¿ÃƒÂ¨Ã‚Â¾Ã‚Â¼ÃƒÂ£Ã‚ÂÃ‚Â¾ÃƒÂ£Ã‚Â‚Ã‚ÂŒÃƒÂ£Ã‚ÂÃ‚ÂŸÃƒÂ£Ã‚ÂƒÃ‚Â­ÃƒÂ£Ã‚ÂƒÃ‚ÂœÃƒÂ£Ã‚ÂƒÃ‚ÂƒÃƒÂ£Ã‚ÂƒÃ‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ£Ã‚Â‚Ã‚ÂˆÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ¨Ã‚Â¡Ã‚ÂŒÃƒÂ£Ã‚Â‚Ã‚ÂÃƒÂ£Ã‚Â‚Ã‚ÂŒÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚Â€Ã‚Â‚	Car manufacturing is carried out by computer-programmed robots in place of human workers.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/07/10/semi-form-letters-hooray-for-open-source/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Really funky Planner sorting</title>
		<link>http://sachachua.com/wp/2005/06/29/really-funky-planner-sorting/</link>
		<comments>http://sachachua.com/wp/2005/06/29/really-funky-planner-sorting/#comments</comments>
		<pubDate>Wed, 29 Jun 2005 18:22:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<category><![CDATA[planner]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.06.29.php#anchor-1</guid>
		<description><![CDATA[<p>The following code sorts completed tasks in reverse-chronological
order and incomplete tasks in chronological order. This makes it
easier to see the next action (top of list) and the last action (first
completed task).</p>

<pre class="example">
(defun sacha/planner-sort-tasks-by-date ()
  "Sort tasks by date, status and priority."
  (skip-chars-forward "#ABC")
  (let ((ch (char-before))
        status)
    (skip-chars-forward "0123456789 ")
    (setq status (char-after))
    (goto-char (line-end-position))
    (skip-chars-backward "]) ")
    (format "%1c%1c%10s"
            (cond
             ((= status ?o) ?1)
             ((= status ?X) ?3)
             ((= status ?C) ?4)
             (t ?2))
            ch
            (let ((date (or (planner-task-date (planner-current-task-info))
                            planner-sort-undated-tasks-equivalent)))
              (if (or (= status ?X)
                      (= status ?C))
                  (sacha/planner-invert-date date)
                date)))))

(defun sacha/planner-invert-date (date)
  "Reverse the date in the sorting order."
  (mapconcat (lambda (ch)
               (if (string= ch ".")
                   ch
                 (number-to-string
                  (- 9 (string-to-number ch)))))
             (split-string date "" t) ""))
</pre>

<p><a href="../emacs/planner-config.el">pos://../emacs/planner-config.el#35188</a></p>

<p>ÃƒÂ£Ã‚ÂÃ‚Â“ÃƒÂ£Ã‚ÂÃ‚Â“ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ£Ã‚ÂƒÃ‚Â‘ÃƒÂ£Ã‚Â‚Ã‚Â½ÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂÃ‚Â¯ÃƒÂ£Ã‚Â‚Ã‚Â·ÃƒÂ£Ã‚Â‚Ã‚Â¹ÃƒÂ£Ã‚ÂƒÃ‚Â†ÃƒÂ£Ã‚ÂƒÃ‚Â ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¥Ã‚Â¤Ã‚Â‰ÃƒÂ£Ã‚ÂÃ‚ÂˆÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚ÂÃ‚Â“ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚ÂŒÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ£Ã‚ÂÃ‚ÂÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ¤Ã‚Â½Ã‚Â•ÃƒÂ£Ã‚Â‚Ã‚Â‚ÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ£Ã‚ÂÃ‚ÂÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â€Ã‚Â‚	Because the personal computer here cannot change the system, anything cannot be done.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/planner" rel="tag">planner</a>, <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<p>The following code sorts completed tasks in reverse-chronological
order and incomplete tasks in chronological order. This makes it
easier to see the next action (top of list) and the last action (first
completed task).</p>

<pre class="example">
(defun sacha/planner-sort-tasks-by-date ()
  "Sort tasks by date, status and priority."
  (skip-chars-forward "#ABC")
  (let ((ch (char-before))
        status)
    (skip-chars-forward "0123456789 ")
    (setq status (char-after))
    (goto-char (line-end-position))
    (skip-chars-backward "]) ")
    (format "%1c%1c%10s"
            (cond
             ((= status ?o) ?1)
             ((= status ?X) ?3)
             ((= status ?C) ?4)
             (t ?2))
            ch
            (let ((date (or (planner-task-date (planner-current-task-info))
                            planner-sort-undated-tasks-equivalent)))
              (if (or (= status ?X)
                      (= status ?C))
                  (sacha/planner-invert-date date)
                date)))))

(defun sacha/planner-invert-date (date)
  "Reverse the date in the sorting order."
  (mapconcat (lambda (ch)
               (if (string= ch ".")
                   ch
                 (number-to-string
                  (- 9 (string-to-number ch)))))
             (split-string date "" t) ""))
</pre>

<p><a href="../emacs/planner-config.el">pos://../emacs/planner-config.el#35188</a></p>

<p>ÃƒÂ£Ã‚ÂÃ‚Â“ÃƒÂ£Ã‚ÂÃ‚Â“ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ£Ã‚ÂƒÃ‚Â‘ÃƒÂ£Ã‚Â‚Ã‚Â½ÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂÃ‚Â¯ÃƒÂ£Ã‚Â‚Ã‚Â·ÃƒÂ£Ã‚Â‚Ã‚Â¹ÃƒÂ£Ã‚ÂƒÃ‚Â†ÃƒÂ£Ã‚ÂƒÃ‚Â ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¥Ã‚Â¤Ã‚Â‰ÃƒÂ£Ã‚ÂÃ‚ÂˆÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚ÂÃ‚Â“ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚ÂŒÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ£Ã‚ÂÃ‚ÂÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ¤Ã‚Â½Ã‚Â•ÃƒÂ£Ã‚Â‚Ã‚Â‚ÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ£Ã‚ÂÃ‚ÂÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â€Ã‚Â‚	Because the personal computer here cannot change the system, anything cannot be done.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/planner" rel="tag">planner</a>, <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/06/29/really-funky-planner-sorting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Planner support for action-lock.el</title>
		<link>http://sachachua.com/wp/2005/06/18/planner-support-for-action-lockel/</link>
		<comments>http://sachachua.com/wp/2005/06/18/planner-support-for-action-lockel/#comments</comments>
		<pubDate>Sat, 18 Jun 2005 12:42:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.06.18.php#anchor-1</guid>
		<description><![CDATA[<p><a href="http://sachachua.com/notebook/emacs/howm-1.1.1.1/action-lock.el">action-lock.el</a> is part
of HOWM. The following code enables Planner-style links
_anywhere_. Add it to your ~/.emacs and use M-x action-lock-mode
to turn action locking on.</p>

<pre class="example">
(add-to-list 'action-lock-default-rules
             (list (with-planner emacs-wiki-url-or-name-regexp)
                   'planner-action-lock-follow-name-at-point))
(setq action-lock-rules action-lock-default-rules)
(defvar planner-action-lock-default-directory planner-directory "Expand files relative to this directory.")
(defun planner-action-lock-follow-name-at-point (&#038;optional other-window)
  (let ((link-name (match-string 0))
        (base-buffer (current-buffer))
        ;; the name of the buffer that contains the link.  check
        ;; whether buffer-name is a WikiName, else make it one
        (parent-name (or (emacs-wiki-page-name)
                         (concat "[[" (buffer-name) "]]")))
        (refresh-buffer nil))
    (with-planner
      (let ((link (emacs-wiki-wiki-link-target link-name)))
        (if (emacs-wiki-wiki-url-p link)
            (emacs-wiki-browse-url link other-window)
          ;; The name list is current since the last time the buffer was
          ;; highlighted
          (let* ((base (emacs-wiki-wiki-base link-name))
                 (file (emacs-wiki-page-file base))
                 (tag  (and (not (emacs-wiki-wiki-url-p link))
                            (emacs-wiki-wiki-tag link)))
                 (find-file-function (if other-window
                                         'find-file-other-window
                                       'find-file))
                 (parent-allowed-backlink-p
                  (not (string-match
                        emacs-wiki-exclude-backlink-parent-regexp
                        parent-name)))
                 (parent-backlink (and parent-allowed-backlink-p
				   (emacs-wiki-get-current-backlink)))
                 (newbuf
                  (funcall find-file-function
                           (or file
                               (expand-file-name
                                       base
                                       (or planner-action-lock-default-directory
                                           (and (buffer-file-name)
                                                (file-name-directory
                                                 (buffer-file-name)))
                                           default-directory)))))
                 (emacs-wiki-create-backlinks
                  (and emacs-wiki-create-backlinks parent-allowed-backlink-p))
                 (make-link-p (and emacs-wiki-create-backlinks
                                   ;; insert backlink only in new files
                                   (null file)
                                   (not (string-match
                                         emacs-wiki-exclude-backlink-regexp
                                         (emacs-wiki-page-name
                                          (buffer-file-name newbuf)))))))
            (when tag
              (goto-char (point-min))
              (re-search-forward (concat "^\\.?#" tag) nil t))
            (when refresh-buffer
              (when make-link-p
                (emacs-wiki-insert-backlink parent-name parent-backlink))
              ;; todo: is with-current-buffer necessary here?
              (with-current-buffer newbuf
                (add-hook 'after-save-hook
                          'emacs-wiki-refresh-buffers-once t t)
                ;; save the new file to avoid another backlink if the
                ;; buffer is visited again before being saved
                (when (or make-link-p
                          (and (null file)
                               (not parent-allowed-backlink-p)))
                  ;; set modified status to t: pages with excluded
                  ;; parents may not be modified, but we want to save
                  ;; anyway
                  (set-buffer-modified-p t)
                  (save-buffer))))))))))
</pre>

<p>ÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â”ÃƒÂ£Ã‚ÂƒÃ‚Â¥ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚Â‚Ã‚Â¿ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ§Ã‚ÂŸÃ‚Â¥ÃƒÂ¨Ã‚Â­Ã‚Â˜ÃƒÂ£Ã‚ÂÃ‚Â¯ÃƒÂ£Ã‚ÂÃ‚Â™ÃƒÂ£Ã‚ÂÃ‚Â¹ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ§Ã‚Â§Ã‚Â‘ÃƒÂ¥Ã‚Â­Ã‚Â¦ÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ¥Ã‚ÂŸÃ‚ÂºÃƒÂ¦Ã‚ÂœÃ‚Â¬ÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ£Ã‚ÂÃ‚Â‚ÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚Â€Ã‚Â‚	Knowledge of computers is basic to all sciences.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://sachachua.com/notebook/emacs/howm-1.1.1.1/action-lock.el">action-lock.el</a> is part
of HOWM. The following code enables Planner-style links
_anywhere_. Add it to your ~/.emacs and use M-x action-lock-mode
to turn action locking on.</p>

<pre class="example">
(add-to-list 'action-lock-default-rules
             (list (with-planner emacs-wiki-url-or-name-regexp)
                   'planner-action-lock-follow-name-at-point))
(setq action-lock-rules action-lock-default-rules)
(defvar planner-action-lock-default-directory planner-directory "Expand files relative to this directory.")
(defun planner-action-lock-follow-name-at-point (&optional other-window)
  (let ((link-name (match-string 0))
        (base-buffer (current-buffer))
        ;; the name of the buffer that contains the link.  check
        ;; whether buffer-name is a WikiName, else make it one
        (parent-name (or (emacs-wiki-page-name)
                         (concat "[[" (buffer-name) "]]")))
        (refresh-buffer nil))
    (with-planner
      (let ((link (emacs-wiki-wiki-link-target link-name)))
        (if (emacs-wiki-wiki-url-p link)
            (emacs-wiki-browse-url link other-window)
          ;; The name list is current since the last time the buffer was
          ;; highlighted
          (let* ((base (emacs-wiki-wiki-base link-name))
                 (file (emacs-wiki-page-file base))
                 (tag  (and (not (emacs-wiki-wiki-url-p link))
                            (emacs-wiki-wiki-tag link)))
                 (find-file-function (if other-window
                                         'find-file-other-window
                                       'find-file))
                 (parent-allowed-backlink-p
                  (not (string-match
                        emacs-wiki-exclude-backlink-parent-regexp
                        parent-name)))
                 (parent-backlink (and parent-allowed-backlink-p
				   (emacs-wiki-get-current-backlink)))
                 (newbuf
                  (funcall find-file-function
                           (or file
                               (expand-file-name
                                       base
                                       (or planner-action-lock-default-directory
                                           (and (buffer-file-name)
                                                (file-name-directory
                                                 (buffer-file-name)))
                                           default-directory)))))
                 (emacs-wiki-create-backlinks
                  (and emacs-wiki-create-backlinks parent-allowed-backlink-p))
                 (make-link-p (and emacs-wiki-create-backlinks
                                   ;; insert backlink only in new files
                                   (null file)
                                   (not (string-match
                                         emacs-wiki-exclude-backlink-regexp
                                         (emacs-wiki-page-name
                                          (buffer-file-name newbuf)))))))
            (when tag
              (goto-char (point-min))
              (re-search-forward (concat "^\\.?#" tag) nil t))
            (when refresh-buffer
              (when make-link-p
                (emacs-wiki-insert-backlink parent-name parent-backlink))
              ;; todo: is with-current-buffer necessary here?
              (with-current-buffer newbuf
                (add-hook 'after-save-hook
                          'emacs-wiki-refresh-buffers-once t t)
                ;; save the new file to avoid another backlink if the
                ;; buffer is visited again before being saved
                (when (or make-link-p
                          (and (null file)
                               (not parent-allowed-backlink-p)))
                  ;; set modified status to t: pages with excluded
                  ;; parents may not be modified, but we want to save
                  ;; anyway
                  (set-buffer-modified-p t)
                  (save-buffer))))))))))
</pre>

<p>ÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â”ÃƒÂ£Ã‚ÂƒÃ‚Â¥ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚Â‚Ã‚Â¿ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ§Ã‚ÂŸÃ‚Â¥ÃƒÂ¨Ã‚Â­Ã‚Â˜ÃƒÂ£Ã‚ÂÃ‚Â¯ÃƒÂ£Ã‚ÂÃ‚Â™ÃƒÂ£Ã‚ÂÃ‚Â¹ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ§Ã‚Â§Ã‚Â‘ÃƒÂ¥Ã‚Â­Ã‚Â¦ÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ¥Ã‚ÂŸÃ‚ÂºÃƒÂ¦Ã‚ÂœÃ‚Â¬ÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ£Ã‚ÂÃ‚Â‚ÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚Â€Ã‚Â‚	Knowledge of computers is basic to all sciences.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/06/18/planner-support-for-action-lockel/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Emacs snippet for pmwiki attachments</title>
		<link>http://sachachua.com/wp/2005/06/16/emacs-snippet-for-pmwiki-attachments/</link>
		<comments>http://sachachua.com/wp/2005/06/16/emacs-snippet-for-pmwiki-attachments/#comments</comments>
		<pubDate>Thu, 16 Jun 2005 17:44:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.06.16.php#anchor-2</guid>
		<description><![CDATA[<pre class="example">
(defun sacha/dired-marked-images-as-attach ()
  "Return a list of images ready to be inserted into a pmwiki page."
  (interactive)
  (kill-new (mapconcat
             (lambda (item)
               (concat "Attach:" (file-name-nondirectory item)))
             (dired-get-marked-files)
             "\n")))
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<pre class="example">
(defun sacha/dired-marked-images-as-attach ()
  "Return a list of images ready to be inserted into a pmwiki page."
  (interactive)
  (kill-new (mapconcat
             (lambda (item)
               (concat "Attach:" (file-name-nondirectory item)))
             (dired-get-marked-files)
             "\n")))
</pre>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/06/16/emacs-snippet-for-pmwiki-attachments/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automatically scheduling tasks onto TaskPool</title>
		<link>http://sachachua.com/wp/2005/06/09/automatically-scheduling-tasks-onto-taskpool/</link>
		<comments>http://sachachua.com/wp/2005/06/09/automatically-scheduling-tasks-onto-taskpool/#comments</comments>
		<pubDate>Thu, 09 Jun 2005 14:52:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<category><![CDATA[planner]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.06.09.php#anchor-1</guid>
		<description><![CDATA[<pre class="example">
(defadvice planner-create-task-from-buffer (before paul activate)
  "Automatically schedule task onto TaskPool as well as other projects."
  (if plan-page
      (unless (string-match plan-page "TaskPool")
        (setq plan-page (concat plan-page planner-multi-separator "TaskPool")))
    (setq plan-page "TaskPool")))
</pre>

<p>Here's another snippet that will unschedule tasks from <a href="http://sachachua.com/notebook/wiki/TaskPool">TaskPool</a> when
you mark them completed with C-c C-x (planner-task-done). Nifty stuff,
huh?</p>

<pre class="example">
(defadvice planner-task-done (after paul activate)
  "Remove completed tasks from the TaskPool if that still leaves them linked."
  (let ((info (planner-current-task-info)))
    (when (planner-task-link-text info)
      ;; If it is linked to TaskPool _and_ at least one other thing
      (if (string-match planner-multi-separator (planner-task-link-text info))
          (planner-multi-replan-task
           (planner-multi-make-link (planner-multi-filter-links "^TaskPool$" (planner-multi-task-link-as-list info) t)))
        ;; Else if it has a date and is linked to TaskPool
        (if (and (planner-task-date info)
                 (string= (planner-task-link info) "TaskPool"))
            (planner-replan-task nil))))))
</pre>

<p>ÃƒÂ¥Ã‚ÂŽÃ‚ÂŸÃƒÂ¥Ã‚Â§Ã‚Â‹ÃƒÂ§Ã‚ÂšÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ¨Ã‚Â¨Ã‚ÂˆÃƒÂ§Ã‚Â®Ã‚Â—ÃƒÂ¦Ã‚Â©Ã‚ÂŸÃƒÂ£Ã‚ÂÃ‚ÂŒÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â”ÃƒÂ£Ã‚ÂƒÃ‚Â¥ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚Â‚Ã‚Â¿ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ©Ã‚Â–Ã‚Â‹ÃƒÂ§Ã‚Â™Ã‚ÂºÃƒÂ£Ã‚ÂÃ‚Â•ÃƒÂ£Ã‚Â‚Ã‚ÂŒÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚ÂÃ‚ÂšÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ¤Ã‚Â»Ã‚Â¥ÃƒÂ¥Ã‚Â‰Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ¥Ã‚Â­Ã‚Â˜ÃƒÂ¥Ã‚ÂœÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â—ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚ÂŸÃƒÂ£Ã‚Â€Ã‚Â‚	Primitive calculating machines existed long before computers were developed.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/planner" rel="tag">planner</a>, <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<pre class="example">
(defadvice planner-create-task-from-buffer (before paul activate)
  "Automatically schedule task onto TaskPool as well as other projects."
  (if plan-page
      (unless (string-match plan-page "TaskPool")
        (setq plan-page (concat plan-page planner-multi-separator "TaskPool")))
    (setq plan-page "TaskPool")))
</pre>

<p>Here's another snippet that will unschedule tasks from <a href="http://sachachua.com/notebook/wiki/TaskPool">TaskPool</a> when
you mark them completed with C-c C-x (planner-task-done). Nifty stuff,
huh?</p>

<pre class="example">
(defadvice planner-task-done (after paul activate)
  "Remove completed tasks from the TaskPool if that still leaves them linked."
  (let ((info (planner-current-task-info)))
    (when (planner-task-link-text info)
      ;; If it is linked to TaskPool _and_ at least one other thing
      (if (string-match planner-multi-separator (planner-task-link-text info))
          (planner-multi-replan-task
           (planner-multi-make-link (planner-multi-filter-links "^TaskPool$" (planner-multi-task-link-as-list info) t)))
        ;; Else if it has a date and is linked to TaskPool
        (if (and (planner-task-date info)
                 (string= (planner-task-link info) "TaskPool"))
            (planner-replan-task nil))))))
</pre>

<p>ÃƒÂ¥Ã‚ÂŽÃ‚ÂŸÃƒÂ¥Ã‚Â§Ã‚Â‹ÃƒÂ§Ã‚ÂšÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚ÂªÃƒÂ¨Ã‚Â¨Ã‚ÂˆÃƒÂ§Ã‚Â®Ã‚Â—ÃƒÂ¦Ã‚Â©Ã‚ÂŸÃƒÂ£Ã‚ÂÃ‚ÂŒÃƒÂ£Ã‚Â€Ã‚ÂÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â”ÃƒÂ£Ã‚ÂƒÃ‚Â¥ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚Â‚Ã‚Â¿ÃƒÂ£Ã‚ÂƒÃ‚Â¼ÃƒÂ£Ã‚ÂÃ‚Â®ÃƒÂ©Ã‚Â–Ã‚Â‹ÃƒÂ§Ã‚Â™Ã‚ÂºÃƒÂ£Ã‚ÂÃ‚Â•ÃƒÂ£Ã‚Â‚Ã‚ÂŒÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚ÂÃ‚ÂšÃƒÂ£Ã‚ÂÃ‚Â£ÃƒÂ£Ã‚ÂÃ‚Â¨ÃƒÂ¤Ã‚Â»Ã‚Â¥ÃƒÂ¥Ã‚Â‰Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â«ÃƒÂ¥Ã‚Â­Ã‚Â˜ÃƒÂ¥Ã‚ÂœÃ‚Â¨ÃƒÂ£Ã‚ÂÃ‚Â—ÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂÃ‚ÂŸÃƒÂ£Ã‚Â€Ã‚Â‚	Primitive calculating machines existed long before computers were developed.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/planner" rel="tag">planner</a>, <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/06/09/automatically-scheduling-tasks-onto-taskpool/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Adding an arbitrary extension to your planner files</title>
		<link>http://sachachua.com/wp/2005/06/07/adding-an-arbitrary-extension-to-your-planner-files/</link>
		<comments>http://sachachua.com/wp/2005/06/07/adding-an-arbitrary-extension-to-your-planner-files/#comments</comments>
		<pubDate>Tue, 07 Jun 2005 20:55:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<category><![CDATA[planner]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.06.07.php#anchor-2</guid>
		<description><![CDATA[<p>Do you want all of your planner files to have a TXT extension so that
they'll be searched by tools such as Google Desktop or Apple Spotlight?</p>

<p>Use the 'rename' tool to add .txt extensions to all of your files, or
use the following code to rename all of your planner files from a
running Planner setup:</p>

<pre class="example">
(defun my-rename-planner-files ()
  "Rename all my planner files to .txt if they don't have that extension yet."
  (interactive)
  (mapcar
   (lambda (file)
     (unless (string-match "\\.txt$" (cdr file))
       (rename-file (cdr file) (concat (cdr file) ".txt"))
       (message "%s" (cdr file))))
   (planner-file-alist))
  (with-planner
    (emacs-wiki-refresh-file-alist)))
</pre>

<p>Then add this to your ~/.emacs before you load Planner:</p>

<pre class="example">
(setq emacs-wiki-ignored-extensions-regexp "\\.txt")

(defadvice emacs-wiki-find-file (around extension activate)
  "Open the Emacs Wiki page WIKI by name.
If COMMAND is non-nil, it is the function used to visit the file.
If DIRECTORY is non-nil, it is the directory in which the Wiki
page will be created if it does not already exist."
  (unless (interactive-p)
    (setq wiki (cons wiki
                     (cdr (assoc wiki (emacs-wiki-file-alist))))))
  ;; At this point, `wiki' is (GIVEN-PAGE FOUND-FILE).
  (if (cdr wiki)
      (let ((buffer (funcall (or command 'find-file) (cdr wiki))))
        (if (= (prefix-numeric-value current-prefix-arg) 16)
            (with-current-buffer buffer
              (set (make-variable-buffer-local 'emacs-wiki-directories)
                   (cons (file-name-directory (cdr wiki))
                         emacs-wiki-directories))
              (set (make-variable-buffer-local 'emacs-wiki-file-alist)
                   nil)))
        buffer)
    (let* ((dirname (or directory
                        (emacs-wiki-maybe t)
                        (car emacs-wiki-directories)))
           (filename (expand-file-name (car wiki) dirname)))
      (unless (file-exists-p dirname)
        (make-directory dirname t))
      (funcall (or command 'find-file) (concat filename ".txt")))))
</pre>

<p>ÃƒÂ¦Ã‚Â–Ã‚Â°ÃƒÂ£Ã‚ÂÃ‚Â—ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂƒÃ‚Â‘ÃƒÂ£Ã‚Â‚Ã‚Â½ÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¨Ã‚Â²Ã‚Â·ÃƒÂ£Ã‚ÂÃ‚Â†ÃƒÂ£Ã‚ÂÃ‚Â¤ÃƒÂ£Ã‚Â‚Ã‚Â‚ÃƒÂ£Ã‚Â‚Ã‚ÂŠÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ©Ã‚Â‡Ã‚Â‘ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¦Ã‚ÂºÃ‚ÂœÃƒÂ£Ã‚Â‚Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚Â‚Ã‚Â“ÃƒÂ£Ã‚ÂÃ‚Â ÃƒÂ£Ã‚Â€Ã‚Â‚	I am saving money in order to buy a new personal computer.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/planner" rel="tag">planner</a>, <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Do you want all of your planner files to have a TXT extension so that
they'll be searched by tools such as Google Desktop or Apple Spotlight?</p>

<p>Use the 'rename' tool to add .txt extensions to all of your files, or
use the following code to rename all of your planner files from a
running Planner setup:</p>

<pre class="example">
(defun my-rename-planner-files ()
  "Rename all my planner files to .txt if they don't have that extension yet."
  (interactive)
  (mapcar
   (lambda (file)
     (unless (string-match "\\.txt$" (cdr file))
       (rename-file (cdr file) (concat (cdr file) ".txt"))
       (message "%s" (cdr file))))
   (planner-file-alist))
  (with-planner
    (emacs-wiki-refresh-file-alist)))
</pre>

<p>Then add this to your ~/.emacs before you load Planner:</p>

<pre class="example">
(setq emacs-wiki-ignored-extensions-regexp "\\.txt")

(defadvice emacs-wiki-find-file (around extension activate)
  "Open the Emacs Wiki page WIKI by name.
If COMMAND is non-nil, it is the function used to visit the file.
If DIRECTORY is non-nil, it is the directory in which the Wiki
page will be created if it does not already exist."
  (unless (interactive-p)
    (setq wiki (cons wiki
                     (cdr (assoc wiki (emacs-wiki-file-alist))))))
  ;; At this point, `wiki' is (GIVEN-PAGE FOUND-FILE).
  (if (cdr wiki)
      (let ((buffer (funcall (or command 'find-file) (cdr wiki))))
        (if (= (prefix-numeric-value current-prefix-arg) 16)
            (with-current-buffer buffer
              (set (make-variable-buffer-local 'emacs-wiki-directories)
                   (cons (file-name-directory (cdr wiki))
                         emacs-wiki-directories))
              (set (make-variable-buffer-local 'emacs-wiki-file-alist)
                   nil)))
        buffer)
    (let* ((dirname (or directory
                        (emacs-wiki-maybe t)
                        (car emacs-wiki-directories)))
           (filename (expand-file-name (car wiki) dirname)))
      (unless (file-exists-p dirname)
        (make-directory dirname t))
      (funcall (or command 'find-file) (concat filename ".txt")))))
</pre>

<p>ÃƒÂ¦Ã‚Â–Ã‚Â°ÃƒÂ£Ã‚ÂÃ‚Â—ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚ÂƒÃ‚Â‘ÃƒÂ£Ã‚Â‚Ã‚Â½ÃƒÂ£Ã‚Â‚Ã‚Â³ÃƒÂ£Ã‚ÂƒÃ‚Â³ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¨Ã‚Â²Ã‚Â·ÃƒÂ£Ã‚ÂÃ‚Â†ÃƒÂ£Ã‚ÂÃ‚Â¤ÃƒÂ£Ã‚Â‚Ã‚Â‚ÃƒÂ£Ã‚Â‚Ã‚ÂŠÃƒÂ£Ã‚ÂÃ‚Â§ÃƒÂ©Ã‚Â‡Ã‚Â‘ÃƒÂ£Ã‚Â‚Ã‚Â’ÃƒÂ¦Ã‚ÂºÃ‚ÂœÃƒÂ£Ã‚Â‚Ã‚ÂÃƒÂ£Ã‚ÂÃ‚Â¦ÃƒÂ£Ã‚ÂÃ‚Â„ÃƒÂ£Ã‚Â‚Ã‚Â‹ÃƒÂ£Ã‚Â‚Ã‚Â“ÃƒÂ£Ã‚ÂÃ‚Â ÃƒÂ£Ã‚Â€Ã‚Â‚	I am saving money in order to buy a new personal computer.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/planner" rel="tag">planner</a>, <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/06/07/adding-an-arbitrary-extension-to-your-planner-files/feed/</wfw:commentRss>
		</item>
		<item>
		<title>sacha/planner-add-recent</title>
		<link>http://sachachua.com/wp/2005/04/20/sachaplanner-add-recent/</link>
		<comments>http://sachachua.com/wp/2005/04/20/sachaplanner-add-recent/#comments</comments>
		<pubDate>Wed, 20 Apr 2005 22:01:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.04.20.php#anchor-5</guid>
		<description><![CDATA[<pre class="example">
(defun sacha/planner-add-recent ()
  "Add the current note to the list of recent entries, trimmed at 10."
  (interactive)
  (let* ((info (planner-current-note-info))
         (url (concat
               "http://sacha.free.net.ph/notebook/wiki/"
               (emacs-wiki-published-name (planner-note-page info))
               "#" (planner-note-anchor info))))
    (when info
      (with-current-buffer
          (find-file-noselect "/home/sacha/notebook/wiki/include/footer.inc.php")
        (goto-char (point-min))
        (when (re-search-forward "--recent--" nil t)
          (save-restriction
            (narrow-to-region (1+ (line-end-position))
                              (progn
                                (re-search-forward "--end of recent--" nil t)
                                (line-beginning-position)))
            (goto-char (point-min))
            (insert "<a href=\"" url "\">"
                    (planner-note-title info)
                    "</a><br/>\n")
            (forward-line 10)
            (delete-region (point) (point-max))
            (save-buffer)))))))
</pre>

<p><a href="http://sachachua.com/notebook/emacs/planner-config.el">../emacs/planner-config.el</a></p>

<p>Ã£ÂÂÃ£ÂÂ®Ã£ÂÂ‹Ã£Â‚ÂÃ£ÂÂ„Ã£ÂÂÃ£ÂÂ†Ã£ÂÂªÃ£ÂƒÂÃ£Â‚Â³Ã£ÂÂ¯Ã£ÂƒÂˆÃ£ÂƒÂ©Ã£ÂƒÂƒÃ£Â‚Â¯Ã£ÂÂ«Ã£ÂÂ²Ã£ÂÂ‹Ã£Â‚ÂŒÃ£ÂÂŸÃ£Â€Â‚	The poor cat was run over by a truck.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<pre class="example">
(defun sacha/planner-add-recent ()
  "Add the current note to the list of recent entries, trimmed at 10."
  (interactive)
  (let* ((info (planner-current-note-info))
         (url (concat
               "http://sacha.free.net.ph/notebook/wiki/"
               (emacs-wiki-published-name (planner-note-page info))
               "#" (planner-note-anchor info))))
    (when info
      (with-current-buffer
          (find-file-noselect "/home/sacha/notebook/wiki/include/footer.inc.php")
        (goto-char (point-min))
        (when (re-search-forward "--recent--" nil t)
          (save-restriction
            (narrow-to-region (1+ (line-end-position))
                              (progn
                                (re-search-forward "--end of recent--" nil t)
                                (line-beginning-position)))
            (goto-char (point-min))
            (insert "<a href=\"" url "\">"
                    (planner-note-title info)
                    "</a><br/>\n")
            (forward-line 10)
            (delete-region (point) (point-max))
            (save-buffer)))))))
</pre>

<p><a href="http://sachachua.com/notebook/emacs/planner-config.el">../emacs/planner-config.el</a></p>

<p>Ã£ÂÂÃ£ÂÂ®Ã£ÂÂ‹Ã£Â‚ÂÃ£ÂÂ„Ã£ÂÂÃ£ÂÂ†Ã£ÂÂªÃ£ÂƒÂÃ£Â‚Â³Ã£ÂÂ¯Ã£ÂƒÂˆÃ£ÂƒÂ©Ã£ÂƒÂƒÃ£Â‚Â¯Ã£ÂÂ«Ã£ÂÂ²Ã£ÂÂ‹Ã£Â‚ÂŒÃ£ÂÂŸÃ£Â€Â‚	The poor cat was run over by a truck.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/04/20/sachaplanner-add-recent/feed/</wfw:commentRss>
		</item>
		<item>
		<title>sacha/emacs-wiki-markup-string</title>
		<link>http://sachachua.com/wp/2005/04/20/sachaemacs-wiki-markup-string/</link>
		<comments>http://sachachua.com/wp/2005/04/20/sachaemacs-wiki-markup-string/#comments</comments>
		<pubDate>Wed, 20 Apr 2005 20:21:00 +0000</pubDate>
		<dc:creator>Sacha Chua</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://sachachua.com/notebook/wiki/2005.04.20.php#anchor-4</guid>
		<description><![CDATA[<pre class="example">
(defun sacha/emacs-wiki-markup-string (string)
  "Mark up STRING according to `emacs-wiki-publishing-rules'.
No header or footer is added."
  (let ((emacs-wiki-project emacs-wiki-current-project))
    (with-temp-buffer
      (emacs-wiki-mode)
      (insert string)
      (let ((emacs-wiki-publishing-header "")
            (emacs-wiki-publishing-footer ""))
        (emacs-wiki-replace-markup))
      (buffer-string))))
</pre>

<p><a href="http://sachachua.com/notebook/emacs/emacs-wiki-config.el">../emacs/emacs-wiki-config.el</a></p>

<p>Ã£ÂÂ†Ã£ÂÂ¡Ã£ÂÂ®Ã§ÂŒÂ«Ã£ÂÂ¯Ã¥ÂÂ°Ã¦Â‰Â€Ã£ÂÂ«Ã£ÂÂ„Ã£ÂÂ¾Ã£ÂÂ™Ã£Â€Â‚	Our cat is in the kitchen.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></description>
			<content:encoded><![CDATA[<pre class="example">
(defun sacha/emacs-wiki-markup-string (string)
  "Mark up STRING according to `emacs-wiki-publishing-rules'.
No header or footer is added."
  (let ((emacs-wiki-project emacs-wiki-current-project))
    (with-temp-buffer
      (emacs-wiki-mode)
      (insert string)
      (let ((emacs-wiki-publishing-header "")
            (emacs-wiki-publishing-footer ""))
        (emacs-wiki-replace-markup))
      (buffer-string))))
</pre>

<p><a href="http://sachachua.com/notebook/emacs/emacs-wiki-config.el">../emacs/emacs-wiki-config.el</a></p>

<p>Ã£ÂÂ†Ã£ÂÂ¡Ã£ÂÂ®Ã§ÂŒÂ«Ã£ÂÂ¯Ã¥ÂÂ°Ã¦Â‰Â€Ã£ÂÂ«Ã£ÂÂ„Ã£ÂÂ¾Ã£ÂÂ™Ã£Â€Â‚	Our cat is in the kitchen.</p>

<p>On Technorati: <a href="http://www.technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://www.technorati.com/tag/code" rel="tag">code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sachachua.com/wp/2005/04/20/sachaemacs-wiki-markup-string/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
