page_pluginmgr(3tcl)

πŸ“¦
version 2.0 Β· 2 versions
, in debian trixie, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– 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:

  1. CONFIG PLUGIN API
  2. READER PLUGIN API
  3. WRITER PLUGIN API
  4. TRANSFORM 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 says done β€” 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_rfeature name β€” 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_rconfigure option 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_read num β€” 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_info text ?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_warning text ?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_error text ?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_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.

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_wconfigure option value β€” reconfigures the plugin: 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. Simple as that. πŸ’«

And writer 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 a 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 a 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 a 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.

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_tconfigure option value β€” reconfigures the plugin: 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. πŸ”₯

And 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 a 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 a 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 a 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.

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 the page application so it can chew through a PEG grammar and spit out ME code. Want the lore? Peep the packages grammar_peg, grammar_me, and relations. πŸ“–

🌸 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 plugin hb, 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 package grammar::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 package struct::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 plugin hb eats. 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 package grammar::me::cpu and 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 package grammar::me and 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 plugin peg. 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 plugin ser. 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 package grammar::peg. 🧚
  • tree β€” takes any serialized tree (per the package struct::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 package grammar::me::cpu and 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

  • page
  • parser generator
  • text processing

πŸ“‚ CATEGORY

Page Parser Generator


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