{"id":27437289,"url":"https://github.com/brewingcode/pug-pack","last_synced_at":"2025-04-14T20:19:56.306Z","repository":{"id":38984503,"uuid":"104175191","full_name":"brewingcode/pug-pack","owner":"brewingcode","description":"Static site generator for developers who like clean formatting, plus a handful of CLI tools using Pug and/or CoffeeScript.","archived":false,"fork":false,"pushed_at":"2024-06-10T23:56:18.000Z","size":4198,"stargazers_count":16,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T07:41:33.889Z","etag":null,"topics":["cli","coffeescript","css","javascript","pug","static-site-generator","stylus"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brewingcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2017-09-20T06:29:31.000Z","updated_at":"2025-01-09T09:12:10.000Z","dependencies_parsed_at":"2024-06-11T01:51:40.429Z","dependency_job_id":"89ff0809-0394-4729-bf74-1291c4647236","html_url":"https://github.com/brewingcode/pug-pack","commit_stats":{"total_commits":356,"total_committers":1,"mean_commits":356.0,"dds":0.0,"last_synced_commit":"1fc0e631024bdf21585b424f54334166a1f63192"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brewingcode%2Fpug-pack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brewingcode%2Fpug-pack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brewingcode%2Fpug-pack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brewingcode%2Fpug-pack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brewingcode","download_url":"https://codeload.github.com/brewingcode/pug-pack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248812163,"owners_count":21165378,"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","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":["cli","coffeescript","css","javascript","pug","static-site-generator","stylus"],"created_at":"2025-04-14T20:19:55.092Z","updated_at":"2025-04-14T20:19:56.274Z","avatar_url":"https://github.com/brewingcode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pug-pack\n\n\u003e Static site generator for developers who like clean formatting, plus a handful\nof CLI tools that wrap client-side javascript and/or\n[pug.js](https://github.com/pugjs/pug).\n\n```sh\nnpm install -g pug-pack\npug-pack --init\n```\n\nor for running locally:\n\n```sh\ngit clone github.com/brewingcode/pug-pack\ncd pug-pack\nnpm install\nnpm run build\nnpm link\n```\n\n`pug-pack` takes all the `.pug` templates in your `src` directory, and renders\neach one as an `.html` file in a `dist` directory. A custom `:inject()` filter\nallows you to easily inline other assets (scripts, CSS, images) into the\n`.html` files. Cleanly-formatted languages\n([.pug](https://pugjs.org/api/getting-started.html),\n[.coffee](http://coffeescript.org/), [.styl](http://stylus-lang.com/), and\n[.yml](http://www.yaml.org/start.html)) are supported, but you can fall back\non files from the last 30 years if you have to.\n\nYou can see some examples by compiling the `test` directory of this repo:\n\n```sh\ncd pug-pack\nnpx pug-pack -w test\nopen dist/index.html\n```\n\nThere are a couple other examples:\n\n```\nopen dist/hyper.html\nopen dist/vue-chart.html\nopen dist/bgg.html\n```\n\n# Pug files\n\nThe main files in `src` are your `.pug` files: these will each end up in\nthe `dist` directory at the exact path they are at, relative to `src`:\n\n    src/index.pug       --\u003e dist/index.html\n    src/foo/bar/baz.pug --\u003e dist/foo/bar/baz.html\n\nEach `.pug` file is compiled with content generated from all the _other_\nnon-pug asset files in the `src` directory, such as scripts, styles, and\nimages. These assets are included in Pug templates via:\n\n* custom `:inject()` filter\n\n* `src` template variable\n\nSee [`non-pug files`](#non-pug-files) for more details, or some examples in\n[test/index.pug](test/index.pug) and [test/hyper.pug](test/hyper.pug). The\n`:inject()` filter is the main workhorse, and it can either:\n\n* read an asset file and inline it as an HTML element\n\n* transform inlined content in the template into plain HTML content\n\n* injected content can be asyncronously generated, which is not possible with\nstandard `pug`\n\n**NOTE:**\n\nThe `:inject(file=\"...\")` pug filter will read file relative to your `src`\ndirectory, NOT relative to the .pug file the filter is in\n\n```pug\nhtml\n  head\n    // this will create a \u003cstyle\u003e tag with Bootstrap's CSS\n    :inject(file=\"bootstrap.css\")\n\n    // this will also create a \u003cstyle\u003e tag, but with the inline Stylus\n    // transpiled to CSS\n    :inject(ext=\"styl\")\n      .current-time\n        color: red\n\n  body\n    .container-fluid\n      p The current time is\n        span.current-time\n\n    // this will create a \u003cscript\u003e tag with JQuery's code\n    :inject(file=\"jquery.js\")\n\n    // and another \u003cscript\u003e with Moment.js's code\n    :inject(file=\"moment.js\")\n\n    // one more \u003cscript\u003e, transpiled with CoffeeScript into plain JavaScript\n    :inject(ext=\"coffee\")\n      $('.current-time').text moment()\n```\n\n# Non-pug files\n\nThe following file types are supported: `.coffee`, `.styl`, `.yml`, `.js`,\n`.css`, `.svg`, `.html`, and `.json`. Most of these are simple transforms of\ntext-to-text:\n\n```pug\n:inject(file=\"jquery.js\")\n:inject(ext=\"coffee\")\n  $('body').text \"Hello from CoffeeScript, it is #{new Date()}\"\n```\n\nHowever, some of these file types are converted into objects. These require a\nlittle care:\n\n### `.yml` and `.json`\n\nThese files are simply converted to objects, which you can use via the `src`\ntemplate variable in your Pug templates. Each file is accessed via it's\nrelative path from the `src` directory:\n\n```yml\n# src/people.yml\n123:\n  name: Spongebob Squarepants\n  location: a pineapple under the sea\n456:\n  name: Elon Musk\n  location: Ne Syrtis, Mars\n```\n\n```pug\n// src/index.pug\nul\n  each val,key in src[\"people.yml\"]\n    li #{val.name} lives in #{val.city} and their SSN is #{key}\n```\n\nNote that `src` also has _all_ the asset files, not just the `.yml` and\n`.json` files. You can use Pug's `!{...}` interpolation to include these\nassets directly, if you have a good reason to. For example, you declare the\ndata in a `.yml` file as a client-side JavaScript variable and use it:\n\n```pug\n:inject(file=\"jquery.js\")\nscript.\n  var people = !{JSON.stringify(src['people.yml'])};\n  Object.keys(people).forEach(function(ssn) {\n    var name = people[ssn].name;\n    var city = people[ssn].city;\n    $('ul').append('\u003cli\u003e' + city + ' is where ' + name + 'lives!\u003c/li\u003e');\n  });\n```\n\n### `.svg`\n\nSVG files are more complicated, because they can either be inlined into a\n`\u003cstyle\u003e` tag, or they can be used \"raw\", ie embeded straight into HTML as an\n`\u003csvg\u003e` element.\n\n```pug\n// creates a \"raw\" \u003csvg\u003e element with a CSS class of \"github-svg\"\n:inject(file=\"github.svg\")\n\n// creates a \u003cstyle\u003e element that declares the \"github-svg\" CSS class\n:inject(file=\"github.svg\" css)\n```\n\nNote the `css` attribute passed to the `:inject` filter: this is required to\ntell the filter to produce CSS instead of SVG. See\n[test/index.pug](test/index.pug) to see both uses of `:inject()` with an\n`.svg` file.\n\n### extras\n\nThe `src` object also gets two additional properties:\n\n* `GIT_HEAD`: the short git sha of the `src` HEAD\n\n* `GIT_TAGS`: any tags that refer to `GIT_HEAD`\n\n# Options for `pug-pack`\n\n`pug-pack` will compile the assets in its own `src` directory first, and then\ncompile your own `src` files. Any file naming collisions will override the\nfiles from `pug-pack` in favor of your version, so if you have\n`src/bootstrap.css`, that is the Bootstrap CSS that will be used.\n\nYou can override the `src` and `dist` directories, and/or pass other options,\nsuch as:\n\n* `--production`/`-p` will minify everything as much as possible\n\n* `--watch`/`w` will use `browser-sync` to watch `src` and re-run your build\non every change\n\n* `--clean`/`-c` will remove the output directory first\n\n* `--verbose`/`-v` for more verbose output\n\n* `--list`/`-l` will list all files involved in the build\n\n* `--init`/`-i` will initialize `pug-pack` in the current directory:\n\n  - add a \"dev\" and \"build\" run-script to package.json\n\n  - write a bare-bones `src/index.pug` file, as per the quickstart above\n\nSee `pug-pack --help` for more, or see the CLI [here](bin/cli.coffee).\n\n# Node API for `pug-pack`\n\nYou can `require('pug-pack')` yourself, if you really want to. The two main\nmethods are:\n\n* `.self()` will process the assets in `pug-pack`'s own `src` directory (there\nare no public `.pug` files in this directory, only .pug files prefixed with `_`\nto denote they are skipped for compilation to .html)\n\n* `.crawl(rootDir)` will process the assets in `rootDir`, which should include\none or more `.pug` files\n\nSee the [CLI](bin/cli.coffee) as an example.\n\n# `include` and `extend` keywords in Pug\n\nIf you would rather use these pug built-ins, see `pugs` below: it exposes the\n`pug-pack/src` directory via pug's own `--basedir` option, so that you can\nwrite:\n\n```pug\nextend /_base  \u003c!-- NOTE: the leading slash tells pug to use \"absolute\" paths,\n               starting at --basedir --\u003e\n\nappend head\n  title Your Cool Page\n```\n\nIf you don't want to use `pugs`, just specify the full path to `pug-pack/src`\nwhen you use `include` and `extend`.\n\n# Additional JSTransformers included in `pug-pack`\n\n### coffeescript\n\n`pug-pack` includes a [CoffeeScript v2 jstransformer](https://github.com/zdenko/jstransformer-coffeescript),\nwhich can be used in .pug as follows:\n\n```\nscript\n  :coffeescript(bare=true)\n    foo = -\u003e \"this is foo\"\n\nscript.\n  console.log(\"foo says:\", foo());\n```\n\nNote that:\n\n- this is simply an alternative to `:inject(ext=\"coffee\")`\n\n- `pug` itself might include the `coffee-script` (with the hyphen) filter,\n  which is CoffeeScript v1\n\n- this jstransformer is `coffeescript` (without the hyphen), and is CoffeeScript v2\n\n- syntax hightlighting doesn't play well with the custom `:inject` filter,\n  so for inlining more than a few lines of CoffeeScript, this jstransformer\n  is preferable\n\n### markdown-it\n\nMarkdown and Pug are a great combo, use this filter like so:\n\n```pug\n:markdown-it\n    # Your Markdown Content\n\n    | Column A         | Column B             |\n    | ---------------- | -------------------- |\n    | A little of this |                      |\n    |                  | and a little of that |\n```\n\n# Reference for files in `src`\n\n## Third-party libraries\n\n| File(s)                          | Notes                                                                 |\n| -------------------------------- | --------------------------------------------------------------------- |\n| axios.js                         | Axios                                                                 |\n| bootstrap.css                    | Bootstrap CSS                                                         |\n| bootstrap-dark.css               | Bootstrap CSS for dark mode                                           |\n| chart.{css,js}                   | Chart.js for making charts                                            |\n| filesize.js                      | Convert numbers to SI-prefixed byte strings                           |\n| hyperapp.js                      | HyperApp UI Framework                                                 |\n| jquery-stripped.js               | Custom JQuery build                                                   |\n| jquery.js                        | Standard JQuery library                                               |\n| jquery.tablesorter.min.js        | Plugin to turn any table sortable                                     |\n| lodash-custom.js                 | Custom Lodash build                                                   |\n| lodash.js                        | Standard Lodash build                                                 |\n| md-icons.css                     | Local copy of Material Design css                                     |\n| moment-timezone.js               | Timezone data for Moment                                              |\n| moment.js                        | Moment.js                                                             |\n| showdown.js                      | Showdown.js to render Markdown to HTML on the client                  |\n| sorttable.js                     | An ancient way to make table sortable; use JQuery.tablesorter instead |\n| sugar.min.js                     | The Sugar.js framework                                                |\n| tablesorter-theme-bootstrap4.css | Nice CSS for the tablsorter plugin                                    |\n| vue-dev.js                       | Vue.js dev build                                                      |\n| vue-prod.js                      | Vue.js prod build                                                     |\n| vuetify.{css,js}                 | Vuetify UI Framework                                                  |\n\n## Example Pug files\n\nThese all use Vuetify to demonstrate how small a useful page can be:\n\n| Template        | Notes                                               |\n| --------------- | --------------------------------------------------- |\n| bgg.pug         | View BoardGameGeek data for a given username        |\n| github-user.pug | Display all repos of a GitHub user                  |\n| vue-chart.pug   | Plot time series data (see `timesc` CLI tool below) |\n\n## Client-side helpers\n\n| File                           | Notes                                                                     |\n| ------------------------------ | ------------------------------------------------------------------------- |\n| bind-input-query-param.coffee  | Easily wrangle query params in the url (see below)                        |\n| mdtable.js                     | Convert JS array-of-arrays to a string of nicely-formatted Markdown table |\n| commify.js                     | Inject commas as thousands separators into a number                       |\n| day-hour-min-sec.js            | Convert a number of seconds into a nicer \"1d 2h 3m 4s\"-style string       |\n\n#### bind-input-query-param.coffee\n\n[This](./src/bind-input-query-params.coffee) is a function to bind \\\u003cinput\u003e\nelements to url query params, with a few extra conveniences around that. After\n`:inject`ing it, simply call `bindInputQueryParam('#your-element-id')`, eg:\n\n```pug\ninput#query\n:inject(file=\"bind-input-query-param.coffee\")\n:inject(ext=\"coffee\")\n  bindInputQueryParam '#query', -\u003e\n    console.log 'the url query string was updated, look at it!'\n```\n\n#### mdtable.js\n\nThis takes an array-of-arrays, and renders it as a markdown table (in a\nstring) using https://github.com/wooorm/markdown-table.\n\n```js\nmdtable(['foo', 'bar'], ['first',2], ['second',4], { align: 'lr' })\n```\n\n#### commify.js\n\nAdds commas to a number to make it easier to read.\n\n```js\ncommify(3423545656356923.1231255) // 3,423,545,656,356,923.123,125,5\n```\n\n#### day-hour-min-sec.js\n\nConverts a number of seconds into something that makes more sense to a human\n\n```js\ndhms(344) // 5m 44s\n```\n\n# Misc CLI Tools\n\n## mdtable\n\nA CLI wrapper around the client-side `mdtable.js` library.\n\n```\nusage: mdtable [options and filename(s)]\n\nReads lines from filename(s) and/or stdin and outputs them in a nicely\nformatted Markdown table.\n\nInput options:\n\n-i INDEXES   include columns via 1-based indexes in CSV form (eg \"2,-1,4\")\n-e INDEXES   exclude columns via 1-based indexes in CSV form\n-r REGEX     regex used to split each row into cells (\"\\t\" by default)\n-w           whitepsace-based inference for column boundaries: use the first\n             line as a template (eg, see Docker's CLI output)\n-j           json-formatted input (ignore -r and -w)\n-c           csv-formatted input (ignore -r and -w)\n\nOutput options:\n\n-a ALIGN     align each cell with \"l\", \"r\", and \"c\" (eg \"llr\")\n-n NAMES     names for column headers as CSV (if first line of input is not\n             headers)\n-t N         truncate all cells to N characters\n-p           plaintext output: un-markdownify the final result\n-s           strict parsing: only output lines that parse to the same number\n             of cells as the first line of input\n\nLong args are also supported: --regex, --align, --names, --truncate,\n--include/--indexes, --exclude, --strict, --whitespace, --plaintext, --json,\nand --csv. A filename of \"-\" will read from stdin.\n\n-a and -n are used AFTER -i and -e. i.e., if you -i three columns, you should\nALSO pass three values for -a and/or -n.\n```\n\n## commify\n\nA CLI wrapper around `commify.js`.\n\n```\nusage: commify [-j] [NUMBER ...]\n\nInserts commas as thousands separators in one or more NUMBER, and outputs each\non its own line. -j outputs as JSON for Alfred Workflow integration.\n```\n\n## dhms\n\nA CLI wrapper around `day-hour-min-sec.js`.\n\n```\nusage: dhms [NUMBER ...]\n\nConvert a number of seconds into human numbers.\n```\n\n## timesc\n\nThis is a command-line tool to feed newline-based timestamps into\nvue-chart.pug on your local machine.\n\n```\ntimesc - (time) (s)eries (c)hart\n\nusage: timesc [file ...] [-f fmt\u003e]\n\nParse timestamps from lines of input and graph it using Vue and Chart.js. The\nchart includes:\n\n- aggregation by adjustable duration\n- limiting to most recent timestamps\n\nEach timestamp has a weight of 1, so that default aggregation amounts to simply\ncounting timestamps. Weight can be changed by including a number with each\ntimestamp, either before or after the timestamp and separated by comma or tab,\nfor example:\n\n    2019-08-29,12\n    24,2019-08-30\n    26,2019-09-01\n\nTimestamps are parsed strictly.\n\n-f/--format \u003cmoment format string\u003e\n\n    Without a format, falls back on moment's default parsing, otherwise\n    parsing will use your format:\n\n    https://momentjs.com/docs/#/parsing/string/\n    https://momentjs.com/docs/#/parsing/string-format/\n```\n\n## cs\n\nA CLI that wraps the `coffee` binary with some useful behavior for shell\none-liners, as well as exploring CoffeeScript in its REPL.\n\n```\nRun CoffeeScript with lots of pre-defined objects/functions:\n\n  s: sugar.js\n  m: moment.js\n  l: lodash.js\n  fs: fs\n  log: console.log()\n  js: JSON.stringify()\n  jp: JSON.parse()\n  fsr: fs.readFileSync()\n  fsw: fs.writeFileSync()\n\nIf given args, assumes each arg is a line of the function to run on each\nline of stdin. Without args, just opens the REPL.\n```\n\n## pugs\n\nA CLI to run `pug` in the context of your local pug-pack installation. `src`\nin this context is the `pug-pack/src` directory itself, not your own `src`\ndirectory. Use this if you're intentionally trying to use files in this repo,\nsomething like the `timesc` script.\n\n```\n$ pugs -h\nA wrapper around running pug with --basedir set to pug-pack's `src` directory.\n\nusage:\n  pugs [-l|--list|ls [ARGS]]   # runs `ls` with ARGS in `src`\n  pugs [-f|--find|find [ARGS]] # runs `find` with ARGS in `src`\n  pugs ARGS                    # runs `pug` with --basedir set to `src` and\n                               # ARGS for pug\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrewingcode%2Fpug-pack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrewingcode%2Fpug-pack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrewingcode%2Fpug-pack/lists"}