{"id":17442418,"url":"https://github.com/clark800/stp","last_synced_at":"2025-10-20T00:48:09.669Z","repository":{"id":197516532,"uuid":"635994917","full_name":"clark800/stp","owner":"clark800","description":"minimalist extensible templating static site generator in 100 lines of POSIX shell","archived":false,"fork":false,"pushed_at":"2024-12-29T20:39:59.000Z","size":202,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-26T04:02:56.632Z","etag":null,"topics":["posix","posix-sh","posix-shell","shell","shell-script","shellscript","static-site","static-site-generator","template-engine","template-processor"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clark800.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-03T22:54:23.000Z","updated_at":"2024-12-29T20:40:03.000Z","dependencies_parsed_at":"2023-11-19T09:28:18.073Z","dependency_job_id":"764fcc63-1f8e-4285-9175-20405dc5cd8a","html_url":"https://github.com/clark800/stp","commit_stats":{"total_commits":358,"total_committers":1,"mean_commits":358.0,"dds":0.0,"last_synced_commit":"fd682f4a46442ae37cd3a680ad7dbdb19d9c580e"},"previous_names":["clark800/stp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/clark800/stp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clark800%2Fstp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clark800%2Fstp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clark800%2Fstp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clark800%2Fstp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clark800","download_url":"https://codeload.github.com/clark800/stp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clark800%2Fstp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279960226,"owners_count":26251358,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-19T02:00:07.647Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["posix","posix-sh","posix-shell","shell","shell-script","shellscript","static-site","static-site-generator","template-engine","template-processor"],"created_at":"2024-10-17T16:06:00.251Z","updated_at":"2025-10-20T00:48:09.625Z","avatar_url":"https://github.com/clark800.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"stp\n===\n\n`stp` (shell template processor) is an extensible static site generator and generic template processor in 100 lines of POSIX shell. Plugins for automatic generation of navigation links, index files, etc are another couple hundred lines.\n\nSummary of features:\n* Dynamic template engine based on shell command substitution (no new syntax)\n* Recursive template instantiation\n* Supports both source templates (e.g. markdown) and target templates (e.g. html)\n* Extensible with plugins for template functions and generators\n* Supports any combination of input formats and output formats\n* The default configuration generates semantic HTML5 with classless CSS and no Javascript from a directory of markdown files\n\n\nQuick Start\n-----------\nIf you have a directory of markdown files, this will generate an HTML page for each markdown file in the same directory as the markdown file.\n\n1. Install the [smd](https://github.com/clark800/smd) markdown renderer.\n2. In the `stp` directory, run `./make`\n3. `sudo ./make install`\n4. `cp -r stp/config \u003cyour-markdown-directory\u003e/.stp`\n5. `cd \u003cyour-markdown-directory\u003e`\n6. `stp`\n\nIf you want to use another markdown processor you can replace `smd` in the `md.to.html` template.\n\nYou can add `=` annotations to markdown files if you want index files to show dates:\n\n```\nTitle\n=====\n= published: 2023-09-30\n= tags: blog\n\nMain content\n```\n\nAnother option is manually writing `index.md` files which provides more flexibility and doesn't require `=` annotations.\n\n\nHow it works\n------------\nThe main idea of `stp` is to use shell command substitution and parameter expansion to instantiate templates. It does this by automatically escaping double quotes and backticks in the input, then `eval`ing a `printf` with the input placed inside shell script double quotes. The actual instantiation code is one line:\n\n```shell\neval \"printf '%s\\\\n' \\\"$(sed 's/\\\\*\\([\"`]\\)/\\\\\\1/g' \"$path\")\\\"\"\n```\n\nThis is a simplified markdown to HTML template:\n\n```html\n\u003chtml\u003e\n\u003chead\u003e\n\u003cmeta name=\"generator\" content=\"stp:$GENERATOR\"\u003e\n\u003ctitle\u003e$TITLE\u003c/title\u003e\n\u003clink rel=\"stylesheet\" href=\"/.stp/styles/default.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\u003cheader\u003e\n$(breadcrumb)\n\u003c/header\u003e\n$(input | smd)\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nInstantiation will substitute the value of the shell variables for `GENERATOR` and `TITLE`, and run the code in the `$()` brackets, substituting the output into the template. The `input` function prints the contents of the current source file being processed, which is then stripped of metadata annotations with `grep`, then processed with the `smd` markdown processor to fill in the main content.\n\n\nRecursive templates\n-------------------\nTemplates can recursively instantiate other templates, which allows you to extract common parts like headers and footers. The above template could be refactored to:\n\n```html\n$(instantiate header.html)\n$(input | smd)\n$(instantiate footer.html)\n```\n\nNow the `header` and `footer` templates can be reused in other templates.\n\n\nPlugins\n-------\nAny `.sh` shell script you place in the `.stp/plugins` directory will be automatically imported when you run `stp` and any functions imported from plugins will be available in all templates.\n\nTo avoid conflicts between plugins, each plugin should only define one top-level function and the name should be the same as the filename without the `.sh` extension. Additional functions can be defined nested inside the top-level function starting with an underscore, which ensures they don't interfere with any top-level functions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclark800%2Fstp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclark800%2Fstp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclark800%2Fstp/lists"}