Whole document tree
    

Whole document tree

Links-Lua

Links-Lua

Links with Lua extensions

patch 11

Peter Wang


Introduction

What is it

Links-Lua is a fork of the Links web browser thats adds Lua scripting capabilities in order to make Links more flexible and customisable.

It was written by Peter Wang and Cliff Cunnington. Right now we are taking a bit of a break, but if people express interest, development will probably pick up again. Regardless of that, and a couple of bugs, the software is quite usable (and addictive :-), which is why it's being released at this time.

Where to get it

The web site is at http://www.sourceforge.net/projects/links/, and the docs are at http://links.sourceforge.net/links-lua/. You can download patches against official versions of Links, or complete tarballs. One day we might put Links-Lua into CVS, so you can run cvs update to keep up to date. Since the changes we make to Links are quite small, we will keep tracking official Links releases.

UPDATE: An easier option than patching Links manually is to use ELinks (Experimental/Extended Links), available at http://pasky.ji.cz/elinks/. It has more features than regular Links and bugfixes often get into ELinks quicker.

Links can be found at http://links.browser.org.

Lua can be found at http://www.lua.org.

After you have read this manual and played around with the software, you might want to check out Cliff Cunnington's Links-Lua development directory at http://www.ccnet.demon.nl/links-lua/. He's working on an easier configuration system (incomplete), and there's a few more script examples too.

What it runs on

Links-Lua has only been tested under Linux, although it should work under other platforms that Links and Lua support (perhaps with some changes to source code).

Also, note that many of the scripts given here assume a Unix system. Your mileage will definitely vary on other platforms.

Whats new

Patch 11

  • New hook: follow_url_hook
  • New function: current_title
  • An undocumented function edit_bookmark_dialog for the Links-Lua bookmark system (to be generalised at a later date)
  • Added a phony "user:" protocol to help with addons

Patch 10

  • A system-wide configuration file `/etc/links-hooks.lua' will be loaded before the per-user configuration file `~/.links/hooks.lua'
  • The execute function has changed.
  • It is now possible to bind Lua functions to a keystroke, using the bind_key function.

Patch 9

First public release.

Installing

Installing Lua

Before you can compile Links-Lua, you must compile and install Lua. The following instructions are for a Linux system. People on other systems should try to enable popen support, but this is not necessary (you will lose a bit of functionality though).

  1. Download and unpack the Lua `tar.gz' or `zip' somewhere.
  2. cd into the `lua' directory.
  3. Open `config' in a text editor and uncomment the POPEN line.
  4. Optionally, change the INSTALL_ROOT line.
  5. Run make; make so; make sobin; make install. On systems without shared object support, simply run make; make install instead.

Installing Links-Lua

You have two options for installing Links-Lua, the compete tarball or a patch against an official version of Links. In both cases, please check that Lua has been detected on your system during the `configure' step.

From the tarball

tar zxf links-lua-0.96-p11.tar.gz
cd links-lua-0.96-p11
./configure
make
make install            # optional

From a patch

tar zxf links-0.96.tar.gz
cd links-0.96
gzip -dc ~/download/links-lua-0.96-p11.diff.gz | patch -p1
./configure
make
make install            # optional

If you run make install you might overwrite your old copy of Links. It doesn't matter what the filename is called, so you can simply rename one of the copies or keep them in different directories.

Running Links-Lua

Simply start Links as you normally would. To check you have Lua support compiled in, open up the "Help | About" dialog box. It should list "Lua" under "Features". If not, make sure you do not have other copies of Links running, or start Links again with the "-no-connect" option on the command-line.

Using Links-Lua

Out of the box, Links-Lua will do nothing different from regular Links. You need to write some scripts.

Links-Lua additions

Links-Lua is based on the idea of hooks. A hook is a function that gets called at a particular point during the execution of Links. To make Links-Lua do what you want, you can add and edit such hooks.

Links-Lua also adds an extra dialog box, which you can open while in Links with the comma (,) key. Here you can enter Lua expressions for evaluation, or override it to do something different.

And finally, you can bind keystrokes to Lua functions. These keystrokes won't let you do any more than is possible with the Lua Console, but they're more convenient.

Note that this document assumes you have some knowledge of programming in Lua. For that, you should refer to the Lua manual in the Lua distribution.

Config file

On startup, Links-Lua reads in two Lua scripts. Firstly, a system-wide configuration file called `/etc/links-hooks.lua', then a file in your home directory called `~/.links/hooks.lua'. From these files, you can include other Lua files with dofile, if necessary.

To see what kind of things you should put in here, download pwhooks.lua.

Hooks

The following hooks are available.

Hook: goto_url_hook (url, current_url)
This hook is called when the user enters a string into the "Go to URL" dialog box. It is given the string entered, and the current URL (which may be nil). It should return a string, which is the URL that Links should follow, or nil to cancel the operation.

Hook: follow_url_hook (url)
This hook is passed the URL that Links is about to follow. It should return a string (the URL modified or unmodified), or nil to stop Links following the URL.

Hook: pre_format_html_hook (url, html)
This hook gets called just before the final time an HTML document is formatted, i.e. it only gets called once, after the entire document is downloaded. It will be passed the URL and HTML text as strings, and should return the modified HTML text, or nil if there were no modifications.

Hook: lua_console_hook (string)
This hook is passed the string that the user entered into the "Lua Console" dialog box. It should return two values: the type of action to take (`"run"', `"eval"', `"goto-url"' or nil), and a second argument, which is the shell command to run or the Lua expression to evaluate.

Examples:

  • return "run", "someprogram" will attempt to run the program `someprogram'.
  • return "eval", "somefunction(1+2)" will attempt to call the Lua function somefunction with an argument, 3.
  • return "goto-url", "http://www.bogus.com" will ask Links to visit the URL "http://www.bogus.com".
  • return nil will do nothing.

Hook: quit_hook ()
This hook is run just before Links quits. It is useful for cleaning up things, such as temporary files you have created.

Functions

As well as providing hooks, Links-Lua provides some functions in addition to the standard Lua functions.

Function: enable_systems_functions ()
Enable some potentially dangerous functions, as well as some other functions which were unfortunate enough to be lumped in the same group.

The functions are: openfile, closefile, readfrom, writeto, appendto, pipe_read, remove, rename, flush, seek, tmpname, read, write execute, exit, clock, date, getenv, setlocale.

Note: setlocale is a standard Lua function and will not affect the current Links locale.

Function: current_url ()
Returns the URL of the current page being shown (in the Links session that invoked the function).

Function: current_link ()
Returns the URL of the currently selected link, or nil if none is selected.

Function: current_title ()
Returns the title of the current page, or nil if none.

Function: current_document ()
Returns the current document as a string, unformatted.

Function: current_document_formatted ([width])
Returns the current document, formatted for the specified screen width. If the width is not specified, then the document is formatted for the current screen width (i.e. what you see on screen). Note that this function does not guarantee all lines will be shorter than width, just as some lines may be wider than the screen when viewing documents online.

Function: pipe_read (command)
Executes command and reads in all the data from stdout, until there is no more. This is a hack, because for some reason the standard Lua function read seems to crash Links when used in pipe-reading mode.

Function: execute (string)
Executes shell commands string and returns the exit code. Beware that you must not read or write to stdin and stdout. And unlike the standard Lua function of the same name, the return value is meaningless.

Function: bind_key (keymap, keystroke, function)
Currently, keymap must be the string `"main"'. Keystroke is a keystroke as you would write it in the Links config file `~/.links/user.cfg'. The function function should take no arguments, and should return the same values as lua_console_hook.

User protocol

There is one more little thing which Links-Lua adds, which will not be described in detail here. It is the fake "user:" protocol, which can be used when writing your own addons. It allows you to generate web pages containing links to "user://blahblah", which can be intercepted by the follow_url_hook (among other things) to perform unusual actions. For a concrete example, see the bookmark addon.

Example recipes

This chapter contains some example scripts that you can use. All of them come from pwhooks.lua. I really recommend you download it instead of copying code out of this document. Also, not everything in there is covered here.

If you would like to contribute scripts, that would be great! Please send them to me at tjaden@users.sourceforge.net. Cliff and I plan to start a script repository, provided we get some contributions. As for script ideas, you'll just have to be a little creative :-)

Go to URL on steroids

There are some web sites that I visit often. Bookmarks are okay, but they are separate from the "Go to URL" dialog box, so I keep forgetting to use them. Also, when I visit a search engine home page, all I really want to do is enter a search term.

The following script allows me to type certain strings into the "Go to URL" dialog box, and it will convert them to the URL I actually want to visit. As a bonus, it allows me perform some searches on sites like Google without loading up the front page first.


function match (prefix, url)
    return strsub (url, 1, strlen (prefix)) == prefix
end

function strip (str)
    return gsub (str, "^%s*(.-)%s*$", "%1")
end

function plusify (str)
    return gsub (str, "%s", "+")
end

function goto_url_hook (url, current_url)
    -- Google search (e.g. ,gg unix browsers).
    if match (",gg", url) then
        url = plusify (strip (strsub (url, 4)))
        return "http://www.google.com/search?q="..url.."&btnG=Google+Search"
 
    -- Freshmeat search.
    elseif match (",fm", url) then
        url = plusify (strip (strsub (url, 4)))
        return "http://www.freshmeat.net/search/?q="..url

    -- Appwatch search (e.g. ,aw lynx).
    elseif match (",aw", url) then
        url = plusify (strip (strsub (url, 4)))
        return "http://www.appwatch.com/Linux/Users/find?q="..url
    
    -- Dictionary.com search (e.g. ,dict congenial).
    elseif match (",dict", url) then
        url = plusify (strip (strsub (url, 6)))
        return "http://www.dictionary.com/cgi-bin/dict.pl?db=%2A&term="..url

    -- RPM search (e.g. ,rpm links).
    elseif match (",rpm", url) then
        url = plusify (strip (strsub (url, 5)))
        return "http://www.rpmfind.net/linux/rpm2html/search.php?query="
                ..url.."&submit=Search+..."
        
    -- Netcraft.com search (e.g. ,whatis www.google.com).
    elseif match (",whatis", url) then
        url = plusify (strip (strsub (url, 8)))
        return "http://uptime.netcraft.com/up/graph/?host="..url

    -- LinuxToday home page.
    elseif match (",lt", url) then
        return "http://linuxtoday.com/"

    -- Weather forecast for Melbourne, Australia.
    elseif match (",forecast", url) then
        return "http://www.bom.gov.au/cgi-bin/wrap_fwo.pl?IDF02V00.txt"

    -- Unmatched
    else
        return url
    end
end

Expanding ~

By adding an extra snippet of code to the previous example, we can make Links expand pathnames such as `~/foo/bar' and `~user/zappo', like in the shell and other Unix programs.


-- Home directory: If you do not enable system functions, you will need
-- to set the following to your home directory.

home_dir = (getenv and getenv ("HOME")) or "/home/MYSELF"

function goto_url_hook (url, current_url)
                .
                .

    -- Expand ~ to home directories.
    elseif match ("~", url) then
        if strsub(url, 2, 2) == "/" then    -- ~/foo
            return home_dir..strsub(url, 2)
        else                                -- ~foo/bar
            return "/home/"..strsub(url, 2)
        end

                .
                .

Filtering crap

Many web pages nowadays have columns to the left and right of the text, which are utterly useless. If you happen to be viewing the page in a 80x25 screen, the text you want to read ends up crammed into a tiny space in the centre. We use Links-Lua to manipulate the HTML before it reaches the parser.

linuxtoday.com

Linux Today has two problems when viewed in Links: the useless columns on the left and the right and all the text appears in cyan. Here is a quick recipe to fix that:


-- Plain strfind (no metacharacters)
function sstrfind (s, pattern)
    return strfind (s, pattern, 1, 1)
end

function pre_format_html_hook (url, html)
    -- Strip the left and right columns from Linux Today pages
    -- and change the font colour to white.
    if sstrfind (url, "linuxtoday.com") then
        if sstrfind (url, "news_story") then
            html = gsub (html, '<TABLE CELLSPACING="0".-</TABLE>', '', 1)
            html = gsub (html, '<TR BGCOLOR="#FFF.-</TR></TABLE>', '', 1)
        else
            html = gsub (html, 'WIDTH="120">\n<TR.+</TABLE></TD>', '>', 1)
        end
        html = gsub (html, '<A HREF="http://www.internet.com.-', '')
        html = gsub (html, "<IFRAME.-</IFRAME>", "")
        -- emphasis in text is lost
        return gsub (html, 'text="#002244"', 'text="#001133"', 1)
    end

    return nil
end

linuxgames.com

Here is a simpler example, for http://www.linuxgames.com/.


function pre_format_html_hook (url, html)
                .
                .

    elseif strfind (url, "linuxgames.com", 1, 1) then
        return gsub (html, "<CENTER>.-</center>", "", 1)

                .
                .

Reading gzipped files

Sometimes documents come gzipped in order to save space, but then you need to uncompress them to read them with Links. Here is a recipe to handle gzipped files on a Unix system.


-- This script requires system functions.

function pre_format_html_hook (url, html)
                .
                .

    -- Handle gzip'd files within reasonable size.
    if strfind (url, "%.gz$") and strlen (html) < 65536 then
        local tmp = tmpname ()
        writeto (tmp) write (html) writeto ()
        html = pipe_read ("(gzip -dc "..tmp.." || cat "..tmp..") 2>/dev/null")
        remove (tmp)
        return html
    end

                .
                .

Printing

Printing a web page with Links usually involves quite a few steps: Save the current document onto disk. Run it through Links on the command-line (so it fits into 80 columns) to generate a plain text version. Remove the 80th column from the text version, as it will make printers wrap down to the next line. Finally, run the processed file through `lpr', then delete it.

The following functions allow you to print web pages directly from Links, using `lpr' or `enscript'. Type lpr() or enscript() in the Lua Console to run them. (In the `pwhooks.lua', I have also made it so you can just type lpr or enscript.)


-- This script requires system functions.

function catto (output)
    writeto (output)
    write (current_document_formatted (79))
    writeto ()
end

-- Send the current document to `lpr'.
function lpr ()
    -- You must compile Lua with `popen' support for pipes to work.
    -- See `config' in the Lua distribution.
    catto ("|lpr")
end

-- Send the current document to `enscript'.
function enscript ()
    catto ("|enscript -fCourier8")
end

Deferring to Netscape

If you come across a brain-dead web page that is totally unreadable with Links, you'd probably want to open it with a graphical browser. The following function opens the current document in Netscape.


-- This function requires `execute', a system function.

-- When starting Netscape: Set to `nil' if you do not want
-- to open a new window for each document.
netscape_new_window = 1

-- Open current document in Netscape.
function netscape ()
    local new = netscape_new_window and ",new_window" or ""
    execute ("( netscape -remote 'openURL("..current_url ()..new..")'"
             .." || netscape '"..current_url ().."' ) 2>/dev/null &")
end

Alternative bookmark system

Many people would like to have a bookmark system with categories, and also to be able to view them and search for them in an HTML page. I have written an alternative bookmark system (for Links-Lua), which some people may like better than the standard bookmark system.

It is quite a big addon, so is described in a separate document, here: bookmark.html

More ideas

  • Cliff Cunnington had a neat idea of clipping text that you see in web pages (you enter a regexp that will match the start and end of the text you want to clip), and saving the text to disk, along with the URL and timestamp. This would help if you find that you can't ever remember where you had seen a piece of text, or if you want to keep a piece of information but don't need to save the entire page.
  • People who use download management programs could write a function to send the current link to their favourite downloading program.
  • If you wrote a small C program to put text into the X11 selection clipboard, you could pass the current link or URL to that program, to make it easier to paste URLs into other windows. It might be possible to do the same with GPM, or the KDE/GNOME equivalents.
  • Send the current page to Babelfish for translation.
  • Look for stupid JavaScript URLs and convert them to something usable.
  • More things are possible, I'm sure. If you have an idea that requires another hook or function, contact me and I'll see what I can do.

Document history

  • 2001-07-04 Updated for Links-Lua 0.96 patch 11.
  • 2001-05-12 Updated for Links-Lua patch 11.
  • 2001-05-07 Added keystrokes to "Links-Lua additions".
  • 2001-05-05 Updated for Links-Lua patch 10.
  • 2001-04-20 Added Babelfish and JavaScript ideas.
  • 2001-04-19 Added section on "Running Links-Lua", a couple more script ideas, listed the system functions I missed, and some minor things.
  • 2001-04-15 First Links-Lua public release. This document was started a few days before that.


This document was generated on 17 March 2002 using texi2html 1.56k.