Skip to content

Variables

Brett Terpstra edited this page Mar 7, 2023 · 9 revisions

When running commands in a topic, you can use a double dash (--) in the command line (surrounded by spaces) and anything after it will be interpreted as shell arguments. These can be used in commands with $ placeholders. $1 represents the first argument, counting up from there. Use $@ to pass all arguments as a shell-escaped string.

For example, the topic titled "Test" could contain an @run command with placeholders:

## Test
@run(./myscript.sh $@)

Then you would run it on the command line using:

howzit -r test -- -x "arg 1" arg2

This would execute the command as ./myscript.sh -x arg\ 1 arg2.

Placeholders can be used in both commands and run blocks. If a placeholder doesn't have an argument supplied, it's not replaced (e.g. leaves $2 in the command).

Numeric placeholders can also have default (fallback) values assigned in the case that no argument is provided when running. To do so, refer to them with the syntax ${1:DEFAULT VALUE}. See below for more details.

Named Variables

When defining a topic you can add variable names in parenthesis after the topic title. These will be populated in order from parameters passed after -- on the command line. They can be referred to with ${NAME} in your scripts or in the Markdown text.

## Test (var1, var2)
@run(cp "${var1}" "${var2}")

Variable names must be alphanumeric characters with no spaces or hyphens (underscores ok). Multiple variables are separated by commas.

Default Values

You can set a default (fallback) value for any variable definition or placeholder, making it optional, by appending ':DEFAULT'. For example, if you defined a variable myvar and wanted it to populate with a default value if none was provided on the command line, you would use:

## Test (myvar:clobber package)
@run(rake ${myvar})

Fallbacks can also be defined in the placeholder:

## Test (myvar)
@run(rake ${myvar:clobber package})

Now when the "Test" topic is run (or displayed) and no arguments are passed after --, it will default to clobber package. If an argument is passed, it replaces the default.

Note that in the example above, if you wanted to pass an argument containing spaces, you'd need to quote them in the command, e.g. howzit -r Test -- "bump:patch rspec". Otherwise you could use $* to insert all passed variables as a single string.

Named variables are populated positionally, so if you have two variables named and the first one has a default value, and then you call the topic with only one variable, it's the first name that will have the value assigned (overriding the default). If you want to assign the second variable, you have to provide two arguments on the command line.

Passing Variables With @include

Variables can be passed when using @include() directives by adding square brackets at the end of the include topic title. So if I were going to call the above example from within another topic, I would use @include(Test [rspec]). Arguments are separated by commas. You can also use variables within the square brackets, so if the parent topic had already defined a variable (or set it in front matter), you could use @include(Test [${default_test}]).

A big thing that this allows is the creation of reusable topics that perform a specific function which can be included by multiple parent topics. Changing the parameters of the @include directive within the parent topic will change the behavior of the nested snippet.

Mixing With Metadata

Metadata defined at the top of a build note file becomes available as ${NAME} as well as [%NAME]. Arguments passed on the command line take precedence over metadata when populating ${NAME} syntax placeholders, but if there is no correlating argument passed, the metadata value will be used.

Clone this wiki locally