arbinger systems

Plake
Target-based file assembler

Plake is a tool that allows you to maintain sections within a single file (usually, variations of the same code/markup/content) and then assemble variations of that file according to which target you call. It was inspired by Make, can be used in conjunction with Make, and is written in Perl, hence the name "Plake".

It uses a very simple grammar, and allows you to define sections within a given text file, then define targets that assemble the sections you want, and optionally, specify a path where the assembled section will be written to disk as a new file.

Let's say you have a C++ source file that gets built for the Windows platform and also for Linux. Keep the differences as sections in a single Plake file, then when you assemble the .cpp file for the given platform, it only contains that platform's code.

The following commands both produce "myfile.cpp" (but possibly at different folder locations) with only the code that each platform needs:

plake file=myfile.plk target=windows_build

plake file=myfile.plk target=linux_build

Plake runs in two modes.

1. "Top-down/lazy", the default mode, which includes all sections for a given target plus lines from the file that do not have a defined section. The output is assembled top-down. This is useful for when you only need small variations of a file to be made, and want to keep Plake to a minimum.

2. "Stickler", which means that any text not attributed to a named section is ignored, and sections are assembled in the order that they are passed into target(). This means you have specific ideas about how the output will be assembled and don't want Plake to try and be intelligent about it.

NAME

Plake - Target based file assembler

SYNOPSIS

Here's roughly what a Plake file would look like:

!plake: # Denote "code" section, where we setup targets

# This is all just Perl code that gets eval'd...
my $START = "header base_section";

target(
		default,                    # Target name       
		"$START section1 footer",   # Sections to include
		'path/to/output/file.pl'    # Target output path
		);

target(
		section2,
		"$START section2 footer",
		''                          # Output to STDOUT
		);
		
!plake. # End section

This text will appear if "lazy/top-down" behavior is invoked -- 
that is, any lines not specifically part of a section are 
allowed to be output.

!plake header
HEADER: One liner section

!plake base_section:
... included in all assemblages ...
... etc ...

!plake section1:

... something, code, markup, comments, whatever ...
... more ...
... etc ...

!plake section2: # Start of this section denotes end of previous
... stuff ...
... more ...
... etc ...

!plake footer:
(c) 2999

And here's generally how you would use the Plake.pm package to process a Plake file:

use Plake qw(target my_builder);

# ... Open file...
# Parse
while() {
		Plake::parse($_);
}

# Setup targets (and whatever else)
eval $Plake::CODE;

# Build a target. $src is the assembled content. $target is
# the path to the output file that should be created, if one
# is defined.
$stickler_mode = 'on';
my ($target, $src) = Plake::build('target_name', $stickler_mode);

# ... Now, do something with $target and $src ...

Plake grammar

Code section
Use !plake: to indicate the start of a ``code'' section, where you declare your targets with the target() method, and maybe even override the default ``build'' method with your own using my_builder().
Standard section
!plake \w+:, e.g. !plake section1:, indicates the start of a multi-line, standard section. The start of a new section flags the end of a previous section.
One-line section
Use !plake \w+, e.g. !plake oneliner (followed immediately by your line) to generate a single line section.
Section ending
Use !plake. to end a section explicitly. You can use it to end standard sections as well as code sections.