This series is written by a representative of the latter group, which is comprised mostly of what might be called "productivity users" (perhaps "tinkerly productivity users?"). Though my lack of training precludes me from writing code or improving anyone else's, I can, nonetheless, try and figure out creative ways of utilizing open source programs. And again, because of my lack of expertise, though I may be capable of deploying open source programs in creative ways, my modest technical acumen hinders me from utilizing those programs in what may be the most optimal ways. The open-source character, then, of this series, consists in my presentation to the community of open source users and programmers of my own crude and halting attempts at accomplishing computing tasks, in the hope that those who are more knowledgeable than me can offer advice, alternatives, and corrections. The desired end result is the discovery, through a communal process, of optimal and/or alternate ways of accomplishing the sorts of tasks that I and other open source productivity users need to perform.

Friday, March 23, 2012

Addendum to fifth installment: prescience?; more on xmodmap

Prescience?

Ok, grappling with this xmodmap issue has caused me to revisit the issue of inputting non-latin characters under Linux, something I dealt with a few years ago. Finally, with helpful hints gotten in on-line forums and reading various README files, I had some success. I observe now that I displayed a bit of prescience back then as well.

For posterity's sake, I'm pasting here the resolution I came up with--the prescient bit (written almost 8 years ago) highlighted in bold:
. . . I'm taking the other approach I mentioned earlier (editing XF86Config-4 to allow for keyboard map/font switching for X apps).  He's also helped me out with this. . . . there is an additional line possible in the keyboard stanza of XF86Config-4 (this refers to 4.3.0something and may not apply to earlier releases): the XkbVariant" line.  In order to get the phonetic Russian and polytonic layouts (or at least a semblance of polytonic) I want, I've added the "XkbVariant" line with ",phonetic,polytonic" following.  That has gotten me most of the way to where I need to be in entering unicode input into Xapps.  It also works in a console if you have the right fonts installed.  As an additional detail, I should mention that I think you must have a unicode locale specified in your system for this to work.  In my case, I've set locale to en_US.UTF-8 (how to set that varies by distribution: dpkg-reconfigure locales is how Debian does it).  I'll provide the relevant section of my XF86Config-4 for those interested:

Section "InputDevice"
Identifier      "Generic Keyboard"
Driver          "keyboard"
Option          "CoreKeyboard"
Option          "XkbRules"      "xfree86"
Option          "XkbModel"      "pc104"
Option          "XkbLayout" "us,ru,el"
Option          "XkbVariant" ",phonetic,polytonic"
Option          "XKbOptions" "grp:alt_shift_toggle,grp_led:scroll"
EndSection

Note the "grp_led:scroll" segment too, which causes the scroll lock LED on the keyboard to light up when I'm in one of the alternate keyboard/font mappings.  In summary, I've written this in the hope it may help someone else wanting to do this under Linux. . . . my little research/how to project here could likely be itself obsoleted pretty shortly.
Now, as those of you who've been working with GNU/Linux this long will know, we no longer edit GUI configuration files by hand: these are to be auto-generated by the system. But sometimes, for whatever crazy reason, you'll need to do some tricky thing like I was doing then so that you can switch keyboard layouts on the fly.

In current circumstances, for example, my work computer uses a very minimalist desktop that includes no keyboard-layout switching utility/applet--something Gnome, KDE, XFCE4, and the like, do include. So, if I want to implement keyboard-layout switching there, I'm going to need a solution like the one I implemented several years ago.

I suppose it's still possible to hand-edit the GUI configuration file--now called xorg.conf, as we may all know--but that, I believe, is not the canonical method. Instead, what's now expected is that modifications such as the one above be entered into a different configuration file, from whence they get loaded into the xorg.conf file the system automatically generates.

That file is located (on Debian-based systems) in /etc/default and is called, appropriately enough, "keyboard." The content needed to implement the modifications listed above--along with further context from that file--will look as follows:

# If you change any of the following variables and X is configured to
# use this file, then the changes will become visible to X only if udev
# is restarted. You may need to reboot the system.

# The following variables describe your keyboard and can have the same
# values as the XkbModel, XkbLayout, XkbVariant and XkbOptions options
# in /etc/X11/xorg.conf.

XKBMODEL="pc105"
XKBLAYOUT="us,ru,el"
XKBVARIANT=",phonetic,polytonic"
XKBOPTIONS=""ctrl:nocaps,grp:alt_shift_toggle,grp_led:scroll,terminate:ctrl_alt_bksp""

# If you don't want to use the XKB layout on the console, you can
# specify an alternative keymap. Make sure it will be accessible
# before /usr is mounted.
# KMAP=/etc/console-setup/defkeymap.kmap.gz

There's my demonstration of prescience for the year (I hope that doesn't change again within the year). Now, on to a revisitation of the xmodmap issue.

More on xmodmap
Turns out the xmodmap issue is in no way unique to XFCE4: rather, it seems to affect many, and perhaps all, graphical environments. As a moderator from the Arch Linux forums put it almost exactly two years ago, "This is an unsolved problem for quite some time" (see this thread for a bit of further detail).

The symptom on the machine I'm trying this with is that it xmodmap will not initiate when the GUI comes up, despite my attempts at placing commands intended to invoke it in relevant start-up files: xmodmap will only take effect when run manually after the graphical environment is running. Even then, it causes 100% CPU usage for several seconds while it is initiating (this is a pretty low-resource system, at only 800 Mhz, which partly explains the delay).

What is the nature of this problem? Why can't this re-mapping or re-binding be done in connection with the user's log-in and graphical environment's initiation? Does it have something to do with evdev which, as I understand it, is what implements the system's auto-configuration of peripherals like keyboard and mouse? I simply do not understand, unfortunately.

But this matter seems to have foiled greater minds than my own. As a case in point, while trying to resolve this and similar problems, I bumped into the following example in the Xsession man page--which even seemed calculated to address specifically the problem I was trying to resolve:

Here is an example of how one might write a script, named 40custom_load-xmodmap, to invoke xmodmap(1):

SYSMODMAP="/etc/X11/Xmodmap"
USRMODMAP="$HOME/.Xmodmap"

   if [ -x /usr/bin/X11/xmodmap ]; then
      if [ -f "$SYSMODMAP" ]; then
           xmodmap "$SYSMODMAP"
      fi
     fi

    if [ -x /usr/bin/X11/xmodmap ]; then
        if [ -f "$USRMODMAP" ]; then
            xmodmap "$USRMODMAP"
        fi
     fi

Well, I tried that. I created a file with that content, put it in the recommended directory (/etc/X11/Xsession.d) and gave it the same permissions as the other files in that directory. But the xmodmap modifications I'd stipulated were not in effect once the graphical environment came up: I still had to run xmodmap manually.

The only thing approaching a resolution I've found that's calimed to work, is a really ugly looking hack I read about on the Archbang forums (you can read about it here). I haven't tried it yet and so cannot confirm that it works: and I hope to avoid trying it. I really hope there's something a bit less kludgy that'll resolve the issue.

As for things I might attempt, I've thought of entering each of my eight modifications on separate lines in the .xsession or .xinitrc file to see whether that'll cause the modifications to take effect when the user logs in--though that solution isn't much prettier than the one outlined on the Archbang forum. If I did do that, I assume the lines would take the form xmodmap -e “keycode 12 = 3 numbersign 3 numerosign” &. If I try that and it's any more successful, I'll report back about it.

Meantime, I'm still looking for more informed helpers with this issue. Got any insights?

Wednesday, March 7, 2012

Fifth installment: "fun" with xmodmap

