ts-budgie
Version:
Converts TypeScript code to Budgie.
89 lines (72 loc) • 2.52 kB
text/typescript
import { CommandsBag, CommandsBagFactory, LanguagesBag, RenderContext } from "budgie";
import { BudgieLine } from "../output/budgieLine";
/**
* Generates spaces equivalent to 4-space code tabbing.
*
* @param amount How many tabs should be added.
* @returns An all-spaces String of length = amount * 4.
*/
const generateTabs = (amount: number): string => {
let output = "";
for (let i = 0; i < amount; i += 1) {
output += " ";
}
return output;
};
/**
* Indents Budgie lines using their command metadata.
*/
export class LineIndenter {
private readonly commandsBag: CommandsBag;
public constructor() {
this.commandsBag = CommandsBagFactory.forContext(new RenderContext(new LanguagesBag().getLanguageByName("TypeScript")));
}
/**
* Indents Budgie lines using their command metadata.
*
* @param lines Budgie and literal string lines.
* @returns Indented versions of the lines.
*/
public indent(lines: (string | BudgieLine)[]): string[] {
const output: string[] = [];
if (lines.length === 0) {
return output;
}
let currentIndentation = 0;
for (const line of lines) {
if (typeof line === "string") {
output.push(line);
continue;
}
const indentationChanges = this.getIndentationChanges(line);
const stringified = line.toString();
for (const change of indentationChanges) {
if (change < 0) {
currentIndentation += change;
}
}
if (stringified === "") {
output.push("");
} else {
output.push(generateTabs(currentIndentation) + line.toString());
}
for (const change of indentationChanges) {
if (change > 0) {
currentIndentation += change;
}
}
}
return output;
}
/**
* Computes how a line's command changes indentation.
*
* @param line Output Budgie line.
* @returns How the line's command changes indentation.
*/
private getIndentationChanges(line: BudgieLine): number[] {
const command = this.commandsBag.getCommand(line.command);
const metadata = command.getMetadata();
return metadata.indentation;
}
}