SCSS Loop Template Processor 1.2.0.0
------------------------------------
History (compact):
1.2.0.0 - December 2019 - Cleanup code, added this documentation, prepare for NANY 2020 release
1.1.0.0 - November 2019 - Added enable/disable-lines-start/end processing
1.0.0.0 - October 2019 - Working as intended
0.1.0.0 - October 2019 - Initial development

Purpose:
Process SCSS (css preprocessing) @for loops to @each loops including only used classes.

During development we use many generated classes for 'pixel-perfect' alignment of page elements.
(The proprietary platform used doesn't allow for direct html or css tags to be applied on elements, only classes can be applied, and to override previous, platform-standard, css often !important needs to be added to the css.)
Both the template and the generated output are @include'd in the files proveded to the scss compiler, but those from the templated are disabled by using an @if that is defined in the template-output to be false on second evaluation. During development the template-output is a (nearly) empty file.

include example:
@include 'global/generated-loops.scss' /* order of these imports is !important, first the generated loops file, then the template loops file */
@include 'global/template-loops.scss'

scss example:
[code=scss]
$position-list: top right bottom left;
@for $i from -50 through 500 {
	@each $position in $position-list {
		.cf-margin-#{$position}-#{$i} {
			margin-#{$position}: #{$i}px !important;
		}
	}
}
[/code]

After development of a release is completed, performance optimization of the generated css is desired, as we generate ca. 22,000 classes but only 200 are actually used...
The used classes are extracted from the platform-generated page sources (xml files) with a batch script using xml-starlet, grep and sort, and filtered into a list that only includes classes with a specific prefix end a numeric postfix. This script is not included here.
The resulting list is fed to scss-loop-template to be processed on a template, producing a scss output file where unused generated classes are disabled, and @for loops replaced by @each loops for only those values supplied in the input file.

template example:
[code=scss]
$position-list: top right bottom left;
/* ---class cf-margin(?:-top|-right|-bottom|-left) */
/* ---replace @for @each $i in $$ { */
/* next line is added/updated by the processor */
@for $i from -50 through 500 {
	@each $position in $position-list {
		.cf-margin-#{$position}-#{$i} {
			margin-#{$position}: #{$i}px !important;
		}
	}
}
/* ---end cf-margin(?:-top|-right|-bottom|-left) */
[/code]

template example output (input: cf-margin-left-10 cf-margin-left-12 cf-margin-left-24 cf-margin-left-26 cf-margin-left-30 cf-margin-left-31 cf-margin-left-350 cf-margin-left-38 cf-margin-left-400 cf-margin-left-5 cf-margin-left-50 cf-margin-left-6 cf-margin-left-60 cf-margin-right--10 cf-margin-top-10 cf-margin-top-150 cf-margin-top-2 cf-margin-top-20 cf-margin-top-24 cf-margin-top-25 cf-margin-top-3 cf-margin-top-40)
[code=scss]
$position-list: top right bottom left;
/* ---class cf-margin(?:-top|-right|-bottom|-left) */
/* ---replace @for @each $i in $$ { */
/* next line is added/updated by the processor */
/* ---original @for $i from -50 through 500 { */
@each $i in 10, 12, 24, 26, 30, 31, 350, 38, 400, 5, 50, 6, 60, -10, 150, 2, 20, 25, 3, 40 { 
	@each $position in $position-list {
		.cf-margin-#{$position}-#{$i} {
			margin-#{$position}: #{$i}px !important;
		}
	}
}
/* ---end cf-margin(?:-top|-right|-bottom|-left) */
[/code]

NB: In this example all 4 position values are generated for all cf-margin values found, even though not all those positions are used. This is a trade-off between maintainability and performance.

Template markers are in single-line block comments (/* */), always prefixed by --- and values (where applicable) are always separated from the marker by at least 1 space

Supported markers:
---class <name> : a classname or a regex specifying a range of classnames (regex needs to contain at least 1 '(' ).
---replace <what> <replacement> : what line-prefix to replace with what replacement content. Only a single word/element is used for the prefix ('@for' in the example) and the rest of the line as the replacement ('@each $i in $$ {' ) where $$ is replaced by the range of postfix-values found matching the classname/regex.
---original <string> : the content of the line replaced, is always overwritten by the processor.
---end <name> : marks the end of the section to disable if no match for ---class is found. Needs to specify the exact same value as its matching ---class entry.
---enable-next-line [<n>] ---enable-next-lines [<n>]: enables the next n lines (default = 1) (unconditional).
---disable-next-line [<n>] ---disable-next-lines [<n>] : disables the next n lines (default = 1) (unconditional).
---enable-lines-start : start of a block to enable during processing (unconditional).
---enable-lines-end : end of a block to enable during processing (unconditional).
---disable-lines-start : start of a block to disable during processing (unconditional).
---disable-lines-end : end of a block to disable during processing (unconditional).

See the provided sample template for more examples.

usage:
scss-loop-template-processor.exe [options] [-i] <classesfile> [-t] <templatefile> [-o] <outputfile>
Command-line parameters:
options:
-? / --help			: Show this help
-q / --quiet		: Suppress output during processing
-v / --verbose		: Show more info during processing
-x / --extraverbose	: Show even more info during processing
-p / --pause		: Wait for a keypress after processing before closing the application
file arguments:
-i / --input <classesfile>		: Specify the inputfile with the list of classes (1 per line)
-t / --template <templatefile>	: Specify the templatefile to process
-o / --output <outputfile>		: Specify the outputfile, always overwritten
When no -i/-t/-o arguments are specified then <classesfile>/<templatefile>/<outputfile> are taken from non-option arguments specified, in this order.
These 3 file arguments are required.

Sample run:
D:\tools\scss> scss-loop-template-processor -i appearance-classes.txt -t custom-loop-template.scss -o custom-loops.scss -p
scss-loop-template-processor : Replace scss @for loops by @each loops to reduce the number of generated classes 1.2.0.0
(c) 2019.. Ath Software Design
Processing template to custom-loops.scss...
Done.
Press a key to continue...