Skip to content

Instantly share code, notes, and snippets.

@BinToss
Last active February 5, 2024 06:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BinToss/41441008e71142ed2bae79b8c0d8ee53 to your computer and use it in GitHub Desktop.
Save BinToss/41441008e71142ed2bae79b8c0d8ee53 to your computer and use it in GitHub Desktop.
redhat.vscode-xml - assignAttributeGroupIDs
// https://github.com/redhat-developer/vscode-xml/issues/965
import micromatch from 'micromatch';
// example of a PatternGroup[] parsed from the VSCode workspace's configuration (./.vscode/settings.json)
const workspaceConfigurationPatternGroups: PatternGroup[] = [
[
// same matches as "(mc|d):*", but implemented as two calls to micromatch.match and a call to array.push() to combine the matches
"mc:*",
"d:*"
],
["xmlns:*"]
];
class XmlElement {
attributes: IXmlAttributeFormatting[] = [];
value: object | null | undefined;
/**
* @param {PatternGroup[]} patternGroups - two-dimensional array of micromatch pattern. Each sub-array is an array of patterns whose matches should be grouped together.
*/
assignAttributeGroupIDs(patternGroups: PatternGroup[]): void {
if (this.attributes.length === 0) {
return;
}
// iterate through attributes, assigning IDs for the group they should belong to. This ID will only be used for formatting and will not be written to the XML document.
for (let attrI = 0; attrI < this.attributes.length; attrI++) {
this.attributes[attrI]._tentativeUniqueIDs = []; // init temporary property
// iterate pattern groups
for (let groupID: GroupID = 0; groupID < patternGroups.length; groupID++) {
const patternGroup = patternGroups[groupID];
//iterate patterns
for (let patternID: PatternID = 0; patternID < patternGroup.length; patternID++) {
// if the attribute matches the pattern, add the Group-Pattern ID
if (micromatch.isMatch(this.attributes[attrI].key, patternGroup[patternID])) {
this.attributes[attrI]._tentativeUniqueIDs.push({ groupID, patternID } as UniqueID);
}
}
}
}
// reiterate: assign final groupID. Iterate the groupID if the current attribute and prior attribute have no tentative IDs in common.
for (let attrI = 0; attrI < this.attributes.length; attrI++) {
//this.attributes[attrI];
if (attrI === 0) {
// first group will always be 0
this.attributes[attrI]._groupID = 0;
}
else {
/**
* Check if the prior {@link IXmlAttributeFormatting} and this
* {@link IXmlAttributeFormatting} have any of the same
* {@link IXmlAttributeFormatting._tentativeUniqueIDs}
* If they have at least one {@link UniqueID} in common, assign
* the prior's {@link IXmlAttributeFormatting._groupID} as this
* attribute's {@link IXmlAttributeFormatting._groupID}.
*/
const sharesAtLeastOneUniqueIDWithPriorAttribute =
this.attributes[attrI]._tentativeUniqueIDs.some((uniqueID) =>
this.attributes[attrI]._tentativeUniqueIDs.includes(uniqueID));
if (sharesAtLeastOneUniqueIDWithPriorAttribute) {
this.attributes[attrI]._groupID = this.attributes[attrI - 1]._groupID;
}
}
}
/** Remove {@link IXmlAttributeFormatting._tentativeUniqueIDs}. We don't need them anymore. */
this.attributes.forEach(attr => attr._tentativeUniqueIDs = []);
}
}
//#region typedefs
type Pattern = string;
type PatternID = number;
type GroupID = number;
interface UniqueID { groupID: GroupID, patternID: PatternID };
/**
* @remark When this is added to an array, its index in that array becomes this group's ID for use in UniquePatternID.
*/
interface PatternGroup extends Array<Pattern> {
label?: string;
readonly [patternID: PatternID]: Pattern;
}
interface IXmlAttribute {
// remember to delete other properties before writing the document!
key: string,
value: string
}
/**
* {@link IXmlAttribute} extended with formatting metadata.
*
* @interface IXmlAttributeFormatting
* @type {IXmlAttributeFormatting}
* @extends {IXmlAttribute}
*/
interface IXmlAttributeFormatting extends IXmlAttribute {
/**
* Each {@link UniqueID} in this array represents an individual {@link Pattern} matched against this attribute.
* @type {UniqueID[]}
*/
_tentativeUniqueIDs: UniqueID[],
/**
* The finalized ID of the attribute formatting group.
* @type {number}
* @see {@link XmlElement.assignAttributeGroupIDs}
*/
_groupID: number
}
//#endregion typedefs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment