diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-04 23:15:06 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-04 23:15:06 +0200 |
commit | 59e6f1ed73bb414c983944982db67d47c36876ce (patch) | |
tree | 4ce4090691430052892146e367e541d10306b892 /res/about/help.gmi | |
parent | 82e9eed2f9362313f5e8e46c6fc7088500a79c1d (diff) |
Updated release notes and Help
Documentation for MIME hooks.
Diffstat (limited to 'res/about/help.gmi')
-rw-r--r-- | res/about/help.gmi | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/res/about/help.gmi b/res/about/help.gmi index 3f21adb8..af534c2e 100644 --- a/res/about/help.gmi +++ b/res/about/help.gmi | |||
@@ -315,12 +315,99 @@ Other Unix : ~/.config/lagrange/ | |||
315 | 315 | ||
316 | * bindings.txt | 316 | * bindings.txt |
317 | * bookmarks.txt | 317 | * bookmarks.txt |
318 | * feeds.txt | ||
318 | * idents.binary and idents/ | 319 | * idents.binary and idents/ |
320 | * mimehooks.txt | ||
319 | * prefs.cfg | 321 | * prefs.cfg |
320 | * state.binary | 322 | * state.binary |
321 | * trusted.txt | 323 | * trusted.txt |
322 | * visited.txt | 324 | * visited.txt |
323 | 325 | ||
326 | # MIME hooks | ||
327 | |||
328 | MIME hooks enable piping Gemini responses through external programs for arbitrary processing. This allows leveraging scripting languages and binary executables to perform format conversions, content transformation, and data analysis. | ||
329 | |||
330 | Hooks are configured using the file "mimehooks.txt" in Lagrange's config directory. Each hook has a regexp that is matched against the response MIME type and parameters, and each matching hook is offered the response body via stdin. The called external programs are free to rewrite the entire response, including the MIME type. If one of the hooks returns a valid response, it is used as the final response of the Gemini request. | ||
331 | |||
332 | Example use cases: | ||
333 | * Parsing an Atom XML feed and generating a Gemini feed index page | ||
334 | * Rendering a MIDI file using Timidity as PCM WAV | ||
335 | * Generate a graph PNG based on values in a CSV | ||
336 | * Converting HTML or Markdown to 'text/gemini' | ||
337 | * Language translations | ||
338 | |||
339 | ## Interface | ||
340 | |||
341 | When a hook is called, it is given the MIME type and parameters via command line arguments. The response body is provided via stdin. | ||
342 | |||
343 | The MIME type and parameters are split at semicolons, so "text/gemini; lang=ja" would be called as: | ||
344 | ``` | ||
345 | hookprogram text/gemini lang=ja | ||
346 | ``` | ||
347 | |||
348 | Output from the program (via stdout) must be a valid "20" Gemini response that includes the new MIME type: | ||
349 | ``` | ||
350 | 20 text/gemini; lang=en\r\n | ||
351 | {...body...} | ||
352 | ``` | ||
353 | |||
354 | Any output that does not follow this format is considered to mean that the hook refused to process the contents. The next hook will be offered the response instead. | ||
355 | |||
356 | ## mimehooks.txt syntax | ||
357 | |||
358 | Like other Lagrange configuration lines, mimehooks.txt has a simple line-oriented syntax. Lagrange must be restarted for changes to the configuration file to take effect. | ||
359 | |||
360 | Each hook is specified as three lines: | ||
361 | * A human-readable label (for reporting to the user) | ||
362 | * MIME type/parameter regular expression | ||
363 | * Command to execute, plus additional arguments each separated with semicolons | ||
364 | |||
365 | For example: | ||
366 | ``` | ||
367 | Convert Atom to Gemini feed | ||
368 | application/xml | ||
369 | /usr/bin/python3;/home/jaakko/atomconv.py | ||
370 | ``` | ||
371 | |||
372 | The hook program is executed directly without involving the shell. This means scripts must be invoked via the interpreter executable. | ||
373 | |||
374 | ## Example: Converting from Atom to Gemini | ||
375 | |||
376 | The following simple Python script demonstrates how a MIME hook could be used to parse an Atom XML document using Python 3 and output a Gemini feed index page based on the parsed entries. This is just a simple example; a more robust script could include more content from the Atom feed and handle errors, too. | ||
377 | ``` | ||
378 | import sys | ||
379 | import xml.etree.ElementTree as ET | ||
380 | |||
381 | def atomtag(n): | ||
382 | return '{http://www.w3.org/2005/Atom}' + n | ||
383 | |||
384 | root = ET.fromstring(sys.stdin.read()) | ||
385 | if root.tag != atomtag('feed'): | ||
386 | sys.exit(0) | ||
387 | feed_title = '' | ||
388 | feed_author = '' | ||
389 | feed_entries = [] | ||
390 | for child in root: | ||
391 | if child.tag == atomtag('title'): | ||
392 | feed_title = child.text | ||
393 | elif child.tag == atomtag('entry'): | ||
394 | feed_entries.append(child) | ||
395 | print("20 text/gemini\r") | ||
396 | print(f'# {feed_title}') | ||
397 | for entry in feed_entries: | ||
398 | entry_date = '' | ||
399 | entry_title = '' | ||
400 | entry_link = '' | ||
401 | for child in entry: | ||
402 | if child.tag == atomtag('updated'): | ||
403 | entry_date = child.text[:10] | ||
404 | elif child.tag == atomtag('title'): | ||
405 | entry_title = child.text | ||
406 | elif child.tag == atomtag('link'): | ||
407 | entry_link = child.attrib['href'] | ||
408 | print(f'=> {entry_link} {entry_date} {entry_title}') | ||
409 | ``` | ||
410 | |||
324 | # Open source licenses | 411 | # Open source licenses |
325 | 412 | ||
326 | => about:license | 413 | => about:license |