page_pluginmgr(3tcl)
π page_pluginmgr β the page plugin manager π
okay bestie, so this is page_pluginmgr(3tcl), from the Parser generator tools crew, and it's literally the girlboss that runs the whole plugin situation. no cap.
β¨ SYNOPSIS β¨
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 πΈ
so this package is the plugin manager, and it's the literal main character at the center of the page application. it's the one holding the group chat together β managing all the various reader, writer, configuration, and transformation plugins that actually do the work of processing the text (read it, transform it, write it). she's the organizer, she's the vibe coordinator, periodt. π
here's the tea though, bestie: all plugins get loaded into slave interpreters that are specially prepped just for them. and even though they're implemented using packages, they need this special environment and they are NOT usable in a plain interpreter like tclsh. like, they simply will not thrive there. π
because of that, they only get described in general terms over in the PREDEFINED PLUGINS section β they are not documented as regular packages. it's giving "special treatment only." π
and the expectation? every plugin follows the APIs laid out in these sections, depending on what type of plugin it is:
CONFIG PLUGIN APIREADER PLUGIN APIWRITER PLUGIN APITRANSFORM PLUGIN API
no cap β if your plugin doesn't match its API, it's not gonna slay. match the API, know your type, and you're iconic. π
β¨ API β¨
okay bestie, this is the API section, and it's giving everything. Every command, every argument, no skips. Let's get into it π
::page::pluginmgr::reportvia cmd
This command defines the callback command used by ::page::pluginmgr::report (scroll down, it's right there) to report input errors and warnings. The default? It writes those reports straight to the standard error channel. Iconic. π
::page::pluginmgr::report level text ?from ?to??
This is the report command for input errors and warnings. By default, those reports go to standard error. You can change that by setting a user-specific callback command with ::page::pluginmgr::reportvia (see above). The level and text arguments tell you how important the message is and what the message actually says. For allowed level values, check the package logger. The optional from and to arguments 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. Fr fr. π
::page::pluginmgr::log cmd
This defines a log callback command that loaded plugins use for reporting internal errors, warnings, and general information. Pass an empty string as the callback and logging is disabled, periodt. Note: cmd has to be created by the logger package, or 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, retrieves the options encoded in it, and then immediately unloads it again. If name is the path to a file, that file is tried as a plugin first. 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 section CONFIG PLUGIN API for what configuration plugins are supposed 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 a single reader plugin can be loaded. Loading another reader plugin causes the previously loaded reader plugin to be de-initialized and unloaded. See section READER PLUGIN API for the API expected of reader plugins. π¦
::page::pluginmgr::rconfigure dict
Configures the loaded reader plugin. The options and their values come in as a Tcl dictionary. The result is the empty string. π
::page::pluginmgr::rtimeable
Checks if the loaded reader plugin can collect timing statistics. The result is a boolean flag: true if the plugin can be timed, false otherwise. β±οΈ
::page::pluginmgr::rtime
Activates the collection of timing statistics in the loaded reader plugin. Let's get those numbers. π₯
::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. This is 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 results of the plugin 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 the processing of the input.
β οΈ note: the signature says?complete?but the description saysdoneβ we're keeping it exactly as the original, no cap.
::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. (Yes, it says reader even though this is writer β we're just the messenger. π) See section WRITER PLUGIN API for the API expected of writer plugins. βοΈ
::page::pluginmgr::wconfigure dict
Configures the loaded writer plugin. The options and their values come in as a Tcl dictionary. The result is the empty string. π
::page::pluginmgr::wtimeable
Checks if the loaded writer plugin is able to measure execution times. The result is a boolean flag: true if the plugin can be timed, false otherwise. β³
::page::pluginmgr::wtime
Activates the collection of timing statistics in the loaded writer plugin. Go off. β±οΈ
::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. This is expected to be in doctools format. π
::page::pluginmgr::wlabel
Retrieves the human-readable name of the loaded writer plugin. Name drop. π·οΈ
::page::pluginmgr::write chan data
The loaded writer plugin is invoked to generate the output. It is given 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 this order. Multiple transformation plugins can be loaded and are identified by handles. See section TRANSFORM PLUGIN API for the API expected of transformation plugins. π§
::page::pluginmgr::tconfigure id dict
Configures the identified transformation plugin. The options and their values come in as a Tcl dictionary. The result is the empty string. β¨
::page::pluginmgr::ttimeable id
Checks if the identified transformation plugin is able to collect timing statistics. The result is a boolean flag: true if the plugin 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. This is 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
The identified transformation plugin is invoked 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. π
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. Nope, none. π ββοΈ
It is expected that a configuration plugin FOO is implemented by the package page::config::FOO. That's the naming convention, bestie. β¨
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. One and done. π
π READER PLUGIN API π
Reader plugins are the ones that actually read stuff, and they're expected to hand over the following commands, bestie. Here's the whole rundown:
page_rfeaturename β you hand it a feature name and it hands you back a boolean flag saying whether the plugin supports that feature or not. Result has to be true if it's supported, false if it's not. Peep the FEATURES section for the possible features the plugin manager is gonna come asking about. β¨page_rtimeβ calling this one activates the collection of timing statistics. Clock in, queen. β±οΈpage_rgettimeβ this is how you retrieve all those collected timing statistics.page_rlabelβ retrieves a human-readable label for the plugin. A lil name tag, basically. πpage_rhelpβ retrieves a help text for the plugin. Heads up: that text is expected to be in doctools format.page_roptionsβ retrieves the options the plugin understands.page_rconfigureoption value β reconfigures the plugin, specifically the given option gets set to the new value. Glow-up time. πpage_rrunβ this is the main character. It processes the input stream per the current plugin configuration, and the result of the command is the result of the processing.
So reader plugins are also expecting the environment to hand them these special commands:
page_readnum β invoked to read num characters/bytes from the input. Its result has to be those read characters/bytes. πpage_read_doneβ invoked to signal that the plugin has finished processing the input. That's a wrap!page_eofβ invoked to check if the input stream has hit its end. Result has to be a boolean flag: true when the input has reached the end, false otherwise.page_infotext ?from ?to?? β invoked to report some information to the user. It may indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers. πpage_warningtext ?from ?to?? β invoked to report a warning to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.page_errortext ?from ?to?? β invoked to report an error to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers. πpage_log_infotext β invoked to report some internal information.page_log_warningtext β invoked to report an internal warning.page_log_errortext β invoked to report an internal error.
Also, the expectation is that a reader plugin FOO is implemented by the package page::reader::FOO. That's the naming convention, no cap. π«Ά
Reader plugins get loaded by the command ::page::pluginmgr::reader. And listen β at most one reader plugin can be kept in memory. One at a time, bestie, that's the rule. π
β¨ WRITER PLUGIN API β¨
Writer plugins are the ones that spit the output out, and they're expected to provide these commands:
page_wfeatureβ takes a feature name and returns a boolean flag for whether the plugin supports that feature or not. True if supported, false otherwise. Check 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β retrieves a human-readable label for the plugin.page_whelpβ retrieves a help text for the plugin. And yes, that text is expected to be in doctools format.page_woptionsβ retrieves the options understood by the plugin.page_wconfigureoption value β reconfigures the plugin: the given option is set to the new value.page_wrunchan 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. Simple as that. π«
And writer plugins expect the environment to provide these special commands:
page_infotext ?from ?to?? β invoked to report some information to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.page_warningtext ?from ?to?? β invoked to report a warning to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.page_errortext ?from ?to?? β invoked to report an error to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers. πpage_log_infotext β invoked to report some internal information.page_log_warningtext β invoked to report an internal warning.page_log_errortext β invoked to report an internal error.
The vibe is that a writer plugin FOO is implemented by the package page::writer::FOO. Iconic naming, honestly. π
Writer plugins are loaded by the command ::page::pluginmgr::writer. And again β at most one writer plugin can be kept in memory. One. Singular. Periodt. π
πΈ TRANSFORM PLUGIN API page::transform::* πΈ
Transformation plugins are expected to provide the following commands, bestie:
page_tfeatureβ takes a feature name and returns a boolean flag for whether the plugin supports that feature or not. Result has to be true if supported, 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β retrieves a human-readable label for the plugin.page_thelpβ retrieves a help text for the plugin. That text is expected to be in doctools format.page_toptionsβ retrieves the options understood by the plugin.page_tconfigureoption value β reconfigures the plugin: the given option is set to the new value.page_trunchan 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. π₯
And transformation plugins expect the environment to provide these special commands:
page_infotext ?from ?to?? β invoked to report some information to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.page_warningtext ?from ?to?? β invoked to report a warning to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers.page_errortext ?from ?to?? β invoked to report an error to the user. May indicate a location or a range in the input. Each piece of location data, if provided, is a 2-element list containing line and column numbers. πpage_log_infotext β invoked to report some internal information.page_log_warningtext β invoked to report an internal warning.page_log_errortext β invoked to report an internal error.
The expectation here is that a transformation plugin FOO is implemented by the package page::transform::FOO. π¦
Transformation plugins are loaded by the command ::page::pluginmgr::transform. And here's the plot twist that makes transforms so slay: more than one transformation plugin can be kept in memory. The more the merrier, bestie. π
β¨
β¨ PREDEFINED PLUGINS β¨
So here's the tea, bestie: these are the plugins that are already known to the system, aka the ones shipped right in the page module. You don't gotta install anything, they just exist. π
π Configuration
pegβ hands you back a whole set of options for configuring thepageapplication so it can chew through a PEG grammar and spit out ME code. Want the lore? Peep the packagesgrammar_peg,grammar_me, andrelations. π
πΈ Reader
hbβ expects what we call a half-baked PEG container as input and returns the equivalent abstract syntax tree. And where does that container come from? The writer pluginhb, obviously. It's giving teamwork. π«Άlemonβ expects a grammar specification in the format that Richar Hipp's LEMON parser generator understands, and returns an abstract syntax tree for it. πpegβ expects a grammar specification as a parsing expression grammar (PEG, duh) and returns an abstract syntax tree for it. The classic. The blueprint. β¨serβ expects the serialized form of a parsing expression grammar, the kind generated by the packagegrammar::peg, converts it into an equivalent abstract syntax tree, and returns that. Glow-up complete. π¦treeserβ expects the serialized form of a tree, like the one generated by the packagestruct::tree, and returns it β after validation, because we check our work here. β
π Writer
hbβ expects an abstract syntax tree for a parsing expression grammar and writes it out as a half-baked PEG container. This is literally the source of the thing the reader pluginhbeats. Circular queen. πidentityβ takes whatever input you throw at it and writes it out as is. No notes, no changes, just vibes. πmecpuβ expects symbolic assembler code for the MatchEngine CPU (check the packagegrammar::me::cpuand its relatives) and writes it out as Tcl code for a parser. π€meβ expects an abstract syntax tree for a parsing expression grammar and writes it out as Tcl code for the MatchEngine (see the packagegrammar::meand relatives), which then parses input in that grammar. It's giving compiler energy. π₯nullβ takes any input and writes nothing. The logical equivalent of/dev/null. Silent. Mysterious. Iconic. πpegβ expects an abstract syntax tree for a parsing expression grammar and writes it out as a canonical PEG that can be read by the reader pluginpeg. Round trip, slay. πserβ expects an abstract syntax tree for a parsing expression grammar and writes it out as a serialized PEG container that can be read by the reader pluginser. Also a round trip, also slay. πtpcβ expects an abstract syntax tree for a parsing expression grammar and writes it out as Tcl code that initializes a PEG container, as provided by the packagegrammar::peg. π§treeβ takes any serialized tree (per the packagestruct::tree) as input and writes it out in a generic indented format. Nice and tidy, like a made bed. ποΈ
π Transformation
mecpuβ takes an abstract syntax tree for a parsing expression grammar as input, generates symbolic assembler code for the MatchEngine CPU, and returns that as its result (see the packagegrammar::me::cpuand relatives). βοΈreachableβ takes an abstract syntax tree for a parsing expression grammar as input, performs a reachability analysis, and returns the modified and annotated tree. πrealizableβ takes an abstract syntax tree for a parsing expression grammar as input, performs an analysis of realizability, and returns the modified and annotated tree. π§
π FEATURES
Okay so rn the plugin manager only checks plugins for one feature, and that feature is timeable. If a plugin supports it, we assume it can collect timing statistics on request. That's it. That's the whole list. Periodt. β±οΈ
π BUGS, IDEAS, FEEDBACK
Not to be dramatic but this document and the package it describes will undoubtedly contain bugs and other problems. It's software, babe. Please report them in the category page of the Tcllib Trackers:
http://core.tcl.tk/tcllib/reportlist
Also please report any ideas for enhancements you might have for either the package and/or the documentation. We love ideas. We thrive on ideas. π«Ά
When proposing code changes, please provide unified diffs, i.e. the output of diff -u.
Also heads up: attachments are strongly preferred over inlined patches. You can attach stuff by going to the Edit form of the ticket right after you create it, then hitting the left-most button in the secondary navigation bar. Easy. π
π KEYWORDS
pageparser generatortext processing
π CATEGORY
Page Parser Generator
Β©οΈ COPYRIGHT
Copyright (c) 2007 Andreas Kupries <andreas_kupries@users.sourceforge.net>
and that's a wrap on the whole page, bestie ππ you made it to the very end, which is lowkey an achievement because this thing was LONG. this came out of tcllib version 1.0, filed under page_pluginmgr(3tcl) β go forth and manage those plugins, you absolute icon πβ¨
π¦ where this page comes from
- debian trixie: tcllib 2.0+dfsg-4 Β· Tcl
- ubuntu questing: tcllib 2.0+dfsg-4
- ubuntu resolute: tcllib 2.0+dfsg-5 Β· Tcl
- ubuntu stonking: tcllib 2.0+dfsg-6 Β· Tcl
- Copyright (c) 2007 Andreas Kupries <andreas_kupries@users\&.sourceforge\&.net>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms