Blog

For the English part of the blog, see Content AND Presentation.

2021-06-05 Emacs Lisp book update – what the book is going to look like

About a month ago I decided to write about the book on Emacs Lisp I am writing. I also made it available on Leanpub where you can download the first chapter and pay me to get the (roughly) 40% of the book that is already written.

This post is the first in a series of updates I plan to publish about once per month. Read on if you are curious about the process of writing a book, or want to learn if it is for you, or want to actually help me to write it!

First of all, I’d like to thank all the people who trusted me so far and say that I was surprised and humbled to have so many of you. Now I feel even more encouraged to stick to my writing schedule.

Also, I’d very much appreciate if anyone who actually read any part of the book told me if it was too easy/too difficult/too verbose/too concise etc. Of course, you can’t satisfy everyone, but I have a very specific target in mind when I’m writing: me from about 10 years ago. It was (almost) exactly then when I started learning Emacs Lisp. I read Robert J. Chassell’s An introduction to programming in Emacs Lisp (which is great for beginners, both to programming and Elisp), and had that “what now?” feeling. And now I’m writing a book to help people in a similar situation find their way through the jungle of Elisp. This means that I assume that the readers are intermediate learners. They already know the basics – what let does, what car and cdr are and how lists in Elisp work, what save-excursion is, etc., and now want to be able to do more advanced stuff. There is (of course) some overlap, but I do not repeat a lot of things from Chassell’s book. One of the readers emailed me that my book may be too difficult – if you have an opinion on this, definitely drop me a line! I have tendencies to write long, complicated sentences, and I may gloss over some details obvious to me but not to someone who is closer to the beginning of their journey, so any such feedback might help other readers. (I will obviously reread the book at some point, too – more than once, actually – to flesh out weaker parts etc.)

I’d also like to share my philosophy of writing this book, since I am still not absolutely sure it’s the best one, and it’s not yet too late to make some changes. When I started writing the first drafts (more than 5 years ago), I thought I’d just write whatever I fell like writing and then stitch what I have written together later. Needless to say, this is a very bad approach. (I think I know that better now, having authored or coauthered three other textbooks.)

So the first part of the plan is that I am going to show really useful code instead of some toy examples. Emacs is rather unique in that it actually allows to do useful stuff in half a dozen lines and two functions. This is actually something I did in the first chapter – the first command useful enough to make it sensible to add it to one’s init.el has exactly six lines and uses exactly two built-in functions. It can be made better – in fact, the whole first chapter (which, as I mentioned, is available for free!) is devoted to make it better – but even that first version is fully usable (even if it has some quirks, e.g. interacts strangely with undo).

The focus on useful things has a kind of a drawback, though – it means that instead of introducing concepts in a very orderly way, starting easy and progressing to more advanced ones, I introduce them when they are needed. Of course, the first versions of the commands I show in the book are the simplest ones, and adding features and fixing bad behavior makes them progressively more complex, but it happens a few times that something perceived as “advanced” is introduced before some another, simpler idea. I’d argue that this is actually a good thing – this is how self-teaching programming often works, when you try to solve some real problem and learn along the way. It may, of course, leave strange gaps in your knowledge – you might end up knowing pretty advanced stuff which you happened to need but having no idea about something much simpler which just was never necessary for you – but my hope is that when you gain enough skills and confidence, finding other stuff in the manual and in Emacs sources (not to mention on the internet) will be natural.

Another consequence of my approach is that some parts tend to be long and contain what may look like an endless stream of digressions. In fact, every chapter has a well-defined subject, but it is not some theoretical area of Elisp, but rather a project to complete. Hence there is no chapter or section about “destructive functions” (which are a very important concept not only in Lisp), but I spend a couple of paragraphs explaining their idea (with an example and diagrams) in one of the chapters where I need to construct a list by succesively appending elements to it. (Expectedly, I use the standard idiom of creating a local variable with let, push​ing the elements to it and nreverse​ing it at the end.) There is no section or chapter devoted to interactive declarations, but I introduce different “interactive codes” and also an interactive clause with a list when they are needed. There is no separate section or chapter devoted to ways of finding functions doing things you need (which is extremely important, given how messy Elisp function naming is), but the first chapter is sprinkled with a few tricks helping with that. All this means that my book cannot really be used as a reference material – it is supposed to be read in order, not skipping anything. (More advanced Elisp coders might thus find parts of it boring – but then, the book is definitely not aimed for them. Also, if what you look for is a reference, you should really use the GNU Emacs Lisp Reference Manual.) I might add an index at some point, though. (An alternative would be to make every part devoted to some Elisp construct or idea a separate section, with an entry in the table of contents. That might work, but I just don’t like that idea.)

Ok, that’s enough for today. In the next updates I plan to say more about the actual contents of the book, my writing schedule and the challenges I had when writing the book. Till the next time!

CategoryBlog, CategoryEnglish, CategoryEmacs, CategoryEmacsBook

Comments on this page

2021-05-30 Extending subed-mode

Some time ago I mentioned the subed-mode, Emacs mode for editing srt files with movie subtitles. Well, I’ve been using it regularly for more than half a year now, and I used it to translate more than 20 hours of material into Polish, spending more than 100 hours on it altogether. (And before you ask, this is – again – a hobby/amateur project for my family, not even published.) I think I can safely say that I know quite a bit more about subed-mode now – for instance, I now know that it supports playing the video and actually syncing it to the subtitle at point (with some margins, of course), which is absolutely great.

It had some shortcomings, though. One was that while it supported starting and pausing the video, there was no support for stepping one frame forward or backward. This was a shame, since sometimes it is important to sync the subtitles as precisely as possible to what is happening on the screen. (I also learned in the meantime that srt is not really what professionals use, but I don’t mind that – after all, what I’m doing is just a hobby project.) Another one was that I sometimes needed to use simple formatting (basically, render some part in italics), and typing HTML-like tags manually (which is what the srt format requires) is quite tedious.

However, the thing I missed the most was calculating CPS, or characters per second. It is a well-known fact that translating a text from English to Polish almost always makes it longer. (I remember reading somewhere, many years ago, that a Polish text is on average about 20% longer than its English equivalent. I have no idea where or when I read it – it might as well be before I had any access to the Web – and if that is even true. A quick Google search gave conflicting results. Some people claim that translating from any language to any other tends to make the text longer, which also sounds reasonable – and actually pretty fascinating.) It turns out that the industry standard is 17 CPS for subtitles, with 20 CPS being tolerated in special circumstances, and my subtitles were sometimes even in the 25–30 range! No wonder my dear wife couldn’t keep up – she reads like a normal person, which means much slower than me. (And before you start to be envious – reading fast is a curse as well as a blessing, so to speak, since if I want to read something for pleasure, I sometimes have to put concious effort into reading slower… Also, as a complete side-note, let me also mention that spending more than a decade as a proofreader apparently did some things to my brain. Sometimes I look at a text and perceive a slight discomfort, meaning there’s a typo. Then I have to read it word by word, very slowly and carefully, maybe even twice, to actually find the typo my subconscious noticed in a fraction of a second. This phenomenon both fascinates and terrifies me.)

A careful reader must have noticed that I wrote about the issues with subed-mode in past tense. Well, I did what every programmer would do – I implemented some changes. Most notably, I wrote a CPS-calculating function for subed-mode (which was – expectedly – very easy), and then spent some time writing code to display and update it dynamically while working on the text. That turned out to be a little more difficult than I thought, but I am now happy to say that it works pretty reliably.

Coming back – I submitted a couple of PRs with my changes (CPS display, inserting HTML-like tags and moving by one frame), and after a short back-and-forth (revealing some easy-to-solve bugs or poor keybinding choices) they got accepted and are now included in the master branch if you need these features. Of course, the CPS calculation is the most visible (and cool) one.

your-hair-is-orange.png

If you look carefully and count, you’ll notice that the HTML-ish tags are excluded from the calculation. This feature is not very robust, i.e., it assumes they are correctly formed and don’t contain the “greater-then” sign in their “attribute” part (IOW, it just disregards everything from a < to the next occurrence of a >). Of course, you can turn this behavior off (or supply a better function to strip the tags – see the source for the details).

I have to say that rndusr, the author and maintainer of subed-mode, was very responsive and helpful, and his suggestions concerning the UI made these features much better. Thanks!

Having this, I figured there are more potentially useful things you could so with subed-mode. Probably the coolest one would be to be able to see not only the video, but also a visual rendering of the underlying soundwave, and fit the subtitles to the precise moments people start talking etc. This, however, would be much more work, and not really that much needed for a hobby project like mine, so I decided to postpone this idea until I have much more time. And in fact an even more useful feature would probably be to add support for more formats, like EBU STL, which is apparently the industry standard used by professionals. Yet another great thing would be to have a subtitle linter, detecting common errors, and linking it to flymake (this sounds like something I might be actually tempted to code one day!).

Anyway, if you ever need to edit srt (or vtt) subtitles with Emacs, I am quite proud to say that the experience is now even better:-)!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2021-05-24 Ivy and ignoring the order of tokens

Emacs function naming is strange. I rediscovered that fact a few weeks ago when I tried to find a function giving me the position of the beginning of the current line. I tried to look for a function whose name would match begin.*line, and there was none. I concluded that there is no such function (which was strange, but I learned not to be surprised that often), and proceeded to write my own.

After some time I found out that such a function obviously exists, and that it is called… line-beginning-position. Oh well.

Of course, being who I am, I immediately got an idea to write an apropos-type command which would accept a number of words/tokens separated by spaces, construct a regex matching any string having those “tokens” in any order and feeding it to apropos. Fortunately, I decided to check first if anything like that existed already.

And of course it did. I’ve been using the great Ivy package as my completion engine for a long time now, and from time to time I skim through the manual and find some hidden gems there. This time it was ivy--regex-ignore-order, one of the “completion styles” of Ivy. This “completion style” means that the input of the form begin line will match anything containing both begin and line, in whichever order. Of course, I don’t want every my search to ignore the token order, but searching for Emacs functions and variables should. That’s why I added this to my init.el:

(add-to-list 'ivy-re-builders-alist '(counsel-describe-function . ivy--regex-ignore-order))
(add-to-list 'ivy-re-builders-alist '(counsel-describe-variable . ivy--regex-ignore-order))

(As you might expect, I have also bound C-h f and C-h v to the counsel-... versions, coming from the Counsel package, which defines Ivy-aware counterparts to many Emacs functions and more.)

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

More...