PM Module¶
The top-level PM module is the primary interface. All public methods are class methods on PM.
Parsing¶
PM.parse(source) → Parsed¶
Parse a file or string and return a PM::Parsed object.
Parameters:
| Name | Type | Description |
|---|---|---|
source |
String, Symbol, Pathname | File path (.md extension or Pathname), Symbol, single word, or raw string |
Returns: PM::Parsed (Struct with metadata and content)
Behavior:
- If
sourceis a Symbol or a single word (letters, digits, underscores only),.mdis appended and it is treated as a file basename - If
sourceis a Pathname, responds toto_path, or is a String ending in.md, it is treated as a file path - File paths are resolved relative to
PM.config.prompts_dir(unless absolute) - File parsing adds
directory,name,created_at,modified_atto metadata - Processing pipeline: strip comments → extract YAML → shell expansion
# File
parsed = PM.parse('review.md')
# Symbol or single word (basename — .md appended)
parsed = PM.parse(:review) #=> parses review.md
parsed = PM.parse('review') #=> parses review.md
# String
parsed = PM.parse("---\ntitle: Hello\n---\nContent")
PM.parse_string(string) → Parsed¶
Parse a string directly through the processing pipeline, bypassing all file-detection logic. Unlike PM.parse, single words are never treated as prompt IDs.
Parameters:
| Name | Type | Description |
|---|---|---|
string |
String | Raw string content to parse |
Returns: PM::Parsed (Struct with metadata and content)
Behavior:
- Always parses the input as string content — never looks up files
- Runs the same pipeline as
PM.parse: strip comments → extract YAML → shell expansion - Does not add
directory,name,created_at, ormodified_atto metadata
# Single words are parsed as content, not treated as file basenames
parsed = PM.parse_string('hello')
parsed.content #=> "hello"
# Strings with YAML front-matter work as expected
parsed = PM.parse_string("---\ntitle: Hello\n---\nContent")
parsed.metadata.title #=> "Hello"
parsed.content #=> "Content\n"
When to use parse_string instead of parse:
PM.parse('summarize') #=> looks for summarize.md
PM.parse_string('summarize') #=> parses "summarize" as content
Configuration¶
PM.config → Configuration¶
Returns the singleton PM::Configuration instance.
PM.configure { |config| } → Configuration¶
Yields the configuration instance for block-style configuration.
PM.configure do |config|
config.prompts_dir = '~/.prompts'
config.shell = true
config.erb = true
end
Utilities¶
PM.strip_comments(string) → String¶
Remove all HTML comments (<!-- ... -->) from the string, including multiline.
PM.expand_shell(string) → String¶
Expand shell references in the string.
$VARand${VAR}→ environment variable value (empty string if unset)$(command)→ command stdout (trailing newline stripped)
Only UPPERCASE variable names are expanded.
Raises: RuntimeError if a command exits with non-zero status.
Directives¶
PM.register(*names, &block) → nil¶
Register one or more named directives available in ERB templates. Multiple names register the same block under each name (aliases).
Parameters:
| Name | Type | Description |
|---|---|---|
*names |
Symbols, Strings | One or more directive names |
block |
Proc | Receives RenderContext as first arg, then user args |
Raises: RuntimeError if any name is already registered.
PM.register(:env) { |_ctx, key| ENV.fetch(key, '') }
PM.register(:webpage, :website, :web) { |_ctx, url| fetch_page(url) }
PM.directives → Hash¶
Returns the current directive registry.
PM.reset_directives! → nil¶
Remove all custom directives and re-register only the built-in include directive.