In case it's not evident I'll point out at the outset that this entry is facetiously entitled (as the scare quotes might indicate). What I did with xmodmap wasn't exactly fun. Maybe mildly rewarding, finally. But also a bit perturbing.

Why perturbing? Because, after finally discovering a means of accomplishing the goal at which I was aiming, I bumped into what appears to be a long-standing bug that thwarts the resolution about half of the time. I'm still looking for a better resolution but, at least for the time being, I have a mostly workable solution.

Anyway, back to describing the task at hand, which I record here in case it may benefit anyone else and so that the lesson might stick with me longer.

So, I needed to help someone get all needed keys working on a keyboard that would, for the most part, be used for creating non-latin content. For what it's worth, the user will be switching back and forth between English and the non-latin language occasionally.

The target machine has XFCE4 installed as graphical environment. And it happens to be a "new-world Mac" that runs Linux--Debian, to be precise--a factoid which may prove fodder for a future entry. And yes, it's the powerpc architecture, and yes, it has a Mac keyboard (but not a Mac mouse).

XFCE4 has facilities for keyboard switching, which I hoped would make my job a little easier. Its graphical utilities did allow for selection of the needed encoding and layout, so I got a good part of the way using that. The user brought along stickers for the keyboard's keys which could be placed on the appropriate latin-lettered keys so that, being a non-touch-typist, it would be clear which letters should be typed in.

Almost all the letter keys all worked fine under the initial configuration. The problem was that the numerical keys across the top of the keyboard, when shifted, were supposed to be printing certain signs, and the stickers and the actual signs were not matching up. Something like 8 keys were affected. That needed to be fixed.

On looking into what could be done about this state of affairs, xmodmap began to look like it could provide an appropriate solution. So, I dove in. I did get it to work for the most part, though it seems XFCE4 cannot play nicely with xmodmap, so I had to introduce a kludge to be used on certain occasions (see here and here for some dated descriptions of the issues).

It was a bit mind-numbing trying to figure out exactly how to deploy xmodmap, given that I'd never used it before and that I was trying to make it handle two different encodings. The command xmodmap -pke >.Xmodmap-pke proved very helpful, since it created a text file of the current keyboard mapping.

Looking over that output I was able to identify the target keys. Some further reading and experimentation enabled me to find the right syntax to be used for modifying the current mapping.

It seems the canonical way of causing xmodmap to modify the current keyboard mapping is to create a file named .Xmodmap in the user's home directory. The window manager or graphical environment is supposed to read that file on starting and modify the mapping that will be used for those keys within the graphical environment.

For information on how the entries in that file should look, you should, of course, consult the man page--which, in this case, actually contains examples (many man pages, for reasons I as non-programmer can neither fathom nor appreciate, do not).

I did, of course, find helpful information in my web searches as well. The initial red herrings that needed to be sifted out were related to the fact that virtually all pages I found dealing with the matter of re-mapping macintosh keyboards were focused on re-mapping system keys like control, alt, or the "Apple key." I did not find any information dealing with the specific issue I was researching, namely, on re-mapping number keys.

But, as I observed, using xmodmap -pke gave me the data that, once I'd figured out the relevant portions, enabled me to do the required mapping. I needed, for example, the 3 key, when shifted in the non-latin mapping, to produce not the hash or number sign (i.e., #), but something that looks like the following: №. That, as I discovered, is called the numerosign.

Likewise the 7 key, when shifted in the non-latin mapping, needed to produce the question mark. The question-mark/slash key, on the other hand, needed to produce a period and a comma in the non-latin mapping, the latter when shifted.

The output of xmodmap -pke indicated that the 3 key corresponded to what to xmodmap is keycode 12 (xmodmap uses the terms keycodes and keysims to designate the various keys found on the keyboard but I do not claim to understand what is the technical difference between those terms/concepts). The Xmodmap-pke file I had created showed the following line for keycode 12:

12 0x0033 (3) 0x0023 (numbersign) 0x0033 (3) 0x0023 (numbersign)

From looking at other entries in Xmodmap-pke I was able to discern that the second half of the various lines which make up that list referred to the non-latin mappings for this keyboard, while the first half referred to the default, latin, mapping. So 0x0033 (3) 0x0023 (numbersign) is the output the key generates when the latin mapping is in effect, 3 being output when the keyboard is unshifted, and the hash sign being output when it's shifted.

The second half of the line is where my problem lay, then. In its present configuration, the keyboard was mapped to output the same 3 and hash character in the non-latin mapping as it was configured to output in the latin one. So I set about changing that.

I found some helpful samples for testing this at http://mac.linux.be/content/tuning-ubuntu-macintosh-key-mapping-and-3-mouse-button-emulation-0 . Specifically, I discovered that keyboard mapping can be changed sort of on-the-fly from the command line by issuing a command like xmodmap -e “keycode 12 = 3 numbersign 3 numerosign”. Once I did that, the 3 key, when shifted under the non-latin mapping, did, in fact, cause the desired № to appear.

That provides a good way to test the re-mapping to make sure it's working as desired. But if you want the change to be permanent, as I did, you have to construct an .Xmodmap file in your home directory that has all the relevant re-mapping lines in it and which should be read and processed each time the graphical environment starts. Entries in the .Xmodmap,file, by the way, look as follows: keycode 12 = 3 numbersign 3 numerosign. My .Xmodmap file consists in 8 such lines.

Once I had all relevant entries in that file I expected that the mapping modifications would be set and working once the graphical environment had fully loaded. In practice, however, I found that only some of the time was that the case: in many instances I had to open a terminal and type xmodmap .Xmodmap for the re-mapping to go into effect. Further internet searching revealed to me that there is some sort of incompatibility between xmodmap and XFCE4 that causes them to not work together very well. So I created a graphical shortcut that would run xmodmap .Xmodmap when the user clicked on it so as to get the desired mapping to take effect. Not a very pretty solution, but one that works for the time being.

There may be other solutions to this re-mapping issue. The xmodmap solution is one of the first I came across and pursued, so I can't speak to any of the other possible solutions. If you know of some other, possibly more effective one, I'd appreciate hearing about it.

NOTES TO SELF: setxkbmap provides some interesting key re-mapping options as well, a list of which can be found in /usr/share/X11/xkb/rules/base.lst. Another possibility I ran across suggests editing the relevant mapping file in /usr/share/X11/xkb/symbols/, but those files make little sense to me and I'm hesitant to go fiddling with them.

Tuesday, February 21, 2012

Fourth installment: How to write a business letter using TeX/LaTeX

I continue my experiments with TeX/LaTeX. There's just something I like about working with mark-up. I suppose that for most people, the mark-up would hopelessly complicate things. But I find the opposite to be the case for me.

That dates back probably at least as far as the first word processor I used with regularity--WordPerfect (WP hereafter) 4.0. It was also a console application, one that I managed to learn my way around fairly easily. It ran on a 286 with a whopping 20 megabytes of hard drive space and probably not more than 2 megabytes of RAM.

One of the great things about that version of WP was a feature it had called "reveal codes." If some aspect of the document you were working on looked weird and you couldn't correct by selecting various canned options, you could use the "reveal codes" feature to examine the situation behind the scenes. Despite the fact that my computer knowledge was extremely paltry back then, I don't think I ever confronted a situation where, by revealing those codes, I wasn't able to straighten things out.

Skip forward about a year to when I had finally gotten rid of the old computer and was using a "modern" word processor--Word 6.0. Imagine my surprise and dismay when, having issues with documents I was creating with that version of Word, I discovered that the program had no "reveal codes" feature. I was stuck with whatever Word wanted to give me, and that was that (a more technical explanation of the matters at issue can be read here).

So, my interest in TeX/LaTeX perhaps traces, ultimately, to the frustrations I encountered long ago with using more "modern" word processing applications. Whatever the motivations, I continue to experiment--and am now even having modest successes--with TeX/LaTeX.

Recently, I had another opportunity to continue my experimentation with  TeX/LaTeX. I needed to write an official, business-type letter and decided to try writing it with TeX/LaTeX.

I must admit there were also other motivating factors--not least of which was that, since I write so few of these types of letters, I can never remember the proper format and need, each time I write one, to do some web research aimed at refreshing my memory about that prior to composing the letter. TeX/LaTeX could be of assistance here since, I assumed, the letter document class should already be set to output the proper format--which did, indeed, turn out to be the case.

The down side was that it took me an inordinately long time to compose this fairly short letter: but that was, in part, because I wasted a lot of time in a largely fruitless attempt to utilize what was supposed to be a new-and-improved letter class, something called scrlttr2, a component of what is called the "KOMA bundle." Had I just used the old letter document class and not spent so much time trying to get scrlttr2 to do what I wanted, it probably would have taken me about half as long. A long time to write just one letter but, given that it was my first try using this application and that I had some spare time to spend on it, not too bad.

I was successful in the end. Below I'll paste a template for the letter I wrote, one that contains a nice tweak that causes a scanned signature to be printed.

Without further ado, here's the template I used (some explanation below):

\documentclass[12pt]{letter}
\usepackage{fullpage}
\usepackage[english]{babel}
\usepackage{graphicx} %so that signature graphic can be included
%\signature{Name Surname}
\address{My Street \\ My City zip \\ Phone: 555-555-5555 \\ e-mail: me@mydomain.whrvr}
\begin{document}
\begin{letter}{Recipient \\ Recipient's street \\ Recipient's city zip\\ country}
\opening{To whom it may concern:}
This letter is written for the purpose of \ldots

If you have any questions, or would like to see some additional documentation, please do not hesitate to contact me.
\closing{Sincerely,\\
\fromsig{\includegraphics[width=55mm]{Mysig.jpeg}}\\
\fromname{My Name}
}
% \ps{P.S. Here goes your ps.}
% \encl{Enclosures.}
\end{letter}
\end{document}

The first thing I'd like to explain is the use of the graphicx package, which is what allows for the graphic of the signature file to be included. Simply scan your signature and save it as a jpg file (other image formats may work, though jpg is the only one I tested). It will need to be saved within the directory from which you're compiling your letter. Stipulate the size you want for the signature, and pdflatex will include it once you compile.

The other fields in the template should be self-explanatory. I've commented out some of them (the percentage sign is the comment character in TeX/LaTeX), either because they did not apply to the letter I was writing--for example, the PS and enclosure options at the end--or perhaps because it was something that I tried but that didn't have the desired result (the "signature" option in the preamble).

The template should work as is. Just save it as a .tex file, enter your values in place of the generic information, scan your signature and save it to the same directory, then run pdflatex on the .tex file. You should end up with a nicely-formatted business letter.

EDIT: Thanks to those commenters who pointed out the the missing \end{document} tag at the letter's end--not sure how I left that out but it's now been added.

Tuesday, February 14, 2012

Third installment: In praise of newsbeuter

As I've mentioned previously, I'm a T.E.T. (trailing edge technology) type of guy. Rather than chasing after the latest, greatest, electronics must-haves, I'm content to sit on the sidelines watching developments, trying to scheme up ways of getting dated tech to approximate what the new gadgets can do, or sometimes even pouncing on something a bit dated when prices to drop by 50% or more once the novelty's worn off.

That sort of curmudgeonly attitude, augmented by being something of a technological late-bloomer (never touched a computer prior to age 30), it may come as scant surprise that, until fairly recently, I'd done little to nothing involving feed reading. I do recall, when first hearing about RSS, that it seemed like something well-suited to my needs and disposition. But initial attempts at utilizing it did not get very far.

Feed reading seemed attractive to me initially because, given my penchant for T.E.T. and all things low-resource, my preference for things like news reading, which I do a fair amount of, has been, for some years now, largely to use non-graphical applications. What I mean by that is that, when I want to know, via the internet, what's happening in the world at large, I want mostly words, not pictures. And most especially what I don't want when I'm looking for news is advertisements.

Well, advert aversity and my preponderating graphical ambivalence happen to go together quite well with low-resource computing--whether as cause or symptom I don't know. These proclivities led me, for several years, to do most of my news reading under text-mode browsers--primarily links/elinks and friends. I was quite pleased with that arrangement since it obviated a good deal of the bothersome advertising and allowed me to pick and choose which of the more newsworthy graphics I wished to view.

I could, for example, set up links/elinks to use a low-resource program like feh to view the graphics of my choice. That, of course, was in the days when in-line images were the standard for web pages, rather than more modern irritations like java scripts or the even more egregious flash. Should, in those bygone days, any news story hold sufficient graphical interest, I could always copy the URL into a graphical browser and have a gander at the site in its full monty manifestation.

As the web has continued its inexorable march toward chimerical perfection, text-mode browsing--as alluded to above--has become less and less practicable. For some time, one of my primary sources for news was the collection of headlines at the yahoo main page--which used to display quite acceptably in elinks. But yahoo finally sold what remained of its soul to the devil of progress and vaulted itself yet further into the 21st century, updating its main page and thereby causing it to render quite terribly under elinks.

I was adrift for a time news-wise in the wake of the demise of the old yahoo main page. I eventually settled on google news as my news page--once I discovered the proper user-agent incantation; one that would give me the mobile version of the page, containing just a clickable headline along with a line or two from the story. The full version of the page, containing whole opening-paragraphs from the various news stories of the day, was way more news than I was looking for.

But I do like to consult more than one news source each day: for example, I typically look at some Linux news site (Lxer is my preference these days), some boxing headlines, and some MMA news as well. I was ending up with 3 or 4 tabs open in elinks, refreshing each site as I wanted to check for new stories. Which didn't work too badly, by the way.

Recently, though, I decided to have another go at learning about and seeing whether RSS might suit better my news-reading needs. What I ended up discovering was an RSS feed reader that would turn out to scratch, in the most satisfactory way probably humanly possible, the wildest insatiable itch I barely even knew I had (if that statement makes no sense, read on: it might later--though I'm making no guarantees :)). That RSS application was newsbeuter.

Will it come as any surprise if I intimate that newsbeuter is a console program? Probably not. Not only can this application be used from a pseudo-terminal, it can even be used straight from the console! Now that's right up my T.E.T. alley.

"Ok, so what is it?" you ask. Well, it's a terminal application for reading RSS feeds, an application that was developed by an Austrian (as in, fellow countryman of our own American Terminator/Governator) fellow, Andreas Krennmair. The interface, such as it is, quite reminiscent of vi/vim. As he tells us, the name
"Newsbeuter" is a pun on the German word "Wildbeuter", which means "hunter-gatherer". During the stone age, people hunted and gathered their food, and these days, they hunt and gather news and information. Credits for this idea goes to Clifford Wolf, who submitted it to a little competiton that was started when I got aware that the original name would violate French and European registered trademarks.
The screenshot below offers a glimpse at what newsbeuter looks like once it's running:


Each of the entries you see in the screenshot represents an RSS feed. You use the up and down arrows to navigate them, and press the enter key to open the feed, which shows you a list of items or headlines for that feed. Note also the numeral pairs in parentheses, which shows how many items are within that group and how many of those have already been read.

Once you've highlighted one of the items using the up/down arrows and pressed the enter key, you'll be presented by something like what's seen in the screenshot below:


Note the blue bar across the bottom of the window that gives a list of keys that can be pressed and offers a description of what each does.

Again, the up/down arrow keys are used to navigate the headlines, and pressing the enter key on the highlighted headline opens a view that shows the first few lines of the story and that looks as follows (and yes, it's running in a screen session):


Here's where the real magic comes in for us command-line commandos. The application is configured to open the system's default browser for viewing the full story which, on most systems, will be Firefox or some other graphical monstrosity. But newsbeuter offers configuration options that will cause a different, more sane browser to open when the "o" (open) key is pressed, allowing you to view the story in a text-mode browser such as my preferred news reading application, elinks.

To configure newsbeuter to use a more sane text-mode browser, just open (or create, if it's not already on your system) ~/.newsbeuter/config and add the entry html-renderer elinks, and you're all set to read your news stories using elinks. Of course lots of other options can be set within this configuration file--which you can read about at the application's documentation page at http://newsbeuter.org/doc/newsbeuter.html.

Actually, a step that needs to be taken before even the tried-and-true elinks will be of any use to you in reading the news stories linked to, is to configure your feeds. To do that, you open the file ~/.newsbeuter/urls and enter in the URL's of the feeds you wish to monitor. Once that's done, you have a minimal configuration for reading news from RSS feeds with the big boys.

I must confess to being as happy as a clam with this new news-reading scheme--actually, happier. No clam grovelling in the cold mud in the murky depths could ever experience the warmth and satisfaction I've gotten from finding this RSS feed manager, which offers a way to link it up with my favored text-mode browser. So I'm actually happier than a clam--way happier (take that, you smug little bivalve molluscs).

I wish I would have discovered this solution long ago; but part of the reason I didn't was because, simply stated, I'm still very much in learning mode with GNU/Linux system set-up and administration. Had I discovered newsbeuter, say 3 or 4 years ago, I may very well have been unable to puzzle out how to configure and use it.

There are, of course, other command-line RSS feed readers. Perhaps some even work about as well as newsbeuter. I simply haven't looked further yet since what I have looks like it answers to all my needs.

One alternate project that looks interesting is rss2email. I may later have a look at it, but at the moment it's hard for me to imagine what advantages it would have for my purposes over newsbeuter. This entry, from the now--sadly--defunct blog "Motho ke motho ka botho," reviews a few others.

Thus concludes my paean to newsbeuter, the mutt of RSS readers: actually, I used mutt for about a year and gave up on it, going back to Alpine--so I'm more inclined to call it the Alpine of RSS readers. But, whatever.

All hail Andreas Krennmair, command-line RSS manager programmer extraodinaire! He deserves a Nobel prize for command-line RSS feed reader programming! Buy the man a beer in lieu of the Nobel prize he's been stinted if ever you meet him!

Thursday, February 2, 2012

A second addendum to the second installment

I really do have things other than outlining with nano to write about. Really I do. For example, there's the project of installing the Tinycore distribution on some older machines in our computer lab to write about--something I did about a month ago and about which I've already started an article; there's an article about the newsbeuter rss client; one about how to set a weather map as the desktop background; and so forth.  But I've gone on kind of a jag with this nano project lately, and it's complex and foreign enough to me that if I don't record it now, I'm liable to forget important details. So, you're forced to endure another installment on it. :)

What follows may be the last entry on this topic for awhile--we'll see whether any enhancements will be forthcoming soon. If not, I'll probably move on to some of those other important writing projects after this entry. Anyway, on to the topic at hand.

With help from some generous folks over at the linux questions forum, I now have a 3 scripts to share. All the scripts--one written in perl, one in python, and one in awk--add mark-up to the nano outlines I create, mark-up that causes them, once pdflatex has been run on them, to transform into documents that print nicely on paper. I'll paste below the code for each of the three scripts so that, not only will I be less likely to forget how all this works, but also for the possible benefit of others who want to do something similar to what I'm doing. I'll start with the perl script.

The following perl script will add TeX/LaTeX mark-up to the outline files I create with nano. The code can be seen in the following graphic (thanks, blogspot, for making it such a PITA to post code snippets here that I have upload graphic files in order to show them, and sincere thanks to formatmysourcecode for providing the real and effective solution evident below):

#!/usr/bin/perl
# run outl2tex.pl as follows: outl2tex.pl file.outl > file.tex

print <<END
\\documentclass[14pt]{extarticle}
\\usepackage{cjwoutl}
\\usepackage[top=1in,bottom=1in,left=1in,right=1in]{geometry}
\\usepackage{underlin}
\\setlength{\\headsep}{12pt}
\\pagestyle{myheadings}
\\markright{\\today{\\hfill ***Header*title*here***\\hfill}}
\\linespread{1.3} % gives 1.5 line spacing
\\pagestyle{underline}
\\begin{document}
\\begin{outline}[new] 
END
;

while (<>) {
  s/^(\t*)=(.*)/"$1\\outl{".((length $1) + 1)."}$2"/e;
  print;
}

print <<END
\\end{outline}
\\end{document} 
END
;
(the code pasting above was made easy and possible by the source code formatter available at http://formatmysourcecode.blogspot.com/)

As will be obvious, I've named the script outl2tex.pl. As should also be clear, the script is to be run by issuing the command outl2tex.pl name_of_outl_file.outl > name_of_tex_file.tex

The next script--actually scripts--I'll show are the python ones. Why two? Well, it seems python is a rapidly-developing scripting language--something I found out when trying to run the first script that was created for me: it returned an error on my machine. At the same time, it ran fine on the machine of the fellow who created it.

Well, as it turns out, I have version 3.2.2 installed on my machine, while he developed the script on a machine that had version 2.6 on it. So, the following script is the one he originally wrote and that ran on his computer, and one which should work for python version 2.x (he wrote it for 2.6, I ran it successfully with version 2.7, but whether it works for all 2.x versions I cannot say for certain).

#!/usr/bin/python
# for use with versions 2.x of python
# run outl2tex.py as follows: outl2tex.py file.outl > file.tex

import sys
import re

if( len( sys.argv ) != 2 ):
    print >> sys.stderr, "{0} requires one filename to process.".format( sys.argv[0].split('/')[-1] )
    sys.exit( 1)

try:
    rawOutline = open( sys.argv[1], 'r' )
except:
    print >> sys.stderr, "Unable to open {0} for reading".format( sys.argv[1] )
    sys.exit( 2 )

print ( '\\documentclass[14pt]{extarticle}\n'
        '\\usepackage{cjwoutl}\n'
        '\\usepackage[top=1in,bottom=1in,left=1in,right=1in]{geometry}\n'
        '\\usepackage{underlin}
        '\\setlength{\\headsep}{12pt}
        '\\pagestyle{myheadings}\n'
        '\\markright{\\today{\\hfill ***Header*title*here***\\hfill}}\n'
        '\\linespread{1.3} % gives 1.5 line spacing\n'
        '\\pagestyle{underline}
        '\\begin{document}\n'
        '\\begin{outline}[new]\n' )

for inputLine in rawOutline:
    reMatches = re.match( r"(\t*)=(.*)", inputLine )
    if( reMatches == None ):
        print inputLine.rstrip()
    else:
        tabCount = len( reMatches.group(1).split('\t') )
        print "{0}\\outl{{{1:d}}}{2}".format( reMatches.group(1), tabCount, reMatches.group(2) )

print ( '\\end{outline}\n'
        '\\end{document}\n' )

This script is run in essentially the same way as the perl one.

Next, the python 3.x script. As with the 2.x version listed above, I've confirmed that this one runs using version 3.2.2, though I am uncertain whether it can be expected to run under all 3.x versions of python.

#!/usr/bin/python
# for use with versions 3.x of python
# run outl2tex.py as follows: outl2tex.py file.outl > file.tex

import sys
import re

if( len( sys.argv ) != 2 ):
    print ( "{0} requires a filename to process.".format( sys.argv[0].split('/')[-1] ), file=sys.stderr )
    sys.exit( 1 )

try:
    rawOutline = open( sys.argv[1], 'r' )
except:
    print ( "Unable to open {0} for reading".format( sys.argv[1] ), file=sys.stderr )
    sys.exit( 2 )

print ( '\\documentclass[14pt]{extarticle}\n'
        '\\usepackage{cjwoutl}\n'
        '\\usepackage[top=1in,bottom=1in,left=1in,right=1in]{geometry}\n'
        '\\usepackage{underlin}
        '\\setlength{\\headsep}{12pt}
        '\\pagestyle{myheadings}\n'
        '\\markright{\\today{\\hfill ***Header*title*here***\\hfill}}\n'
        '\\linespread{1.3} % gives 1.5 line spacing\n'
        '\\pagestyle{underline}
        '\\begin{document}\n'
        '\\begin{outline}[new]\n' )

for inputLine in rawOutline:
    reMatches = re.match( r"(\t*)=(.*)", inputLine )
    if( reMatches == None ):
        print ( inputLine.rstrip() )
    else:
        tabCount = len( reMatches.group(1).split('\t') )
        print ( "{0}\\outl{{{1:d}}}{2}".format( reMatches.group(1), tabCount, reMatches.group(2) ) )

print ( '\\end{outline}\n'
        '\\end{document}\n' )

Finally, here's the awk script, and it's a long 'un (unfortunately this script is now broken owing to some updates I made to the template file):

#!/usr/bin/awk -f
#
# -v tab=8
#       set tab stops at every eight columns (the default).
#
# -v template=template.tex
#       set the path to the LaTeX template file.
#
# run outl2tex.awk as follows: outl2tex.awk file.outl > file.tex

# Convert tabs to spaces.
function detab(detab_line) {

    if (length(tabsp) != tab) {
    }

    while ((detab_pos = index(detab_line, "\t")) &gt; 0)
        detab_line = substr(detab_line, 1, detab_pos - 1) substr(tabsp, detab_pos % tab) substr(detab_line, detab_pos + 1)

    return detab_line
}

BEGIN {
    # Set tab width to default, unless set on the command line.
    if (tab &lt; 1)
        tab = 8

    # Set template name to default, unless set on the command line.
    if (length(template) &lt; 1)
        template = "template.tex"

    # Record separator is a newline, including trailing whitespace.
    RS = "[\t\v\f ]*(\r\n|\n\r|\r|\n)"

    # Field separator is consecutive whitespace.
    FS = "[\t\v\f ]+"

    # Configuration -- parsed from magic comments.
    split("", config)
    config["tab"] = tab
    config["template"] = template

    # We are not working on anything yet.
    template = ""
    header = ""
    footer = ""
    split("", outline)
    outline[0] = 1
    maxspaces  = 0
    CURR = ""
}

CURR != FILENAME {

    # Empty line?
    if ($0 ~ /^[\t ]*$/)
        next        

    # Configuration comment?
    if ($0 ~ /^%[\t ]*[A-Za-z][0-9A-Za-z]*[\t ]*:/) {
        name = $0
        sub(/^%[\t ]*/, "", name)
        sub(/[\t ]*:.*$/, "", name)
        value = $0
        sub(/^[^:]*:[\t ]*/, "", value)

        # Make the name case-insensitive.
        temp = name
        name = ""
        for (i = 1; i &lt;= length(temp); i++) {
            c = substr(temp, i, 1)
            uc = toupper(c)
            lc = tolower(c)
            if (uc != lc)
                name = name "[" uc lc "]"
            else
                name = name c
        }

        config[name] = value
        next
    }

    # Comment line (skipped)?
    if ($0 ~ /^[\t ]*%/)
        next

    # This is the first line of actual content.
    CURR = FILENAME

    # Set up tabs as currectly specified.
    tab = int(config["tab"])
    tabsp = "                "
    while (length(tabsp) &lt; tab)
        tabsp = tabsp tabsp
    tabsp = substr(tabsp, 1, tab)

    # Have we used a template yet?
    if (length(template) &lt; 1) {
        # No, read it.
        template = config["template"]
        if (length(template) &lt; 1) template = "-"
        OLDRS = RS
        RS = "(\r\n|\n\r|\r|\n)"

        while ((getline line &lt; template) &gt; 0) {
            # Content marker line?
            if (line ~ /^[\t\v\f ]*[Cc][Oo][Nn][Tt][Ee][Nn][Tt][\t\v\f ]*$/)
                break

            # Outline level definition?
            if (line ~ /^%[\t ]*\\outl{/) {
                level = line
                sub(/^[^{]*{/, "", level)
                sub(/}.*$/, "", level)
                level = int(level)

                line = detab(line)
                sub(/\\.*$/, "", line)
                sub(/%/, "", line)
                spaces = length(line)
                outline[spaces] = level
                if (spaces &gt; maxspaces)
                    maxspaces = spaces
                continue
            }

            # Default value definition?
            if (line ~ /^%[\t ]*[A-Z][0-9A-Za-z]*:/) {
                name = line
                sub(/^%[\t ]*/, "", name)
                sub(/[\t ]*:.*$/, "", name)
                value = line
                sub(/^[^:]*:[\t ]*/, "", value)

                # Make the name case-insensitive.
                temp = name
                name = ""
                for (i = 1; i &lt;= length(temp); i++) {
                    c = substr(temp, i, 1)
                    uc = toupper(c)
                    lc = tolower(c)
                    if (uc != lc)
                        name = name "[" uc lc "]"
                    else
                        name = name c
                }

                # If not in config already, set.
                if (!(name in config))
                    config[name] = value
                continue
            }

            # Comment line?
            if (line ~ /^[\t ]*%/)
                continue

            # Ordinary header line. Remove comment.
            sub(/[\t ]%.*$/, "", line)
            header = header line "\n"
        }

        # The rest belongs to footer.
        while ((getline line &lt; template) &gt; 0)
            footer = footer line "\n"

        close(template)
        RS = OLDRS

        # Fill in the outline levels.
        level = outline[0]
        for (spaces = 1; spaces &lt; maxspaces; spaces++)
            if (spaces in outline)
                level = outline[spaces]
            else
                outline[spaces] = level

        # Replace all known ~Name~ in the template.
        for (name in config) {
            gsub("~" name "~", config[name], header)
            gsub("~" name "~", config[name], footer)
        }

        # Replace all other ~Name~ entries in the template with empty strings.
        gsub(/~[A-Z][0-9A-Za-z]*~/, "", header)
        gsub(/~[A-Z][0-9A-Za-z]*~/, "", footer)

        # Emit the template.
        printf("%s", header)
    }
}

/^[\t ]*=/ {
    line = $0
    prefix = index(line, "=") - 1

    # Indentation size in spaces.
    spaces = length(detab(substr(line, 1, prefix)))

    # Find out the outline level for this indentation.
    if (spaces &gt; maxspaces)
        level = outline[maxspaces]
    else
        level = outline[spaces]

    # Add outline level definition.
    line = substr(line, 1, prefix) "\\outl{" level "}" substr(line, prefix + 2)

    printf("%s\n", line)
    next
}

{   printf("%s\n", $0)
}

END {
    printf("%s", footer)
}

As you'll note, this script is quite a bit more complex than the others. It expects, for example, that the TeX template is located in the directory in which the script is run, since it reads values from there (neither the perl nor the python scripts expect such a template file). If it doesn't find the template, it won't process the .outl file.

Furthermore, certain variables can be entered on the command line with this script--unlike the others: the number of spaces that make up a tab space can be fed to it, or an alternate name for the template file--even the title can be set as a command line option using -v title="Title". The title can likewise be entered as a commented line at the top of the outline file after the fashion % Title: A Nice Outline (the percentage sign is how commented lines are to be formed using TeX/LaTeX mark-up).

That about wraps up this second addendum to outlining with nano. The only other addition I can make for the time being is to point out that I've slightly modified the TeX/LaTeX preamble for my outlines, adding in the header, instead of the author's name, mark-up that will print there today's date (\today)--information more apropos for my purposes. See below the slightly modified template:

\documentclass[14pt]{extarticle}
\usepackage{cjwoutl}
\usepackage[top=1in,bottom=1in,left=1in,right=1in]{geometry}
\usepackage{underlin}
\setlength{\headsep}{12pt}
\pagestyle{myheadings}
\markright{\today{\hfill ***Header*title*here***\hfill}}
\linespread{1.3} % gives 1.5 line spacing
\pagestyle{underline} %this along with underlin package give hrule in header
\begin{document}
\begin{outline}[new]
%\outl{1}
%       \outl{2}
%               \outl{3}
%                       \outl{4}
%                               \outl{5}
%                                       \outl{6}
%                                               \outl{7}
%                                                       \outl{8}
%                                                               \outl{9}
%                                                                       \outl{10}
\end{outline}
\end{document} 

I've also altered slightly my .nanorc file so that it includes my preferred "pseudo-bullet"--the equals sign. What that means is that any line that does not begin with the equals sign--regardless of whether it's indented or not--does not get color highlighting applied. Lines that do begin with the equals sign--indented or not--do get color highlighting applied. The relevant section of the updated .nanorc is:

syntax "outl" "\.outl$"
color brightwhite "(^)=.*$"
color brightred "(^[[:blank:]])=.*$"
color brightgreen "(^[[:blank:]]{2})=.*$"
color magenta "(^[[:blank:]]{3})=.*$"
color brightblue "(^[[:blank:]]{4})=.*$"
color brightyellow "(^[[:blank:]]{5})=.*$"
color cyan "(^[[:blank:]]{6})=.*$"
color brightred "(^[[:blank:]]{7})=.*$"
color brightgreen "(^[[:blank:]]{8})=.*$"
color magenta "(^[[:blank:]]{9})=.*$"
color brightblue "(^[[:blank:]]{10})=.*$"

That's pretty much it. The only other modification that might be done involves quotation marks: since TeX/LaTeX expects, not " but `` (double back-ticks) as the opening quotation marks, my files produce the wrong sort of open quotation mark (back-facing instead of front-facing). If one of the above scripts could be modified to detect the opening quotation marks and replace them with the needed double back-ticks, it would make processing of the outline files more complete (ugh, I've just realized I have a similar problem with single quotes or what are sometimes called apostrophes). Otherwise, a search-and-replace will be in order prior to running pdflatex on the converted outlines.

Ya know, come to think of it, working with TeX/LaTeX is a real PITA. The final output is stunning, and no word processor I've ever dealt with comes anywhere close to matching it aesthetically. But it's still a PITA. And that's gonna to have to do it for now.

Monday, January 23, 2012

Addendum to second installment: a TeX/LaTeX template for outlines

As a follow-up to the last installment regarding creating outlines with nano, I've done some further experimentation with LaTeX and wanted to post here a template I created. The template contains the mark-up that, when appropriately applied, can turn a nano outline into one that prints nicely on a page. After running pdflatex on the created file (which should be given a *.tex extension first), a nice pdf can be output for sending to the printer.

Without further ado, the code:
\documentclass[14pt]{extarticle}
\usepackage{cjwoutl}
\usepackage[top=1in,bottom=1in,left=1in,right=1in]{geometry}
\usepackage{underlin}
\setlength{\headsep}{12pt}
\pagestyle{myheadings}
\markright{\today {\hfill ***Header*title*here***\hfill}}
\linespread{1.3} % gives 1.5 line spacing
\pagestyle{underline}
\begin{document}
\begin{outline}[new]
%\outl{1}
%       \outl{2}
%               \outl{3}
%                       \outl{4}
%                               \outl{5}
%                                       \outl{6}
%                                               \outl{7}
%                                                       \outl{8}
%                                                               \outl{9}
%                                                                       \outl{10}
\end{outline}
\end{document}
Now, for a bit of an explanation. I've increased the font size (see the \begin \end{Large} stipulations) due to my deteriorating vision: the standard 10 pt. font used for the document class just is not going to work for me. For the same reason, I needed to increase line spacing (the \linespread stipulation).

Of course the \outl{#} comments indicate the levels of the outline and how far from the left margin the text gets spaced. The spaces in the template are not, of course needed, but I find them to be a visual aid when looking at this mark-up, so I left them in the template.

The key package I'm using, as may be evident to those of you who've learned a bit about TeX/LaTeX, and the one that allows more than four outline levels, is the cjwoutl package. I also wanted to fiddle with page margins, since the default article class margins seem terribly wasteful of paper. So I set them to be one inch all around.

The final printed product looks pretty nice. Truth be told, I'd like to see greater indentation increments for the outline levels, but I think that might actually be tweakable. I'm not up for attempting that at the moment though, since this looks like it should suit my needs fine.

So, what remains to be done is to find some way to apply that code to the outlines I create in nano. For the time being, I'm content to just edit the files manually, adding mark-up where needed. But there is surely a way to automate that task--a way, unfortunately, shrouded in mystery for uninitiated plebians like myself.

What would need to be done first of all is probably to add at least some special marking to the outline file itself. For example, if each outline level entry were to begin with a unique character unlikely to appear anywhere else in the document as the first character in a new line--say, an equals sign--processing the file could probably be simplified. A program could then be written to look for every new line that begins, either with the equals sign, or with one or more tab spaces followed by an equals sign. Depending on the presence of the equals sign at the beginning of new lines, or after one or more spaces from the newline, the program could be told to replace the equals sign with the \outl{#} mark-up, appropriately incremented.

Then, of course, the preamble and ending would need to be added to the file. Finally, the file would need to be saved with a new extension, namely the .tex extension, so that pdflatex could process it.

For better reference, here are some screenshots of the stages of creating this sort of outline using nano. First, some dummy text entered into a test.outl file open in nano:


In the next phase, the mark-up is added and the file is saved with a new extension (note how the color highlighting changes when the file's extension is modified)(LATER EDIT; you may also note that the prepended and appended lines do not match exactly the mark-up from my template--that because I edited those parts slightly, having found a better way to increase font size for the document):


Finally, pdflatex is run on the file that had the mark-up added and its extension changed appropriately. The pdf produced looks like this:


To give some concrete examples, using regular expressions as they are understood by nano, of the way the nano outline file would have to be processed, the following. Every instance of ^= (new line followed by equals sign) should be replaced by ^\outl{1} (new line followed by first-outline-level mark-up). Next, every instance of ^[[:blank:]]= (new line followed by tab space, followed by equals sign) should be replaced by ^[[:blank:]]\outl{2}. And so on for the various outline levels.

Then, the mark-up
\documentclass[14pt]{extarticle}
\usepackage{cjwoutl}
\usepackage[top=1in,bottom=1in,left=1in,right=1in]{geometry}
\usepackage{underlin}
\setlength{\headsep}{12pt}
\pagestyle{myheadings}
\markright{\today{\hfill ***Header*title*here***\hfill}}
\linespread{1.3} % gives 1.5 line spacing
\pagestyle{underline}
\begin{document}
\begin{outline}[new]
should be prepended to the beginning of the file, and
\end{outline}
\end{document}
should be appended to the file's end. Finally, the extension of the file to which all the mark-up has been added should be changed to .tex. After this, the file is ready for processing by pdflatex.

That's how far I've gotten with it to date. Next, I'll be looking for the aid of someone who might be able to give pointers on how the file could be processed as described. I note that Steve Litt's conversion program for making vimoutliner files into something LyX can handle is done using awk. So, perhaps this could be done in the same way. If I discover a way of doing it, I'll post the results in a further addendum to second installment in this series.

NOTE: I made a later edit to the TeX/LaTeX code so that the date, rather than the author's name, appears at the left margin in the header. I also increased the font size for the header title. So the screenshots no longer correspond precisely with the code.

ANOTHER LATER NOTE: here, by the way, is the modified entry from .nanorc that both makes the color highlighting possible, as well as designates the equals sign as a sort of pseudo-bullet (note that levels that do not start with the equals sign do not get color highlighted on this scheme):
syntax "outl" "\.outl$"
color brightwhite "(^)=.*$"
color brightred "(^[[:blank:]])=.*$"
color brightgreen "(^[[:blank:]]{2})=.*$"
color magenta "(^[[:blank:]]{3})=.*$"
color brightblue "(^[[:blank:]]{4})=.*$"
color brightyellow "(^[[:blank:]]{5})=.*$"
color cyan "(^[[:blank:]]{6})=.*$"
color brightred "(^[[:blank:]]{7})=.*$"
color brightgreen "(^[[:blank:]]{8})=.*$"
color magenta "(^[[:blank:]]{9})=.*$"
color brightblue "(^[[:blank:]]{10})=.*$"
color brightyellow "(^[[:blank:]]{11})=.*$"
color cyan "(^[[:blank:]]{12})=.*$"

Wednesday, January 18, 2012

Second installment: Outlining with nano

nano, the old stand-by, low-resource console editor, is probably most often used for quickly editing computer configuration files. It seems also sometimes to be used by programmers for writing programs or editing code. Some of us non-programmers can think of other uses it might serve, such as writing documents or creating outlines. This article will discuss some of the uses I've tried to make of it and some ideas I have for further deploying it.

My history with nano


I'm a long-time user of the nano text editor, it having been from the beginning for me a far more approachable tool for editing configuration and other text files in GNU/Linux than the other popular option, vi. My experiences with nano began in the days when GNU/Linux operating system installations were command-line affairs, and when most initial configuration of the system was done from the terminal. But even after operating system installations developed into a thing of graphical wonder (Knoppix was sort of a trailblazer in this realm, as I recall), I continued to use nano for many tasks owing, not in small part, to the fact that I'm a trailing-edge technologist (read; I re-purpose cast-off or firesale equipment), and so gravitate toward low-resource computing applications.

When I needed to create a very long and complex document a few years ago, I was even hoping at that point that I could learn enough TeX mark-up in order to be able to write most of it using nano. In the end, however, I found myself too intimidated by the prospect of both learning TeX mark-up and planning and executing the complex document, to make the attempt. I chose instead to use a WYSIWYG word processor for the task--but that's another story.

I've since maintained my interest in TeX and LaTeX, and, in the last year or so, actually managed some modest successes with it. Needless to say, I've been using nano right along, and have combined the two in those successful tests. But what got me started thinking about a possible new way of using nano in combination with TeX/LaTeX was actually a tweaked version of vim--vimoutliner with which I was experimenting. And my initial experiments were not TeX/LaTeX related, but were actually focused on finding a text-mode outliner.

vimoutliner


Ok, I know that's a rather convoluted introduction to this story but, hey, life is like that. I all the time stumble onto new and unexpected variations, both in my technical endeavors as well as in other areas of life. So, please bear with me as I recount some of the convolutions, and be comforted by the fact that I'm not rehearsing them all. :)

Now, as a pre-emptive nod to all you emacs lovers out there who are just hopping at the prospect of putting in your pitch for emacs org-mode here, know that I'm aware of and interested in that project. In fact, I already attempted to install it. But once I saw the outrageous size of emacs and associated files, I got cold feet. vim was far smaller, and the vimoutliner package that causes vim to function as a nice outliner doesn't add much beyond that. So, off I went for some experimentation with vimoutliner.

One of the interesting things vimoultiner does is to cause varying outline levels to appear in different colors. For example, the leftmost level will, in a terminal with a dark background, appear in a white font, while the next level--one tab space from the left margin--will be in a red font. The next level--two tab spaces from the left margin--will appear in a green font. And so forth. So, vimoutliner enables vim to use both a particular type of formatting, where tabs at the left margin determine outline levels, as well as applying font coloring to go with those levels.

That's a nice little trick in that the colors allow the eye more readily to distinguish between outline levels--something that, in more ponderous applications such as Libre Office Writer (LOWriter hereafter) is accomplished by both indentation from the margin and the use of varying symbols or letter/number combinations for the differing levels.

Which brings up another factor in my quest for a lightweight outliner: LOWriter's outlining mode is absolutely horrendous. It keeps popping up some tool bar as you move through outline levels, which steals focus from the cursor, forcing you to do a mouse click at the point where you desire to enter text. Not to mention the fact that it's severe overkill to use such a gigantic application for creating an outline.

As I found out from my experimentation with vimoutliner however, both the lightweight and heavyweight applications have their advantages and drawbacks, depending on what is the final goal. And speaking of final goals, this provides occasion for highlighting a wonderful discovery I made with respect to TeX/LaTeX: the author of vimoutliner (Steve Litt) has created a conversion program that turns his outline files into the chapter, section, and sub-section headings of a book to which can then be added all the remaining text. Incidentally, he uses LyX for entering in the additional text.

I created a few outlines using vimoutliner--not for any book publishing projects, my more immediate need being the creation of notes to be used during lecture delivery. Though it did work well for me for the most part, things were still wanting in certain respects when it came to lecture note creation. For example in a text editor like vim (nano has the same shortcoming, you'll doubtless understand) there is no simple way to render something that will render well in printed form, such as WYSIWYG word processors allow and such as is needed for something like lecture notes, that need to be as legible as possible and to contain various visual cues.

vimoutliner
For example, for use in the lecture hall, a larger font might be wanted--perhaps 14-point--and wider line-spacing. The varying symbols WYSIWYG editors can insert at differing outline levels also provide extra visual cues. Certainly page numbering, and perhaps even a header, would be desirable in the final, printed product as well. So, while the coloring vimoutliner provides on-screen for various levels is an aid to creating the outline, when it comes time to print the outline for use from the podium, it falls seriously short.

As a stop-gap measure, I imported the outline files I had made into LOWriter and performed some of the needed manipulations there. Not a very satisfactory solution but one that got me by at the beginning. The real solution to this issue, i.e., to creating from a file that works well on the computer to one that prints well onto a page, is to come up with some sort of conversion program, as Steve Litt did for his book outlines. That task--despite Steve's short-lived but well-intentioned efforts to teach me a little python (I got as far as creating hello.py)--remains at the moment beyond my capabilities.

Can I do something like this with nano?


But I've not given up altogether. One avenue I've begun exploring as a possible resolution to the issues--owing to being once again faced with the prospect of learning simultaneously two new systems (vimoutliner and whatever programming technique I'd need to use in order to convert my outlines)--is whether I might be able to employ my old friend nano in place of the less familiar vim in this scheme somehow. Oh yeah, this article is supposed to be about nano, isn't it?

My initial question was, then, whether I could get nano to function as well on-screen as vimoultiner. Could I make it do the same sort of indentation of levels, and possibly even cause it to assign differing colors to the varying outline levels? Well, that part of the equation turns out to have been quite trivial: with just a couple of simple tweaks to the configuration file .nanorc, nano can be made to do those same outlining features.

Here's how it's done. First, we'll need to locate nano's configuration file, .nanorc, or else create one. To do the latter, you would simply issue from the command line touch ~/.nanorc. That, of course, creates an empty .nanorc file in your home directory.

To invoke the outlining magic, two entries need to be made in that file. The first entry, which causes tabs made at the left margin to create persistent outline levels, is set autoindent. With just this entry in your .nanorc, nano will begin to treat all tabs that start at the left margin as level indentations--meaning that after each wrapped line or each hard return, the cursor returns to that same level on subsequent lines. To get the cursor back to the left margin, it's necessary to use the backspace key or the left arrow key.

The other way to get a .nanorc file in your home directory, or to perhaps create a nano configuration file that obtains system-wide, is to use the sample file found--on my Ubuntu computer--in /usr/share/doc/nano/examples, a file which, with proper editing, can implement nearly any tweak you might want to make to nano. For that file to be valid system-wide, it should, I believe, be renamed to nanorc (no leading period) and copied to the /etc directory.

In that sample file, for example, the line set autoindent is already included and you need only to uncomment it to activate that feature in nano. Likewise, you'll see toward the end of that file that a number of alternate nanorc files can be invoked as well. What are these?

If you inspect those alternate files--on my system located in the /usr/share/nano directory--you may note that they are pre-configured to apply color highlighting to certain types of files. For example, the html.nanorc configuration file stipulates that all files ending in .html, when opened with nano, are to have angle-brackets highlighted in blue, while other elements are to appear in red. This is all accomplished through the agency of regular expressions, which nano identifies as you type and so highlights with the defined colors in real-time.

I've worked a little in the past with regular expressions--mainly when I need to do "power searches" within LOWriter documents. I'm quite far from being conversant with the system, though, and need to consult some sort of documentation each time I want to do something involving regular expressions. Nonetheless, once I had read about these color-highlighting capabilities and understood that they relied on regular expressions, I suspected I might be able to get nano to do something very like the color highlighting vimoutliner does.

I had to experiment for a few hours, all the while trying to find any relevant snippets of information I might dig up on the internet, but I did finally find a way of causing nano to apply color highlighting to the differing levels that can be achieved by placing set autoindent into .nanorc.

That's done by, first of all, defining the extension of files to which the color highlighting should be applied. I decided to define my own extension: all files with the extension .outl should have the color highlighting applied to them. Then, I defined a set of regular expressions which cause color highlighting to apply to varying levels, as follows: white is applied to the first, left-most level; red is applied to the second level; green is applied to the third level; magenta is applied to the fourth level; blue is applied to the fifth level; yellow as applied to the sixth level; cyan is applied to the seventh level; and then the color scheme starts over again with red. I doubt I would ever create and outline that would go beyond seven levels, but it was trivial to add the capability to continue the coloration, so I did it.

Below is the entry I placed in .nanorc that causes the coloration to be applied:

syntax "outl" "\.outl$"
color brightwhite "(^).*$"
color brightred "(^[[:blank:]]).*$"
color brightgreen "(^[[:blank:]]{2}).*$"
color magenta "(^[[:blank:]]{3}).*$"
color brightblue "(^[[:blank:]]{4}).*$"
color brightyellow "(^[[:blank:]]{5}).*$"
color cyan "(^[[:blank:]]{6}).*$"
color brightred "(^[[:blank:]]{7}).*$"
color brightgreen "(^[[:blank:]]{8}).*$"
color magenta "(^[[:blank:]]{9}).*$"
color brightblue "(^[[:blank:]]{10}).*$"
color brightyellow "(^[[:blank:]]{11}).*$"
color cyan "(^[[:blank:]]{12}).*$"

The regular expressions stipulate that, in every file with the extension .outl, each new line that begins with a blank or series of blanks is to have all characters tinted with the appropriate shade to the end of the line. In this form, an outline can have a color-highlighting scheme that goes to thirteen levels. With those fairly simple modifications I was able to cause nano to mimic some of the chief characteristics of vimoutliner.

nano with my highlighting tweak
The difference, at least on the technical level, in how vimoutliner and nano handle the differing levels is not very clear to me. On the surface they differ in that my nano solution seems to treat all white space at the left margin as indicative of an outline level. So, either a space or a tab at the left margin indicates the second outline level, while either two tabs or two spaces indicate the third outline level. I believe there is no regular expression that differentiates a tab from a single space so, at my current level of understanding, it seems what I've come up with is the best possible solution for making nano do outline levels. In vimoutliner, on the other hand, only tabs at the left margin indicate outline levels.

What remains to be done: export outlines as can be done with vimoutliner


As I hinted earlier, however, my ultimate aims have not yet been accomplished. What I've managed to do thus far is to enable a console editor with which I am familiar to apply color highlighting to my outline files. This answers to two important considerations for me: it allows me to 1) utilize an easy-to-use and low-resource application to create outlines that 2) look good on the screen. But it does leave one very important consideration unanswered, namely how to get the created outline into a form that looks good on paper?

That's an issue on which I continue to work and I'm not really even sure where to begin. It seems that converting these outlines into a form that can be handled by LyX or even straight TeX/LaTeX, and from there into a nice printed form, should be possible--as certain vimoutliner add-ons that apparently utilize python for this, indicate. Since my capability with python has not progressed beyond creating hello.py, I'm certainly in no position to attempt to create that sort of converter.

A more congenial place for me to start, since I have slightly more experience with it, would be to use bash somehow. The little I know about it leads me to wonder whether, by bringing to bear something like awk or sed, a sort of search-and-replace could be done on the .outl files in order to add the relevant mark-up to them. But to be honest, I lack even the rudimentary knowledge to know whether bash might even be a viable option for this task.

Another alternative might be to create some macro in LOWriter that could import and apply formatting to these files. I don't have much more experience with macros than I do with bash scripting, though I have become quite familiar over the years with the LOWriter interface and the program's capabilities. Of course TeX/LaTeX printed output looks superior by far to what any office suite can produce. But I would be satisfied with a somewhat aesthetically inferior product for these lecture outlines if I could more readily accomplish the task with LOWriter.

If you have suggestions for any of the issues raised above, please offer them. Specifically, if you know of a way to distinguish, using regular expressions, tabs from spaces, please offer your input. Also, if you know whether the conversion of which I speak might be accomplished using bash and related utilities, please let me know: that would involve essentially searching for end of lines together with tabs/spaces and followed by any character, then replacing those instances with the same end of line, number of tabs/spaces, a TeX/LaTeX mark-up string, then the same character with which the line initially began (incidentally, the mark-up can be found at this site). Likewise, if you have any Libre/Open Office solution for importing these files into a list or outline, please say your piece.