Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save petrowsky/970d4e45203b8d021e0bbbd29f5e9532 to your computer and use it in GitHub Desktop.

Select an option

Save petrowsky/970d4e45203b8d021e0bbbd29f5e9532 to your computer and use it in GitHub Desktop.
FMIndent Post-processing filemakerstandards
function transformLet(text) {
return text.replace(/Let\s*\(\s*\[/, 'Let ( [');
}
function formatAmpersands(input) {
// Validation function to ensure all characters are preserved
function validateOutput(original, formatted) {
const originalChars = original.replace(/\s/g, '').split('').sort();
const formattedChars = formatted.replace(/\s/g, '').split('').sort();
if (originalChars.length !== formattedChars.length) {
throw new Error('Character count mismatch');
}
for (let i = 0; i < originalChars.length; i++) {
if (originalChars[i] !== formattedChars[i]) {
throw new Error('Character mismatch detected');
}
}
return true;
}
let text = input;
// Step 1: Replace all "&" with "\n&"
text = text.replace(/&/g, '\n&');
// Step 2: Replace all "&\n" with "&"
text = text.replace(/&\n/g, '&');
// Step 3: Regex any space chars (tab, spaces, etc.) following any & down to one space
text = text.replace(/&\s+/g, '& ');
// Step 4: Walk each line and apply indentation of the preceding line
const lines = text.split('\n');
const result = [];
let previousIndent = '';
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.trim() === '') {
// Empty line - keep as is and don't change previousIndent
result.push(line);
continue;
}
if (line.trim().startsWith('&')) {
// This is an ampersand line - use previous line's indentation
const ampersandContent = line.trim();
result.push(previousIndent + ampersandContent);
} else {
// Regular line - extract its indentation for next ampersand line
const indentMatch = line.match(/^(\s*)/);
if (indentMatch) {
previousIndent = indentMatch[1];
}
result.push(line);
}
}
// Step 5: Any & followed by either // or /* should get a return added so the comment is on its own line
const finalLines = result.join('\n').split('\n');
const finalResult = [];
for (let i = 0; i < finalLines.length; i++) {
const line = finalLines[i];
// Check if line contains & followed by // or /*
const commentMatch = line.match(/^(\s*&\s*)(\/\/.*|\/\*.*)/);
if (commentMatch) {
const indent = line.match(/^(\s*)/)[1];
const ampersandPart = commentMatch[1];
const commentPart = commentMatch[2];
finalResult.push(ampersandPart.trimEnd()); // Keep ampersand line, remove trailing spaces
finalResult.push(indent + commentPart); // Add comment on new line with same base indentation
} else {
finalResult.push(line);
}
}
const output = finalResult.join('\n');
// Validate that all characters are preserved
try {
validateOutput(input, output);
} catch (error) {
console.error('Validation failed:', error.message);
throw error;
}
return output;
}
function prefixLetVariables(code) {
// Step 1: Extract the [ ... ] block inside Let
const letBlockMatch = code.match(/Let\s*\(\s*\[\s*([\s\S]*?)\s*\]\s*;/);
if (!letBlockMatch) return code;
const declarations = letBlockMatch[1];
// Step 2: Extract variable names (before each =)
const variableNames = [...declarations.matchAll(/^\s*([a-zA-Z_]\w*)\s*=/gm)].map(match => match[1]);
// Step 3: Replace each variable with ~variable, using word boundaries
let updatedCode = code;
for (const name of variableNames) {
const regex = new RegExp(`\\b${name}\\b`, 'g');
updatedCode = updatedCode.replace(regex, `~${name}`);
}
return updatedCode;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment