Last active
October 4, 2023 14:30
-
-
Save erdesigns-eu/b73107f55b4451601b2794b50a827774 to your computer and use it in GitHub Desktop.
Parse Delphi DFM in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const parseDFM = (text) => { | |
let result = null; | |
// Replace all returns with newlines | |
text = text.replace(/\r\n/g, '\n'); | |
text = text.replace(/\r/g, '\n'); | |
// Split into lines | |
const lines = text.split('\n'); | |
let currentComponent = null; | |
let stack = []; | |
// Loop through lines | |
for (let i = 0; i < lines.length; i++) { | |
// Trim line | |
let line = lines[i].trim(); | |
// Start of component | |
if (line.startsWith('object ')) { | |
const component = line.match(/^object (\w+): (\w+)$/); | |
if (component) { | |
// Create new component object | |
const newComponent = { | |
name: component[1], | |
className: component[2], | |
children: [], | |
}; | |
if (currentComponent) { | |
// Add to children of current component | |
currentComponent.children.push(newComponent); | |
} else { | |
// Set as root component | |
result = newComponent; | |
} | |
// Push to stack and set as current component | |
stack.push(newComponent); | |
currentComponent = newComponent; | |
} | |
continue; | |
} | |
// End of component | |
if (line.startsWith('end') && stack.length > 0) { | |
// Pop from stack | |
currentComponent = stack.pop(); | |
// Set current component to parent component | |
if (stack.length > 0) { | |
currentComponent = stack[stack.length - 1]; | |
} | |
continue; | |
} | |
// Component property | |
const property = line.match(/^([\w.]+)\s*=\s*(.*)$/); | |
if (property) { | |
const value = property[2]; | |
// If value is a string | |
if (value.startsWith("'") && value.endsWith("'")) { | |
// Remove quotes | |
property[2] = String(value.substring(1, value.length - 1)); | |
} | |
// If value is a number | |
if (!isNaN(value)) { | |
// Convert to number | |
property[2] = Number(value); | |
} | |
// If value is a nil | |
if (value === 'nil') { | |
property[2] = null; | |
} | |
// If value is empty | |
if (value === '') { | |
property[2] = null; | |
} | |
// If value is a boolean | |
if (value === 'True') { | |
property[2] = true; | |
} | |
if (value === 'False') { | |
property[2] = false; | |
} | |
// If value is an array | |
if (value.startsWith('(') && value.endsWith(')')) { | |
// Remove brackets | |
property[2] = value.substring(1, value.length - 1); | |
// Split into array | |
property[2] = property[2].split(',').filter((entry) => !!entry); | |
} | |
// If value is a set | |
if (value.startsWith('[') && value.endsWith(']')) { | |
// Remove brackets | |
property[2] = value.substring(1, value.length - 1); | |
// Split into array | |
property[2] = property[2].split(',').filter((entry) => !!entry); | |
} | |
// If value is a dictionary | |
if (value.startsWith('{') && value.endsWith('}')) { | |
// Remove brackets | |
property[2] = value.substring(1, value.length - 1); | |
// Split into array | |
property[2] = property[2].split(',').filter((entry) => !!entry); | |
} | |
// If the property name contains a dot (.) then it is a sub-property | |
if (property[1].indexOf('.') > -1) { | |
// Split property name into parts | |
const parts = property[1].split('.'); | |
// Get property name | |
const propertyName = parts[0]; | |
// Get sub-property name | |
const subPropertyName = parts[1]; | |
// Get current component property | |
const currentComponentProperty = currentComponent[propertyName]; | |
// If current component property is not an object | |
if (typeof currentComponentProperty !== 'object') { | |
// Create new object | |
currentComponent[propertyName] = {}; | |
} | |
// Add sub-property to current component property | |
currentComponent[propertyName][subPropertyName] = property[2]; | |
continue; | |
} | |
// Add property to current component | |
currentComponent[property[1]] = property[2]; | |
} | |
} | |
// Return result | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment