page_pluginmgr(n)

πŸ“¦
version 2.0 Β· 2 versions
, in fedora 43, fedora 44, nixos 26.05, nixpkgs unstable

✨ NAME ✨

Okay so bestie, meet page_pluginmgr(n) β€” the page plugin manager πŸ’–. It's chillin' in the Parser generator tools corner of the manual, and it's the one holding down the whole plugin-manager situation for the page application. No cap.


πŸ¦‹ SYNOPSIS πŸ¦‹

Here's the whole summoning circle, exactly as written. Don't skip a line, because every single one is doing something:

package require page::pluginmgr ?0.3?

package require fileutil

::page::pluginmgr::reportvia cmd

::page::pluginmgr::report level text ?from ?to??

::page::pluginmgr::log cmd

::page::pluginmgr::configuration name

::page::pluginmgr::reader name

::page::pluginmgr::rconfigure dict

::page::pluginmgr::rtimeable

::page::pluginmgr::rtime

::page::pluginmgr::rgettime

::page::pluginmgr::rhelp

::page::pluginmgr::rlabel

::page::pluginmgr::read read eof ?complete?

read num

eof

done

::page::pluginmgr::writer name

::page::pluginmgr::wconfigure dict

::page::pluginmgr::wtimeable

::page::pluginmgr::wtime

::page::pluginmgr::wgettime

::page::pluginmgr::whelp

::page::pluginmgr::wlabel

::page::pluginmgr::write chan data

::page::pluginmgr::transform name

::page::pluginmgr::tconfigure id dict

::page::pluginmgr::ttimeable id

::page::pluginmgr::ttime id

::page::pluginmgr::tgettime id

::page::pluginmgr::thelp id

::page::pluginmgr::tlabel id

::page::pluginmgr::transform_do id data

page_cdefinition

page_rfeature name

page_rtime

page_rgettime

page_rlabel

page_rhelp

page_roptions

page_rconfigure option value

page_rrun

page_read num

page_read_done

page_eof

page_info text ?from ?to??

page_warning text ?from ?to??

page_error text ?from ?to??

page_log_info text

page_log_warning text

page_log_error text

page_wfeature

page_wtime

page_wgettime

page_wlabel

page_whelp

page_woptions

page_wconfigure option value

page_wrun chan data

page_info text ?from ?to??

page_warning text ?from ?to??

page_error text ?from ?to??

page_log_info text

page_log_warning text

page_log_error text

page_tfeature

page_ttime

page_tgettime

page_tlabel

page_thelp

page_toptions

page_tconfigure option value

page_trun chan data

page_info text ?from ?to??

page_warning text ?from ?to??

page_error text ?from ?to??

page_log_info text

page_log_warning text

page_log_error text

πŸ’… DESCRIPTION πŸ’…

Okay so this package? It's literally the plugin manager at the center of the page application πŸ‘‘. It manages all the various reader, writer, configuration, and transformation plugins that actually process the text β€” you know, the read, transform, and write of it all. Main character energy fr fr.

All plugins get loaded into slave interpreters that are specially prepared just for them ✨. And yes, they're implemented using packages, but they need this special environment, so they are not usable in a plain interpreter, like tclsh. That's the whole catch. Because of that, they're only described in general terms in the PREDEFINED PLUGINS section, and they are not documented as regular packages. The expectation is that they follow the APIs specified in these sections:

  • [1] CONFIG PLUGIN API
  • [2] READER PLUGIN API
  • [3] WRITER PLUGIN API
  • [4] TRANSFORM PLUGIN API

...as per their type, bestie. Periodt. πŸ’…

✨ API ✨

okay so here's the whole API, every command, no skips. you're gonna eat this up πŸ’–

  • ::page::pluginmgr::reportvia cmd β€” this command defines the callback command that ::page::pluginmgr::report (scroll down bestie) uses to report input errors and warnings. the default is to write those reports straight to the standard error channel. periodt.
  • ::page::pluginmgr::report level text ?from ?to?? β€” this is the one that reports input errors and warnings. by default it writes them to standard error. you can change that by setting a user-specific callback command with ::page::pluginmgr::reportvia (see above, queen).

the arguments level and text tell you how important the message is and what the message actually says. for the allowed values of level, go check the package logger.

the optional from and to args let the caller point at the location (or range) in the input where the reported problem occurred. each one is a list with two elements: the line and the column in the input, in that order.

  • ::page::pluginmgr::log cmd β€” this defines a log callback command that loaded plugins use to report internal errors, warnings, and general info. if you set the callback to the empty string, logging gets disabled. note: the cmd has to be created by the logger package, or at least follow the same API as one. the command returns the empty string as its result.
  • ::page::pluginmgr::configuration name β€” this loads the named configuration plugin, grabs the options encoded in it, then immediately unloads it again. if name is a path to a file, then that file gets tried as a plugin first, and if that fails, it's opened and its contents are read as a list of options and their arguments, separated by spaces, tabs and newlines, possibly quoted with single and double quotes. see the CONFIG PLUGIN API section for what configuration plugins are expected to do. the result is the list of options retrieved.
  • ::page::pluginmgr::reader name β€” loads the named reader plugin and initializes it. the result is a list of options the plugin understands. only one reader plugin can be loaded at a time. loading another one causes the previously loaded reader plugin to be de-initialized and unloaded. see the READER PLUGIN API section for the API expected of reader plugins.
  • ::page::pluginmgr::rconfigure dict β€” configures the loaded reader plugin. options and their values come in as a Tcl dictionary. result is the empty string.
  • ::page::pluginmgr::rtimeable β€” checks if the loaded reader plugin can collect timing statistics. result is a boolean flag: true if it can be timed, false otherwise.
  • ::page::pluginmgr::rtime β€” activates the collection of timing statistics in the loaded reader plugin.
  • ::page::pluginmgr::rgettime β€” retrieves the collected timing statistics of the loaded reader plugin after it was executed.
  • ::page::pluginmgr::rhelp β€” retrieves the help string of the loaded reader plugin. it's expected to be in doctools format.
  • ::page::pluginmgr::rlabel β€” retrieves the human-readable name of the loaded reader plugin.
  • ::page::pluginmgr::read read eof ?complete? β€” invokes the loaded reader plugin to process the input, and returns the plugin's results as its own result. the input is accessible through the callback commands read and eof. the optional done can be used to intercept when the plugin has completed its processing. all arguments are command prefixes. the plugin will invoke the various callbacks in these situations:
    • read num β€” invoked whenever input to process is needed, with the number of characters/bytes it asks for. the result is expected to be the input the plugin is in need of.
    • eof β€” invoked by the plugin to check if the input has reached the end of the stream. the result is expected to be a boolean flag: true when the input has hit EOF, false otherwise.
    • done β€” invoked when the plugin has completed processing the input.
  • ::page::pluginmgr::writer name β€” loads the named writer plugin and initializes it. the result is a list of options the plugin understands. only a single reader plugin can be loaded. loading another reader plugin causes the previously loaded reader plugin to be de-initialized and unloaded. see the WRITER PLUGIN API section for the API expected of writer plugins.
bestie, yes that says "reader" under the writer command. that's literally what the original says, so I'm keeping it. no cap. 😭
  • ::page::pluginmgr::wconfigure dict β€” configures the loaded writer plugin. options and their values come in as a Tcl dictionary. result is the empty string.
  • ::page::pluginmgr::wtimeable β€” checks if the loaded writer plugin can measure execution times. result is a boolean flag: true if it can be timed, false otherwise.
  • ::page::pluginmgr::wtime β€” activates the collection of timing statistics in the loaded writer plugin.
  • ::page::pluginmgr::wgettime β€” retrieves the collected timing statistics of the loaded writer plugin after it was executed.
  • ::page::pluginmgr::whelp β€” retrieves the help string of the loaded writer plugin. expected to be in doctools format.
  • ::page::pluginmgr::wlabel β€” retrieves the human-readable name of the loaded writer plugin.
  • ::page::pluginmgr::write chan data β€” invokes the loaded writer plugin to generate the output. it gets the data to generate the output from, and the Tcl handle chan of the channel to write the generated output to. the command returns the empty string as its result.
  • ::page::pluginmgr::transform name β€” loads the named transformation plugin and initializes it. the result is a 2-element list containing the plugin id and a list of options the plugin understands, in that order. multiple transformation plugins can be loaded and are identified by handles. see the TRANSFORM PLUGIN API section for the API expected of transformation plugins.
  • ::page::pluginmgr::tconfigure id dict β€” configures the identified transformation plugin. options and their values come in as a Tcl dictionary. result is the empty string.
  • ::page::pluginmgr::ttimeable id β€” checks if the identified transformation plugin can collect timing statistics. result is a boolean flag: true if it can be timed, false otherwise.
  • ::page::pluginmgr::ttime id β€” activates the collection of timing statistics in the identified transformation plugin.
  • ::page::pluginmgr::tgettime id β€” retrieves the collected timing statistics of the identified transformation plugin after it was executed.
  • ::page::pluginmgr::thelp id β€” retrieves the help string of the identified transformation plugin. expected to be in doctools format.
  • ::page::pluginmgr::tlabel id β€” retrieves the human-readable name of the identified transformation plugin.
  • ::page::pluginmgr::transform_do id data β€” invokes the identified transformation plugin to process the specified data. the result of the plugin is returned as the result of the command.

πŸŽ€ CONFIG PLUGIN API πŸŽ€

configuration plugins are expected to provide a single command, described below. slay.

  • page_cdefinition β€” this command of a configuration plugin is called by the plugin manager to execute it. its result has to be a list of options and values to process.

configuration plugins do not expect the environment to provide any special commands.

it's expected that a configuration plugin FOO is implemented by the package page::config::FOO.

configuration plugins are loaded, executed, and unloaded in one step. they are not kept in memory. the command for doing this is ::page::pluginmgr::configuration.

πŸ¦‹ READER PLUGIN API πŸ¦‹

Okay bestie, if you're building a reader plugin, here's the whole vibe: it's expected to hand over these commands, and we're gonna walk through every single one because we don't skip. πŸ’…

  • page_rfeature name β€” you pass in a feature name and it returns a boolean flag saying whether the plugin supports that feature or not, periodt. The result has to be true if it's supported, and false if it isn't. That's the whole assignment.
Peep the FEATURES section for the actual list of features the plugin manager is gonna come asking about. πŸ‘€
  • page_rtime β€” invoked to activate the collection of timing statistics. Stats girlies rise up. ✨
  • page_rgettime β€” invoked to retrieve the collected timing statistics. Get those numbers back.
  • page_rlabel β€” invoked to retrieve a human-readable label for the plugin. Something cute for the people. πŸŽ€
  • page_rhelp β€” invoked to retrieve a help text for the plugin. Heads up: that text is expected to be in doctools format.
  • page_roptions β€” invoked to retrieve the options understood by the plugin.
  • page_rconfigure option value β€” invoked to reconfigure the plugin. Specifically: the given option gets set to the new value. Glow-up moment. πŸ’–
  • page_rrun β€” invoked to process the input stream according to the plugin's current configuration. And the result of the command is the result of the processing. No cap.

Reader plugins also expect the environment to have their back with these special commands, okay? Like the environment is the bestie that shows up with snacks. 🫢

  • page_read num β€” invoked to read num characters/bytes from the input. Its result has to be the read characters/bytes.
  • page_read_done β€” invoked to signal that the plugin has completed processing the input. You did it, congrats. πŸŽ‰
  • page_eof β€” invoked to check if the input stream has reached its end. Its result has to be a boolean flag: true when the input has reached the end, false otherwise.
  • page_info text ?from ?to?? β€” invoked to report some information to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_warning text ?from ?to?? β€” invoked to report a warning to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_error text ?from ?to?? β€” invoked to report an error to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_log_info text β€” invoked to report some internal information.
  • page_log_warning text β€” invoked to report an internal warning.
  • page_log_error text β€” invoked to report an internal error.

So here's the tea: a reader plugin named FOO is expected to be implemented by the package page::reader::FOO. Cute, right? 😌

And reader plugins get loaded by the command ::page::pluginmgr::reader. Key detail: at most one reader plugin can be kept in memory at a time. One. Singular. πŸ’€


πŸ’œ WRITER PLUGIN API πŸ’œ

Now for the writer girlies β€” writer plugins are expected to provide these commands, described below. Same energy, different letter. Let's go. 🌈

  • page_wfeature β€” this command takes a feature name and returns a boolean flag indicating whether the feature is supported by the plugin, or not. The result has to be true if the feature is supported, and false otherwise.
Again, see the FEATURES section for the possible features the plugin manager will ask for. πŸ”₯
  • page_wtime β€” invoked to activate the collection of timing statistics.
  • page_wgettime β€” invoked to retrieve the collected timing statistics.
  • page_wlabel β€” invoked to retrieve a human-readable label for the plugin.
  • page_whelp β€” invoked to retrieve a help text for the plugin. The text is expected to be in doctools format.
  • page_woptions β€” invoked to retrieve the options understood by the plugin.
  • page_wconfigure option value β€” invoked to reconfigure the plugin. Specifically: the given option is set to the new value.
  • page_wrun chan data β€” invoked to process the specified data and write it to the output stream chan. That chan is a Tcl channel handle opened for writing. The result of the command is the empty string. 🫧

Writer plugins expect the environment to provide these special commands too:

  • page_info text ?from ?to?? β€” invoked to report some information to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_warning text ?from ?to?? β€” invoked to report a warning to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_error text ?from ?to?? β€” invoked to report an error to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_log_info text β€” invoked to report some internal information.
  • page_log_warning text β€” invoked to report an internal warning.
  • page_log_error text β€” invoked to report an internal error.

A writer plugin named FOO is expected to be implemented by the package page::writer::FOO. Iconic naming convention, honestly. πŸ‘‘

Writer plugins are loaded by the command ::page::pluginmgr::writer. And once again: at most one writer plugin can be kept in memory. Just the one. πŸ™ˆ


✨ TRANSFORM PLUGIN API page::transform::* ✨

Transformation plugins β€” the glow-up girlies of the pipeline β€” are expected to provide these commands, described below.

  • page_tfeature β€” this command takes a feature name and returns a boolean flag indicating whether the feature is supported by the plugin, or not. The result has to be true if the feature is supported, and false otherwise.
See the FEATURES section for the possible features the plugin manager will ask for. ⭐
  • page_ttime β€” invoked to activate the collection of timing statistics.
  • page_tgettime β€” invoked to retrieve the collected timing statistics.
  • page_tlabel β€” invoked to retrieve a human-readable label for the plugin.
  • page_thelp β€” invoked to retrieve a help text for the plugin. The text is expected to be in doctools format.
  • page_toptions β€” invoked to retrieve the options understood by the plugin.
  • page_tconfigure option value β€” invoked to reconfigure the plugin. Specifically: the given option is set to the new value.
  • page_trun chan data β€” invoked to process the specified data and write it to the output stream chan. That chan is a Tcl channel handle opened for writing. The result of the command is the empty string. 🧚

Transformation plugins expect the environment to provide these special commands:

  • page_info text ?from ?to?? β€” invoked to report some information to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_warning text ?from ?to?? β€” invoked to report a warning to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_error text ?from ?to?? β€” invoked to report an error to the user. May indicate a location or range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.
  • page_log_info text β€” invoked to report some internal information.
  • page_log_warning text β€” invoked to report an internal warning.
  • page_log_error text β€” invoked to report an internal error.

A transformation plugin named FOO is expected to be implemented by the package page::transform::FOO. Consistent queen behavior. πŸ’…

Transformation plugins are loaded by the command ::page::pluginmgr::transform. And here's the fun part β€” unlike the reader and writer girlies, more than one transformation plugin can be kept in memory. Plural. Stack 'em up. 🌸

✨ PREDEFINED PLUGINS ✨

okay so these are the plugins that ship with the box, like they're already there, provided by the page module itself, no extra setup bestie πŸŽ€


Configuration πŸ› οΈ

  • peg β€” hands you back a whole set of options that configure the page application for chewing through a PEG grammar and spitting out ME code. If you wanna know the lore, go peek at the packages grammar_peg, grammar_me and relations πŸ‘‘

Reader πŸ“–

  • hb β€” expects a so-called half-baked PEG container as input and gives you back the equivalent abstract syntax tree. The writer plugin hb is the one that makes this kind of input, iykyk πŸ¦‹
  • lemon β€” expects a grammar spec like the one Richar Hipp's LEMON parser generator understands, and returns an abstract syntax tree for it πŸ‹
  • peg β€” expects a grammar spec written as a parsing expression grammar (PEG) and returns an abstract syntax tree for it πŸ’…
  • ser β€” expects the serialized form of a parsing expression grammar (the kind the package grammar::peg generates) as input, converts it into an equivalent abstract syntax tree, and returns that ✨
  • treeser β€” expects the serialized form of a tree (the kind the package struct::tree generates) as input, validates it, and returns it 🌸

Writer ✍️

  • hb β€” expects an abstract syntax tree for a parsing expression grammar as input and writes it out as a so-called half-baked PEG container 🫢
  • identity β€” takes literally any input and writes it out exactly as is. no thoughts, head empty, just vibes πŸ’€
  • mecpu β€” expects symbolic assembler code for the MatchEngine CPU (see the package grammar::me::cpu and relatives) and writes it out as Tcl code for a parser πŸ”₯
  • me β€” expects an abstract syntax tree for a parsing expression grammar as input and writes it out as Tcl code for the MatchEngine (see the package grammar::me and relatives) which then parses input in that grammar πŸ‘‘
  • null β€” takes any input and writes nothing. the logical equivalent of /dev/null, iconic behaviour honestly πŸ™ˆ
  • peg β€” expects an abstract syntax tree for a parsing expression grammar as input and writes it out as a canonical PEG that the reader plugin peg can read right back 🌈
  • ser β€” expects an abstract syntax tree for a parsing expression grammar as input and writes it out as a serialized PEG container that the reader plugin ser can read right back πŸ’œ
  • tpc β€” expects an abstract syntax tree for a parsing expression grammar as input and writes it out as Tcl code that initializes a PEG container, the kind the package grammar::peg provides ⭐
  • tree β€” takes any serialized tree (per package struct::tree) as input and writes it out in a generic indented format πŸŽ€

Transformation πŸ”„

  • mecpu β€” takes an abstract syntax tree for a parsing expression grammer as input, generates symbolic assembler code for the MatchEngine CPU, and returns that as its result (see the package grammar::me::cpu and relatives) πŸ”₯
  • reachable β€” takes an abstract syntax tree for a parsing expression grammer as input, runs a reachability analysis, and returns the modified and annotated tree πŸ¦‹
  • realizable β€” takes an abstract syntax tree for a parsing expression grammer as input, runs an analysis of realizability, and returns the modified and annotated tree ✨

πŸ’« FEATURES πŸ’«

as of right now, the plugin manager only ever checks plugins for one single feature, and that feature is timeable. a plugin that supports it is assumed to be able to collect timing statistics whenever you ask for them ⏱️


😭 BUGS, IDEAS, FEEDBACK 😭

ngl bestie, this document β€” and the package it describes β€” will undoubtedly contain bugs and other problems. please report them in the category page of the Tcllib Trackers at http://core.tcl.tk/tcllib/reportlist. and please also drop any ideas you have for enhancements to either the package and/or the documentation, we want them fr fr 🫢

when you're proposing code changes, please give unified diffs, i.e. the output of diff -u πŸ’…

also, heads up: attachments are strongly preferred over inlined patches. to attach something, go to the Edit form of the ticket immediately after it's created, and then use the left-most button in the secondary navigation bar πŸ‘‘

πŸ”‘ KEYWORDS πŸ”‘

page, parser generator, text processing


πŸ—‚οΈ CATEGORY πŸ—‚οΈ

Page Parser Generator


Copyright (c) 2007 Andreas Kupries <andreas_kupries@users.sourceforge.net>


and that's the whole thing, bestie, we made it to the end πŸŽ‰ this beauty lives in tcllib, version 1.0, and it's the page_pluginmgr(n) page β€” go forth and manage those plugins, you absolute main character πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from