<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?><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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
	<title>Sacha Chua - tag - latin</title>
	<atom:link href="https://sachachua.com/blog/tag/latin/feed/index.xml" rel="self" type="application/rss+xml" />
	<atom:link href="https://sachachua.com/blog/tag/latin" rel="alternate" type="text/html" />
	<link>https://sachachua.com/blog/tag/latin/feed/index.xml</link>
	<description>Emacs, sketches, and life</description>
	<lastBuildDate>Sat, 04 Apr 2026 02:23:03 GMT</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>11ty</generator>
  <item>
		<title>Org Mode tables and fill-in quizzes &#8211; Latin verb conjugation drills in Emacs</title>
		<link>https://sachachua.com/blog/2015/11/org-mode-tables-fill-quizzes-latin-verb-conjugation-drills-emacs/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Fri, 27 Nov 2015 02:22:00 GMT</pubDate>
    <category>emacs</category>
<category>org</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=28490</guid>
		<description><![CDATA[<p>I was looking for a Latin verb conjugation drill similar to these ones for and <a href="http://www.latintests.net/grammar/nouns.php">nouns</a> and <a href="http://www.latintests.net/grammar/pronouns1.php">pronouns.</a> I liked the instant feedback and the ability to quickly get hints. I couldn&#8217;t find an online drill I liked, though, so I made my own with Emacs and Org. (Because… why not?)</p>
<p>I wrote some code that would take a table like this:</p>
<table id="orgtable1" border="2" frame="hsides" rules="groups" cellspacing="0" cellpadding="6">
<colgroup>
<col class="org-left">
<col class="org-left"> </colgroup>
<tbody>
<tr>
<td class="org-left">present &#8211; 1st sing. &#8211; ago / agere</td>
<td class="org-left">agO</td>
</tr>
<tr>
<td class="org-left">present &#8211; 2nd sing. &#8211; ago / agere</td>
<td class="org-left">agis</td>
</tr>
<tr>
<td class="org-left">present &#8211; 3rd sing. &#8211; ago / agere</td>
<td class="org-left">agit</td>
</tr>
<tr>
<td class="org-left">present &#8211; 1st plu. &#8211; ago / agere</td>
<td class="org-left">agimus</td>
</tr>
<tr>
<td class="org-left">present &#8211; 2nd plu. &#8211; ago / agere</td>
<td class="org-left">agitis</td>
</tr>
<tr>
<td class="org-left">present &#8211; 3rd plu. &#8211; ago / agere</td>
<td class="org-left">agunt</td>
</tr>
<tr>
<td class="org-left">imperfect &#8211; 1st sing. &#8211; ago / agere</td>
<td class="org-left">agEbam</td>
</tr>
<tr>
<td class="org-left">imperfect &#8211; 2nd sing. &#8211; ago / agere</td>
<td class="org-left">agEbAs</td>
</tr>
<tr>
<td class="org-left">imperfect &#8211; 3rd sing. &#8211; ago / agere</td>
<td class="org-left">agEbat</td>
</tr>
<tr>
<td class="org-left">imperfect &#8211; 1st plu. &#8211; ago / agere</td>
<td class="org-left">agEbAmus</td>
</tr>
<tr>
<td class="org-left">imperfect &#8211; 2nd plu. &#8211; ago / agere</td>
<td class="org-left">agEbAtis</td>
</tr>
<tr>
<td class="org-left">imperfect &#8211; 3rd plu. &#8211; ago / agere</td>
<td class="org-left">agEbant</td>
</tr>
<tr>
<td class="org-left">future &#8211; 1st sing. &#8211; ago / agere</td>
<td class="org-left">agam</td>
</tr>
<tr>
<td class="org-left">future &#8211; 2nd sing. &#8211; ago / agere</td>
<td class="org-left">agEs</td>
</tr>
<tr>
<td class="org-left">future &#8211; 3rd sing. &#8211; ago / agere</td>
<td class="org-left">agEt</td>
</tr>
<tr>
<td class="org-left">future &#8211; 1st plu. &#8211; ago / agere</td>
<td class="org-left">agEmus</td>
</tr>
<tr>
<td class="org-left">future &#8211; 2nd plu. &#8211; ago / agere</td>
<td class="org-left">agEtis</td>
</tr>
<tr>
<td class="org-left">future &#8211; 3rd plu. &#8211; ago / agere</td>
<td class="org-left">agent</td>
</tr>
</tbody>
</table>
<p>I can call <code>my/make-fill-in-quiz</code> to get a quiz buffer that looks like this. If I get stuck, <code>?</code> shows me a hint in the echo area.</p>
<p><a href="https://sachachua.com/blog/wp-content/uploads/2015/11/latin-verb-drills-0.gif"><img loading="lazy" class="alignnone size-full wp-image-28491" src="https://sachachua.com/blog/wp-content/uploads/2015/11/latin-verb-drills-0.gif" alt="latin-verb-drills-0" width="640" height="480"></a></p>
<p>To make it easier, I&#8217;ve left <code>case-fold-search</code> set to <code>nil</code> so that I don&#8217;t have to match the case (uppercase vowels = macrons), but I can set <code>case-fold-search</code> to <code>t</code> if I want to make sure I&#8217;ve got the macrons in the right places.</p>
<p>Here&#8217;s the code to display the quiz buffer.</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">     (<span class="org-keyword">require</span> '<span class="org-constant">widget</span>)
     (<span class="org-keyword">defun</span> <span class="org-function-name">my/check-widget-value</span> (widget <span class="org-type">&amp;rest</span> ignore)
       <span class="org-doc">"Provide visual feedback for WIDGET."</span>
       (<span class="org-keyword">cond</span>
        ((string= (widget-value widget) <span class="org-string">"?"</span>)
         <span class="org-comment-delimiter">;; </span><span class="org-comment">Asking for hint</span>
         (message <span class="org-string">"%s"</span> (widget-get widget <span class="org-builtin">:correct</span>))
         (widget-value-set widget <span class="org-string">""</span>))
        <span class="org-comment-delimiter">;; </span><span class="org-comment">Use string-match to obey case-fold-search </span>
        ((string-match 
          (concat <span class="org-string">"^"</span>
                  (regexp-quote (widget-get widget <span class="org-builtin">:correct</span>))
                  <span class="org-string">"$"</span>)
          (widget-value widget))
         (message <span class="org-string">"Correct"</span>)
         (goto-char (widget-field-start widget))
         (goto-char (line-end-position))
         (insert <span class="org-string">"✓"</span>)
         (widget-forward 1)
         )))

   (<span class="org-keyword">defun</span> <span class="org-function-name">my/make-fill-in-quiz</span> (<span class="org-type">&amp;optional</span> quiz-table)
     <span class="org-doc">"Create an fill-in quiz for the Org table at point.</span>
<span class="org-doc">The Org table's first column should have the questions and the second column </span>
<span class="org-doc">should have the answers."</span>
     (interactive (list (org-babel-read-table)))
     (<span class="org-keyword">with-current-buffer</span> (get-buffer-create <span class="org-string">"*Quiz*"</span>)
       (kill-all-local-variables)
       (<span class="org-keyword">let</span> ((inhibit-read-only t))
         (erase-buffer))
       (remove-overlays)
       (mapc (<span class="org-keyword">lambda</span> (row)
               (widget-insert (car row))
               (widget-insert <span class="org-string">"\t"</span>)
               (widget-create 'editable-field
                              <span class="org-builtin">:size</span> 15
                              <span class="org-builtin">:correct</span> (cadr row)
                              <span class="org-builtin">:notify</span> 'my/check-widget-value)
               (widget-insert <span class="org-string">"\n"</span>))    
             quiz-table)
       (widget-create 'push-button
                      <span class="org-builtin">:table</span> quiz-table
                      <span class="org-builtin">:notify</span> (<span class="org-keyword">lambda</span> (widget <span class="org-type">&amp;rest</span> ignore)
                                (my/make-fill-in-quiz (widget-get widget <span class="org-builtin">:table</span>))) 
                      <span class="org-string">"Reset"</span>)
       (use-local-map widget-keymap)
       (widget-setup)
       (goto-char (point-min))
       (widget-forward 1)
       (switch-to-buffer (current-buffer))))
</pre>
</div>
<p>Incidentally, I generated the table above from a larger table of Latin verb conjugations in the appendix of Wheelock&#8217;s Latin, specified like this:</p>
<div class="org-src-container">
<pre class="src src-org"><span class="org-org-meta-line">#+NAME: present-indicative-active</span>
<span class="org-org-table">| laudO    | moneO   | agO    | audiO   | capiO   |</span>
<span class="org-org-table">| laudAs   | monEs   | agis   | audIs   | capis   |</span>
<span class="org-org-table">| laudat   | monet   | agit   | audit   | capit   |</span>
<span class="org-org-table">| laudAmus | monEmus | agimus | audImus | capimus |</span>
<span class="org-org-table">| laudAtis | monEtis | agitis | audItis | capitis |</span>
<span class="org-org-table">| laudant  | monent  | agunt  | audiunt | capiunt |</span>

<span class="org-org-meta-line">#+NAME: imperfect-indicative-active</span>
<span class="org-org-table">| laudAbam   | monEbam   | agEbam   | audiEbam   | capiEbam   |</span>
<span class="org-org-table">| laudAbas   | monEbas   | agEbAs   | audiEbAs   | capiEbas   |</span>
<span class="org-org-table">| laudAbat   | monEbat   | agEbat   | audiEbat   | capiEbat   |</span>
<span class="org-org-table">| laudAbAmus | monEbAmus | agEbAmus | audiEbAmus | capiEbAmus |</span>
<span class="org-org-table">| laudAbAtis | monEbAtis | agEbAtis | audiEbAtis | capiEbAtis |</span>
<span class="org-org-table">| laudAbant  | monEbant  | agEbant  | audiEbant  | capiEbant  |</span>

<span class="org-org-meta-line">#+NAME: future-indicative-active</span>
<span class="org-org-table">| laudAbO    | monEbO    | agam   | audiam     | capiam     |</span>
<span class="org-org-table">| laudAbis   | monEbis   | agEs   | audiEs     | capiEs     |</span>
<span class="org-org-table">| laudAbit   | monEbit   | agEt   | audiet     | capiet     |</span>
<span class="org-org-table">| laudAbimus | monEbimus | agEmus | audiEmus   | capiEmus   |</span>
<span class="org-org-table">| laudAbitis | monEbitis | agEtis | audiEtis   | capiEtis   |</span>
<span class="org-org-table">| laudAbunt  | monEbunt  | agent  | audient    | capient    |</span>
</pre>
</div>
<p>with the code:</p>
<div class="org-src-container">
<pre class="src src-org"><span class="org-org-block-begin-line">#+begin_src emacs-lisp :var present=present-indicative-active :var imperfect=imperfect-indicative-active :var future=future-indicative-active</span>
  (<span class="org-keyword">defun</span> <span class="org-function-name">my/label-latin-with-verbs</span> (table verbs persons tense)
    (apply 'append
           (-zip-with (<span class="org-keyword">lambda</span> (row person) 
                        (-zip-with (<span class="org-keyword">lambda</span> (word verb)
                                     (list word (format <span class="org-string">"%s - %s - %s"</span> tense person verb)))
                                   row verbs))
                      table (-cycle persons))))
  (apply 'append 
         (mapcar (<span class="org-keyword">lambda</span> (tense)
                   (my/label-latin-with-verbs 
                    (symbol-value tense)
                    '(<span class="org-string">"laudo / laudare"</span> <span class="org-string">"moneo / monEre"</span> <span class="org-string">"ago / agere"</span> <span class="org-string">"audiO / audIre"</span> <span class="org-string">"capiO / capere"</span>)
                    '(<span class="org-string">"1st sing."</span> <span class="org-string">"2nd sing."</span> <span class="org-string">"3rd sing."</span> <span class="org-string">"1st plu."</span> <span class="org-string">"2nd plu."</span> <span class="org-string">"3rd plu."</span>)
                    (symbol-name tense)))
                 '(present imperfect future)))

<span class="org-org-block-end-line">#+end_src</span>
</pre>
</div>
<p>This uses <code>dash.el</code> for the <code>-zip-with</code> and <code>-cycle</code> functions. There&#8217;s probably a much better way to process the lists, but I&#8217;m still getting the hang of thinking properly functionally… =)</p>
<p>Anyway, I&#8217;m sure it will be handy for a number of other quiz-like things. org-drill and org-drill-table will probably come in handy for flashcards, too!</p>

<p>You can <a href="https://sachachua.com/blog/2015/11/org-mode-tables-fill-quizzes-latin-verb-conjugation-drills-emacs/#comment">view 4 comments</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2015%2F11%2Forg-mode-tables-fill-quizzes-latin-verb-conjugation-drills-emacs%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Sketchnote: Fun With Dead Languages: Damian Conway</title>
		<link>https://sachachua.com/blog/2013/08/sketchnote-fun-with-dead-languages-damian-conway/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Wed, 07 Aug 2013 01:22:11 GMT</pubDate>
    <category>geek</category>
<category>sketchnotes</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=25710</guid>
		<description><![CDATA[<p>Here are my notes from Damian Conway’s talk “Fun With Dead Languages”. =) I heard him give an older version of this talk years ago, and I’m amused to find that my Latin dabbling gave me a much deeper appreciation of this talk. </p>
<p>As always, click on the image to view a larger version, which you can print out if you want.</p>
<p><a href="https://sachachua.com/blog/wp-content/uploads/2013/08/20130806-Fun-with-Dead-Languages-Damian-Conway1.png"><img loading="lazy" title="20130806 Fun with Dead Languages - Damian Conway" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="20130806 Fun with Dead Languages - Damian Conway" src="https://sachachua.com/blog/wp-content/uploads/2013/08/20130806-Fun-with-Dead-Languages-Damian-Conway_thumb1.png" width="640" height="480"></a></p>
<p>Please feel free to share this under the Creative Commons Attribution License! =)</p>
<p>If you like this, check out <a href="http://damian.conway.org/">Damian Conway’s site</a> or this paper on <a href="http://www.csse.monash.edu.au/~damian/papers/HTML/Perligata.html">Lingua::Latina::Perligata</a>. Like these sketches? Check out my other <a href="https://sachachua.com/blog/category/sketchnotes">sketchnotes</a> and <a href="https://sachachua.com/blog/category/visual-book-notes">visual book reviews</a>.</p>

<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2013%2F08%2Fsketchnote-fun-with-dead-languages-damian-conway%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Cattus Petasatus</title>
		<link>https://sachachua.com/blog/2011/05/cattus-petasatus/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Sat, 14 May 2011 12:00:09 GMT</pubDate>
    <category>learning</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=22207</guid>
		<description><![CDATA[<p>On a whim, W- and I are learning Latin. We figure that schoolkids used to learn Latin and Greek, so we should be able to hack it too. So we&#8217;ve signed up for an Internet study group, borrowed books from the library, and looked for other Latin resources.</p>
<p>We were delighted to find Cattus Petasatus, a Latin translation of Dr. Seuss&#8217; The Cat in the Hat. There are even translations for some of the other books, like Green Eggs and Ham. I like reading them in addition to our textbooks. They make Latin feel more contemporary.</p>
<p>Learning Latin with W- is a lot of fun. He shares the ways Latin reminds him of French. He thinks I find it easier to say Latin than he does because of my background in Filipino, which also has a lot of short syllables. We review our study group homework together, laugh at the contrived examples, and look around for other resources. I&#8217;m so lucky my husband is a geek. =)</p>
<p>We&#8217;ll gradually work our way up to Winnie ille Pu. Maybe we&#8217;ll even put together our own Latin projects!</p>

<p>You can <a href="https://sachachua.com/blog/2011/05/cattus-petasatus/#comment">view 1 comment</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2011%2F05%2Fcattus-petasatus%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>&quot;An Easy Method for Beginners in Latin&quot; and macron-insensitive search for Tiddlywiki</title>
		<link>https://sachachua.com/blog/2011/04/macron-insensitive-search-for-tiddlywiki-and-an-easy-method-for-beginners-in-latin/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Sat, 30 Apr 2011 12:00:00 GMT</pubDate>
    <category>geek</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=22225</guid>
		<description><![CDATA[<p>As previously mentioned, W- and I are re-typing parts of Albert Harkness&#8217; 1822 textbook &quot;An Easy Method for Beginners in Latin&quot;, which was digitized and uploaded to Google Books as a PDF of images. The non-searchable book was driving W- mad, so we&#8217;re re-typing up lessons. It&#8217;s a decent way to review, and I&#8217;m sure it will be a great resource for other people too.</p>
<p><a href="https://sachachua.com/notebook/latin/"><strong>Here&#8217;s what we have so far: An Easy Method for Beginners in Latin, Lessons 1-9</strong></a></p>
<p>We&#8217;re starting off using Tiddlywiki because it&#8217;s a wiki system that W-&#8216;s been using a lot for his personal notes. He&#8217;s familiar with the markup. It&#8217;s not ideal because Google doesn&#8217;t index it, the file size is bigger than it needs to be (0.5MB!), and it&#8217;s Javascript-based. It&#8217;s a good start, though, and I should be able to convert the file to another format with a little scripting. My first instinct would be to start with Org Mode for Emacs, of course, but we <a href="https://sachachua.com/blog/2011/04/writing-macrons-linux-latin-pronunciation/">already know what W- thinks of Emacs</a>. ;)</p>
<p>Most of the text was easy to enter. Harkness is quite fond of footnotes, numbered sections, and lots of bold and italic formatting. We&#8217;re going to skip the illustrations for now.</p>
<p>Typing all of this in and using it as our own reference, though, we quickly ran into a limitation of the standard TiddlyWiki engine (and really, probably all wiki engines): you had to search for the exact word to find something. In order to find <b>poēta</b>, you had to type <b>poēta</b>, not <b>poeta</b>. That&#8217;s because <b>ē</b> and <b>e</b> are two different characters.</p>
<p>We wanted to keep the macrons as pronunciation and grammar guides. We didn&#8217;t want to require people to know or type letters with macrons. Hmm. Time to hack Tiddlywiki.</p>
<p>TiddlyWiki plugins use Javascript. I found a <a href="http://devpad.tiddlyspot.com/#SimpleSearchPlugin">sample search plugin</a> that showed me the basics of what I needed.</p>
<p>I considered two approaches:</p>
<ol>
<li>Changing the search text to a regular expression that included macron versions of each vowel </li>
<li>Replacing all vowels in the Tiddler texts with non-macron vowels when searching </li>
</ol>
<p>The first approach was cleaner and looked much more efficient, so I chose that route. If the search text contained a macron, I assumed the searcher knew what he or she was doing, so I left the text alone. If the text did not contain a macron, I replaced every vowel with a regular expression matching the macron equivalents. Here&#8217;s what that part of the code looked like:</p>
<pre class="src src-javascript">s = s.replace(/(.)/g, &quot;['/]*$1&quot;);
if (!s.match(macronPattern)) {
  // Replace the vowels with the corresponding macron matchers
  s = s.replace(/a/, &quot;[aāĀA]&quot;);
  s = s.replace(/e/, &quot;[eēĒE]&quot;);
  s = s.replace(/i/, &quot;[iīĪI]&quot;);
  s = s.replace(/o/, &quot;[oōŌO]&quot;);
  s = s.replace(/u/, &quot;[uūŪU]&quot;);
}</pre>
<p>That got me almost all the way there. I could search for most of the words using plain text (so <b>poeta</b> would find <b>poēta</b> and <b>regina</b> would find <b>rēgīnae</b>), but some words still couldn&#8217;t be found.</p>
<p>A further quirk of the textbook is that the characters in a word might be interrupted by formatting. For example, <code>poēt&lt;strong&gt;am&lt;/strong&gt;</code> is written as =poēt&#8221;am&#8221;= in Tiddlywiki markup. So I also inserted a regular expression matching any number of &#8216; or / (bold or italic markers when doubled) between each letter:</p>
<pre style="overflow: visible" class="src src-javascript">s = s.replace(/(.)/g, &quot;['/]*$1&quot;);</pre>
<p>It&#8217;s important to do this <b>before</b> the macron substitution, or you&#8217;ll have regexp classes inside other classes.</p>
<p>That&#8217;s the core of the macron search. Here’s what it looks like. I was so thrilled when I got all of this lined up! =)</p>
<p><a href="https://sachachua.com/blog/wp-content/uploads/2011/04/image1.png"><img loading="lazy" style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://sachachua.com/blog/wp-content/uploads/2011/04/image_thumb1.png" width="580" height="359"></a></p>
<p>And the source code:</p>
<pre class="src src-javascript">// Macron Search Plugin
// (c) 2011 Sacha Chua - Creative Commons Attribution ShareAlike 3.0 License
// Based on http://devpad.tiddlyspot.com/#SimpleSearchPlugin by FND

if(!version.extensions.MacronSearchPlugin) { //# ensure that the plugin is only installed once
version.extensions.MacronSearchPlugin = { installed: true };

if(!config.extensions) { config.extensions = {}; }

config.extensions.MacronSearchPlugin = {
  heading: &quot;Search Results&quot;,
  containerId: &quot;searchResults&quot;,
  btnCloseLabel: &quot;Close search&quot;,
  btnCloseTooltip: &quot;dismiss search results&quot;,
  btnCloseId: &quot;search_close&quot;,
  btnOpenLabel: &quot;Open all search results&quot;,
  btnOpenTooltip: &quot;Open all search results&quot;,
  btnOpenId: &quot;search_open&quot;,

  displayResults: function(matches, query) {
    story.refreshAllTiddlers(true); // update highlighting within story tiddlers
    var el = document.getElementById(this.containerId);
    query = '&quot;&quot;&quot;' + query + '&quot;&quot;&quot;'; // prevent WikiLinks
    if(el) {
      removeChildren(el);
    } else { //# fallback: use displayArea as parent
      var container = document.getElementById(&quot;displayArea&quot;);
      el = document.createElement(&quot;div&quot;);
      el.id = this.containerId;
      el = container.insertBefore(el, container.firstChild);
    }
    var msg = &quot;!&quot; + this.heading + &quot;\n&quot;;
    if(matches.length &gt; 0) {
        msg += &quot;''&quot; + config.macros.search.successMsg.format([matches.length.toString(), query]) + &quot;:''\n&quot;;
      this.results = [];
      for(var i = 0 ; i &lt; matches.length; i++) {
        this.results.push(matches[i].title);
        msg += &quot;* [[&quot; + matches[i].title + &quot;]]\n&quot;;
      }
    } else {
      msg += &quot;''&quot; + config.macros.search.failureMsg.format([query]) + &quot;''\n&quot;; // XXX: do not use bold here!?
    }
    wikify(msg, el);
    createTiddlyButton(el, &quot;[&quot; + this.btnCloseLabel + &quot;]&quot;, this.btnCloseTooltip, config.extensions.MacronSearchPlugin.closeResults, &quot;button&quot;, this.btnCloseId);
    if(matches.length &gt; 0) { // XXX: redundant!?
      createTiddlyButton(el, &quot;[&quot; + this.btnOpenLabel + &quot;]&quot;, this.btnOpenTooltip, config.extensions.MacronSearchPlugin.openAll, &quot;button&quot;, this.btnOpenId);
    }
  },

  closeResults: function() {
    var el = document.getElementById(config.extensions.MacronSearchPlugin.containerId);
    removeNode(el);
    config.extensions.MacronSearchPlugin.results = null;
    highlightHack = null;
  },

  openAll: function(ev) {
    story.displayTiddlers(null, config.extensions.MacronSearchPlugin.results);
    return false;
  }
};

// override Story.search()
Story.prototype.search = function(text, useCaseSensitive, useRegExp) {
  var macronPattern = /[āĀēĒīĪōŌūŪ]/;
  var s = text;
  // Deal with bold and italics in the middle of words
  s = s.replace(/(.)/g, &quot;['/]*$1&quot;);
  if (!s.match(macronPattern)) {
    // Replace the vowels with the corresponding macron matchers
    s = s.replace(/a/, &quot;[aāĀA]&quot;);
    s = s.replace(/e/, &quot;[eēĒE]&quot;);
    s = s.replace(/i/, &quot;[iīĪI]&quot;);
    s = s.replace(/o/, &quot;[oōŌO]&quot;);
    s = s.replace(/u/, &quot;[uūŪU]&quot;);
  }
  var searchRegexp = new RegExp(s, &quot;img&quot;);
  highlightHack = searchRegexp;
  var matches = store.search(searchRegexp, null, &quot;excludeSearch&quot;);
  config.extensions.MacronSearchPlugin.displayResults(matches, text);
};

// override TiddlyWiki.search() to ignore macrons when searching
TiddlyWiki.prototype.search = function(s, sortField, excludeTag, match) {
    // Find out if the search string s has a macron
    var candidates = this.reverseLookup(&quot;tags&quot;, excludeTag, !!match);
    var matches = [];
    for(var t = 0; t &lt; candidates.length; t++) {
        if (candidates[t].title.search(s) != -1 ||
            candidates[t].text.search(s) != -1) {
            matches.push(candidates[t]);
        }
    }
    return matches;
};

} //# end of &quot;install only once&quot;
</pre>
<p>To add this to your Tiddlywiki, create a new tiddler. Paste in the source code. Give it the <code>systemConfig</code> tag (the case is important). Save and reload your Tiddlywiki file, and it should be available.</p>
<p>It took me maybe 1.5 hours to research possible ways to do it and hack the search plugin together for Tiddlywiki. I&#8217;d never written a plugin for Tiddlywiki before, but I&#8217;ve worked with Javascript, and it was easy to pick up. I had a lot of fun coding it with W-, who supplied plenty of ideas and motivation. =) It&#8217;s fun geeking out!</p>

<p>You can <a href="https://sachachua.com/blog/2011/04/macron-insensitive-search-for-tiddlywiki-and-an-easy-method-for-beginners-in-latin/#comment">view 1 comment</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2011%2F04%2Fmacron-insensitive-search-for-tiddlywiki-and-an-easy-method-for-beginners-in-latin%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Writing macrons in Linux for Latin pronunciation</title>
		<link>https://sachachua.com/blog/2011/04/writing-macrons-linux-latin-pronunciation/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Mon, 25 Apr 2011 12:00:00 GMT</pubDate>
    <category>emacs</category>
<category>geek</category>
<category>learning</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=22212</guid>
		<description><![CDATA[<p>Frustrated with the inability to search the scanned images of the 1822 Latin textbook we&#8217;re using (Albert Harkness&#8217; <a href="http://www.archive.org/details/aneasymethodfor00harkgoog">An Easy Method for Beginners in Latin</a> &#8211; get the PDF, the full-text version is badly OCRed), W- has taken it upon himself to recreate the public-domain textbook as a fully searchable TiddlyWiki (sans illustrations). This meant that he needed to type in a great number of macrons in the words, and <i>that</i> meant finding a better way than copying and pasting from KDE&#8217;s character map. </p>
<p> <a href="http://en.wikipedia.org/wiki/Macron">Macrons</a> turn up in many languages. In Japanese, you use them to indicate that vowels are doubled. 大阪（おおさか）can be romanized as Oosaka or Ōsaka. In Latin, beginner textbooks often use macrons (macra) to indicate pronunciation. (Why do we care about pronunciation for a dead language used mostly in church hymns? W- and I actually want to be able to use this conversationally, at least with each other. After all, if you don&#8217;t use it, you lose it.) </p>
<p> I suggested Emacs. In Emacs, it&#8217;s just a matter of using <code>M-x set-input-method</code> to choose <code>latin-alt-postfix</code>. With that input method, you can add macrons to letters by typing &#8211; after them. For example, typing &#8220;a -&#8221; will result in ā. Not only that, dynamic abbreviations (<code>M-/</code>) make it easier to retype words you&#8217;ve already written before. </p>
<p> W- wouldn&#8217;t hear of using Emacs, being almost as firmly wedded to <code>vi</code> as he is to me. ;) </p>
<p> Instead, we spent some time figuring out how to set up KDE and gvim to make it easier for him to type in macrons. HTML character sequences were out of the question, of course. W- used KDE&#8217;s settings to map his unused Windows key and menu key to compose keys. That made it easier to produce ē, ī, ō, and ū using the key sequence &#8220;Compose + hyphen + vowel&#8221;. However, &#8220;Compose + hyphen + a&#8221; produced ã, not ā. This was probably a bug based on some issue reports we found on the Net, but the suggested fix didn&#8217;t work (<kbd>im-switch -c</kbd> to change to <kbd>default-xim</kbd>). I found a page describing an <code>.XCompose</code> fix, customizing the key sequences. He copied the relevant key sequences from en-US&#8217;s locale settings for Compose in <code>/usr/share/X11</code>, restarted X, and it worked. </p>
<p> Now he&#8217;s off and typing! </p>
<p>  <span class="timestamp-wrapper"> <span class="timestamp">2011-04-24 Sun 23:21</span></span> </p>

<p>You can <a href="https://sachachua.com/blog/2011/04/writing-macrons-linux-latin-pronunciation/#comment">view 12 comments</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2011%2F04%2Fwriting-macrons-linux-latin-pronunciation%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Quid est nōmen tuum? Nōmen meum est &#8220;Sacha&#8221;</title>
		<link>https://sachachua.com/blog/2011/04/quid-est-nomen-tuum-nomen-meum-est-sacha/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Fri, 01 Apr 2011 00:35:00 GMT</pubDate>
    <category>learning</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=22179</guid>
		<description><![CDATA[<p>Latīnum studémus. Monē mē! </p>
<p> The Latin textbooks that W- ordered from the library have arrived, and we&#8217;re slowly making our way through both Wheelock&#8217;s Latin and an online copy of a Latin textbook from the 1880s. Writing is probably going to be painfully slow and ungrammatic for a while, but hey, it&#8217;s worth a try. =) </p>
<p> Why Latin? Geek quirkiness. Secret languages for greater connection. Potential classical education. </p>
<p> It will be interesting. Let&#8217;s see if my blog can handle the characters&hellip; </p>

<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2011%2F04%2Fquid-est-nomen-tuum-nomen-meum-est-sacha%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item>
	</channel>
</rss>