Skip to content

Instantly share code, notes, and snippets.

@pointybeard
Created September 7, 2021 02:19
Show Gist options
  • Save pointybeard/91b9fda541716718fc72bcd07f00b7d7 to your computer and use it in GitHub Desktop.
Save pointybeard/91b9fda541716718fc72bcd07f00b7d7 to your computer and use it in GitHub Desktop.
Parses the contents of an input scad file looking for parameters that can be set dynamically
<?php
$paramters = [];
const CONSTRAINT_TYPE_MINMAX = "minmax";
const CONSTRAINT_TYPE_SET = "set";
function determineParameterConstraintType(array $constraint): string
{
return count($constraint) == 1 ? CONSTRAINT_TYPE_MINMAX : CONSTRAINT_TYPE_SET;
}
// Change this to the name of input file
$handle = fopen("input.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$r = preg_match_all(
"@^(?:[ \t]+)?(?<name>[a-z_](?:[a-z_\d]+)?)(?:[ \t]+)?=(?:[ \t]+)?(?<value>[^;]+);(?:(?:[ \t]+)?\/\/(?:[ \t]+)?\[(?<constraint>[^\]]+))?@i",
$line,
$matches,
PREG_SET_ORDER
);
// (guard) No matches
if($r == 0 || $r == false) {
$previousLine = $line;
continue;
}
$parameter = [
"name" => $matches[0]["name"],
"value" => $matches[0]["value"],
"constraint" => $matches[0]["constraint"] ?? null,
"help" => null
];
// Value will can be a number or a string but never anything else
if(preg_match("@^[\"']([^\"']+)[\"']$@", $parameter["value"], $match)) {
$parameter["value"] = $match[1];
} elseif(is_numeric($parameter["value"])) {
// Quick and dirty way to convert to number
$parameter["value"] += 0;
// (guard) This line is not a defined value, instead, it is likely calculated
} else {
continue;
}
// Further parse the constraint if there is one
if(null != $parameter["constraint"]) {
$constraint = [
"values" => explode(",", $parameter["constraint"]),
"type" => null
];
$constraint["values"] = array_map("trim", $constraint["values"]);
// The possibilities here are either an array containing exactly 2 numbers (min/max) or
// an array of values that denotes a set of possible values
$constraint["type"] = determineParameterConstraintType($constraint["values"]);
if($constraint["type"] == CONSTRAINT_TYPE_MINMAX) {
[$constraint["values"]["min"], $constraint["values"]["max"]] = array_map("floatval", explode(":", $constraint["values"][0]));
} else {
$values = array_map(function ($item) {
$bits = explode(":", $item);
$value = $bits[0];
$name = $bits[1] ?? $value;
return [
"value" => trim($value),
"name" => trim($name)
];
}, $constraint["values"]);
$constraint["values"] = [];
foreach($values as $item) {
$constraint["values"][$item["value"]] = $item["name"];
}
}
$parameter["constraint"] = $constraint;
}
// See if the previous line has help text information
$r = preg_match_all(
"@^\/\/(?:[ \t]+)?-(?:[ \t]+)?(?<help>[^\r\n]+)@i",
$previousLine,
$matches,
PREG_SET_ORDER
);
if($r !== false && $r > 0) {
$parameter["help"] = $matches[0]["help"] ?? null;
}
$paramters[] = $parameter;
$previousLine = $line;
}
fclose($handle);
} else {
// error opening the file.
throw new Exception("Unable to open source file input.txt");
}
print json_encode($paramters, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment