From 954b4b5a55347c0c5ec94d873bd47f9b78f8dd36 Mon Sep 17 00:00:00 2001 From: yaqubroli Date: Wed, 21 Aug 2024 08:35:13 -0700 Subject: [PATCH] * contents/customXml/_rels/item1.xml.rels: preliminary work on build system --- .gitignore | 17 +++++++++++++++++ CV.docx | 0 CV.pdf | 0 Makefile | 26 ++++++++++++++++++++++++++ README.org | 18 ++++++++++++++++++ YAMLParser.bas | 313 -------------------------------------------------------------------------------- cv.docm | 0 cv.docm.bak | 0 cv.dotx | 0 cv.thmx | 0 ~$CV.docx | 0 contents/[Content_Types].xml | 2 ++ examples/CV.docx | 0 examples/CV.pdf | 0 python_build/compile_vba.py | 27 +++++++++++++++++++++++++++ python_build/extract_vba.py | 32 ++++++++++++++++++++++++++++++++ contents/_rels/.rels | 2 ++ contents/customXml/item1.xml | 1 + contents/customXml/itemProps1.xml | 2 ++ contents/docProps/app.xml | 2 ++ contents/docProps/core.xml | 2 ++ contents/word/document.xml | 2 ++ contents/word/fontTable.xml | 2 ++ contents/word/numbering.xml | 2 ++ contents/word/settings.xml | 2 ++ contents/word/styles.xml | 2 ++ contents/word/webSettings.xml | 2 ++ src/Class Modules/YAML.cls | 353 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Modules/NewMacros.bas | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Modules/YAMLParser_old.bas | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ contents/customXml/_rels/item1.xml.rels | 2 ++ contents/word/_rels/document.xml.rels | 2 ++ contents/word/_rels/numbering.xml.rels | 2 ++ contents/word/_rels/settings.xml.rels | 2 ++ contents/word/media/image1.png | 0 contents/word/theme/theme1.xml | 2 ++ 36 files changed, 877 insertions(+), 313 deletions(-) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f4e45e9 100644 --- /dev/null +++ a/.gitignore @@ -1,0 +1,17 @@ +# Python virtual environment +venv/ + +# Python bytecode +*.pyc +__pycache__/ + +# Environment variables +.env + +# Temporary files +*.swp +*.swo +.DS_Store + +# Compressed files +*.zip diff --git a/CV.docx b/CV.docx deleted file mode 100644 index fa41516f3503c90a6cb22b3881be0e16faa46706..0000000000000000000000000000000000000000 100644 Binary files a/CV.docx and /dev/null differ diff --git a/CV.pdf b/CV.pdf deleted file mode 100644 index abd4a4d473629eb70a70627ead7da8f1cdb965a2..0000000000000000000000000000000000000000 100644 Binary files a/CV.pdf and /dev/null differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ed6a3c8 100644 --- /dev/null +++ a/Makefile @@ -1,0 +1,26 @@ +# Variables +docm=cv.docm +vba_dir=src + +# Default target +all: compress + +# Target to extract the .docm file and VBA code using your Python script +extract: extract_vba + +# Target to extract VBA code using your Python script +extract_vba: + @mkdir -p $(vba_dir) + @python3 python_build/extract_vba.py $(docm) $(vba_dir) + +# Target to compress the extracted content back into the .docm file using your Python script +compress: insert_vba + @python3 python_build/compile_vba.py $(vba_dir) $(docm) + +# Target to reinsert VBA code into the .docm file using your Python script +insert_vba: + @python3 python_build/compile_vba.py $(vba_dir) $(docm) + +# Clean up the extraction directory +clean: + @rm -rf $(vba_dir) diff --git a/README.org b/README.org new file mode 100644 index 0000000..0469959 100644 --- /dev/null +++ a/README.org @@ -1,0 +1,18 @@ +* YAML CV Generator + +** Features to implement +[*] YAML parsing function +[*] YAML class which can be instantiated +[*] docx writing functionality +[ ] proper formatting +*** Human-readable CV +[ ] phone/web/mail/etc icons +[ ] right-justified years and locations +[ ] footer +*** Machine-readable CV +[ ] everything +*** Build system +[ ] proper python scripts for extracting VBAProject.bin (olevba) +[ ] proper python scripts for re-injecting VBAProject.bin (maybe not possible) +*** Other things +[ ] LaTeX CV generator from the same YAML diff --git a/YAMLParser.bas b/YAMLParser.bas deleted file mode 100644 index 4bbe8e8..0000000 100644 --- a/YAMLParser.bas +++ /dev/null @@ -1,313 +1,0 @@ -Attribute VB_Name = "YAMLParser" -Option Explicit - -Const yamlPath As String = "\\Mac\iCloud\Development\cv\cv.yml" - -Const selfIdentifier As String = "___self___" -Const typeIdentifier As String = "___type___" -Const errIdentifier As String = "YAML Error in " & yamlPath - -Const malformedTypeError As String = "Malformed YAML code at " & yamlPath & " on line " -Const malformedYAMLError As String = "Malformed type error - this is a problem with the internal dictionary" - -Function RemoveEmptyStrings(arr() As String) As String() - Dim tempArray() As String - Dim i As Integer, j As Integer: j = 0 - ReDim tempArray(LBound(arr) To UBound(arr)) - j = 0 - For i = LBound(arr) To UBound(arr) - If Len(arr(i)) > 0 Then - tempArray(j) = arr(i) - j = j + 1 - End If - Next i - ReDim Preserve tempArray(0 To j - 1) - RemoveEmptyStrings = tempArray -End Function - - -Function RegexMatch(inputString As String, pattern As String, Optional isGlobal As Boolean = True) As Boolean - ' checks for regex match without instantiating 80 gazillion objects - - ' parameters - ' isGlobal: whether the regex check is global - - Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") - Regex.pattern = pattern - Regex.Global = isGlobal - RegexMatch = Regex.Test(inputString) -End Function - -Function RegexSplit(inputString As String, pattern As String, Optional onlyFirst As Boolean = False, Optional splitBefore As Boolean = False) As String() - ' splits array at any pattern that matches a regex - - ' parameters - ' onlyFirst: if true, only splits the first instance of the match, creating an array of length 2 - ' splitBefore: if true, preserves the actual instance of the match - - Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") - Dim matches As Object - Dim match As Object - Dim splitParts() As String: ReDim splitParts(0 To 0) - Dim pos As Integer - Dim lastPos As Integer: lastPos = 1 - Dim i As Integer: i = 0 - - ' set regex flags - Regex.Global = True - Regex.IgnoreCase = False - Regex.pattern = pattern - - Set matches = Regex.Execute(inputString) - - ' lastPos = 1 - ' i = 0 - - For Each match In matches - pos = match.FirstIndex + 1 - ReDim Preserve splitParts(i) - splitParts(i) = Mid(inputString, lastPos, pos - lastPos) - If splitBefore Then - lastPos = pos - Else - lastPos = pos + Len(match.Value) - End If - i = i + 1 - If onlyFirst Then Exit For - Next match - - If lastPos <= Len(inputString) Then - ReDim Preserve splitParts(i) - splitParts(i) = Mid(inputString, lastPos) - End If - - ' retvrn - RegexSplit = RemoveEmptyStrings(splitParts) -End Function - -Function RegexSubstitute(inputString As String, pattern As String, Optional substitution As String = "") - ' does what it says on the tin - Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") - Regex.pattern = pattern - Regex.IgnoreCase = False - Regex.Global = True - RegexSubstitute = Regex.Replace(inputString, substitution) -End Function - -' YAML Layer Parser Pseudocode -' ==== -' function GetYAMLLayerAsCollection(String fromYAML) { -' Collection mainDictionary = New Collection(); -' if (fromYAML.containsRegex(/\n[A-Za-z]/)) { -' // is a dictionary -' String[] temporaryArray = fromYAML.split(/\n[A-Za-z]/); -' for each x in temporaryArray { -' x.splitByFirstInstanceOf(':\n'); -' x[1].replaceAllInstancesOf(' -' mainDictionary.add(x[0], x[1]); -' } -' } else if (fromYAML.containsRegex(/\n-/)) { -' // if array, process the array and return it as "self" -' String[] temporaryArray = fromYAML.splitBy('\n-'); -' for each x in temporaryArray { -' x.removeAllInstancesOf('\n- '); -' x.replaceAllInstancesOf('\n ', '\n'); -' mainDictionary.add("self", temporaryArray); -' } -' } else if (fromYAML.startsWith('"')) { -' mainDictionary.add("self", removeQuotes(fromYAML)); -' } else { -' MsgBox("Processing error: neither array, dictionary, nor string"); -' } -' } - - -Function GetYAMLLayerAsDictionary(fromYAML As String) As Dictionary - Dim mainDictionary As Dictionary: Set mainDictionary = New Dictionary - ' create regex objects to test for dict, array, and string - - 'Dim regEx_dict As Object: Set regEx_dict = CreateObject("VBScript.RegExp") - 'Dim regEx_arry As Object: Set regEx_arry = CreateObject("VBScript.RegExp") - 'Dim regEx_strn As Object: Set regEx_strn = CreateObject("VBScript.RegExp") - - 'regEx_dict.Global = True: regEx_dict.Pattern = "\n[A-Za-z]" - 'regEx_arry.Global = True: regEx_arry.Pattern = "\n-\s" - 'regEx_strn.Global = False: regEx_strn.Pattern = "^\s*""(.*?)""\s*$" - - Dim parts() As String - - If RegexMatch(fromYAML, "(?:\n|\^)\w+:", True) Then - ' is a dictionary - parts = RegexSplit(fromYAML, "\n\w+:", False, True) - Dim part As Variant ' not sure why it can't be as string but whatever billy gates - Call mainDictionary.Add(typeIdentifier, "Dictionary") ' identify as dict - For Each part In parts - Dim keyValue() As String: keyValue = RegexSplit(CStr(part), ":\s", True) - ' trim trailing \n from category - If UBound(keyValue) > 0 Then - keyValue(0) = RegexSubstitute(keyValue(0), "^\n+") - ' trim 2 spaces off of each line if they're there - keyValue(1) = RegexSubstitute(keyValue(1), "^\s{2}") - keyValue(1) = RegexSubstitute(keyValue(1), "\n\s{2}", vbLf) - Call mainDictionary.Add(keyValue(0), keyValue(1)) - End If - Next part - ElseIf RegexMatch(fromYAML, "^-\s", True) Then - ' is an array - Call mainDictionary.Add(typeIdentifier, "Array") - parts = RegexSplit(fromYAML, "(^|\n)-\s", False) - Dim i As Integer - For i = LBound(parts) To UBound(parts) - parts(i) = RegexSubstitute(parts(i), "\n\s{2}", vbLf) - Next i - Call mainDictionary.Add(selfIdentifier, parts) - ElseIf RegexMatch(fromYAML, "^\s*""(.*?)""\s*$", True) Then - ' is a string - Call mainDictionary.Add(typeIdentifier, "String") - Call mainDictionary.Add(selfIdentifier, RegexSubstitute(fromYAML, """", "")) - Else - Call mainDictionary.Add(selfIdentifier, "") - Debug.Print _ - "Neither array, dictionary, nor string:" & _ - vbCrLf & vbCrLf & fromYAML & vbCrLf & vbCrLf & _ - "Make sure all strings are enclosed in double quotes." ', _ - 'vbOKOnly, "YAML Error") - End If - - Set GetYAMLLayerAsDictionary = mainDictionary -End Function - -' YAML Traverser Pseudocode -' === -' -' function TraverseYAML(String fromYAML) { -' Dictionary mainDictionary = GetYAMLLayerAsDictionary(fromYAML); -' if mainDictionary.___type___ = "Dictionary" { -' for each entry in mainDictionary { -' TraverseYAML(entry) -' } -' return mainDictionary; -' } else if mainDictionary.___type___ = "Array" { -' for each entry in mainDictionary.___self___ { -' TraverseYAML(entry) -' } -' return mainDictionary; -' } else if mainDictionary.___type___ = "String" { -' return mainDictionary; -' } else { -' MsgBox("Internal YAML Error") -' } -' } -Function GetYAMLAsDictionary(fromYAML As String) As Dictionary - Dim mainDictionary As Object: Set mainDictionary = GetYAMLLayerAsDictionary(fromYAML) - Dim entry As Variant - If mainDictionary(typeIdentifier) = "Dictionary" Then - For Each entry In mainDictionary - Debug.Print "=== PROCESSING DICTIONARY ENTRY ===" - Debug.Print entry & " => " & mainDictionary(entry) - If entry <> typeIdentifier And entry <> selfIdentifier Then - Set mainDictionary(entry) = GetYAMLAsDictionary(mainDictionary(entry)) - End If - Next entry - ElseIf mainDictionary(typeIdentifier) = "Array" Then - Dim i As Integer - Dim subArray() As Object - For i = LBound(mainDictionary(selfIdentifier)) To UBound(mainDictionary(selfIdentifier)) - Debug.Print "=== PROCESSING ARRAY ENTRY ===" - Debug.Print mainDictionary(selfIdentifier)(i) - 'Set subDictionary = GetYAMLAsDictionary(mainDictionary(selfIdentifier)(i)) - 'Set mainDictionary(selfIdentifier)(i) = subDictionary - ReDim Preserve subArray(i) - Set subArray(i) = GetYAMLAsDictionary(CStr(mainDictionary(selfIdentifier)(i))) - Next i - - mainDictionary(selfIdentifier) = subArray - ElseIf mainDictionary(typeIdentifier) <> "String" Then - Debug.Print malformedTypeError ', vbOKOnly, errIdentifier) - End If - Set GetYAMLAsDictionary = mainDictionary -End Function - -' YAML Cleaner Pseudocode -' ===== -' function YAMLCleaner(Dictionary mainDictionary) { -' for each entry in mainDictionary { -' if entry(typeIdentifier) == "Dictionary" { -' for each secondOrderEntry in entry { -' YAMLCleaner(secondOrderEntry) -' } -' } else if entry(typeIdentifier) == "Array" { -' for each secondOrderEntry in entry(selfIdentifier) { -' YAMLCleaner(secondOrderEntry) -' } -' } -' if entry(typeIdentifier) != "Dictionary" { -' mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) -' } -' } -' return mainDictionary; -' } - -Function YAMLCleaner(mainDictionary As Dictionary) As Dictionary - Dim entry As Variant - If mainDictionary(typeIdentifier) = "Array" Then ' go through array and yamlclean it - Dim i As Integer - Debug.Print JsonConverter.ConvertToJson(mainDictionary) - For i = LBound(mainDictionary(selfIdentifier)) To UBound(mainDictionary(selfIdentifier)) - - 'If IsObject(mainDictionary(selfIdentifier)(i)) Then - 'Set mainDictionary(selfIdentifier)(i) = YAMLCleaner(mainDictionary(selfIdentifier)(i)) - 'Else - ' Debug.Print "encountered non-object" - 'End If - Next i - End If - If mainDictionary(typeIdentifier) = "Dictionary" Then 'iterate through dict and yamlclena it - For Each entry In mainDictionary - If entry <> typeIdentifier Then - Set mainDictionary(entry) = YAMLCleaner(mainDictionary(entry)) - End If - Next entry - End If - - For Each entry In mainDictionary - If mainDictionary(typeIdentifier) = "Dictionary" And mainDictionary(entry)(typeIdentifier) <> "Dictionary" And entry <> typeIdentifier And entry <> selfIdentifier Then - Debug.Print "processing " & entry & " which is " & mainDictionary(entry)(typeIdentifier) - If IsObject(mainDictionary(entry)(selfIdentifier)) Then - Set mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) - Else - mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) - End If - End If - Next entry - - ' destroy type identifier? - Set YAMLCleaner = mainDictionary -End Function - -Function GetFileAsString(filePath As String) As String - ' Dim fileContent As String - Dim line As String - Dim fileNumber As Integer - - 'filePath = "\\Mac\iCloud\Development\cv\cv.yml" - - fileNumber = FreeFile() - - Open filePath For Input As fileNumber - - Do While Not EOF(fileNumber) - Line Input #fileNumber, line - GetFileAsString = GetFileAsString & line & vbCrLf - Loop -End Function - -Sub TryFunction() - Dim fileString As String: fileString = GetFileAsString("\\Mac\iCloud\Development\cv\cv.yml") - Dim yamlLayer As Object - Set yamlLayer = GetYAMLLayerAsDictionary(fileString) - Dim yamlWholeDict As Object: Set yamlWholeDict = GetYAMLAsDictionary(fileString) - 'Debug.Print JsonConverter.ConvertToJson(yamlWholeDict, 2, 2) - Dim yamlCleanDict As Object: Set yamlCleanDict = YAMLCleaner(yamlWholeDict) - Debug.Print JsonConverter.ConvertToJson(yamlCleanDict, 2, 2) -End Sub diff --git a/cv.docm b/cv.docm new file mode 100644 index 0000000000000000000000000000000000000000..11f919716d083fab8a94909bb2418ce81c57d78c 100644 Binary files /dev/null and a/cv.docm differ diff --git a/cv.docm.bak b/cv.docm.bak new file mode 100644 index 0000000000000000000000000000000000000000..11f919716d083fab8a94909bb2418ce81c57d78c 100644 Binary files /dev/null and a/cv.docm.bak differ diff --git a/cv.dotx b/cv.dotx new file mode 100644 index 0000000000000000000000000000000000000000..ac1658a3c806aee97981ec683402a448ba6ccf95 100644 Binary files /dev/null and a/cv.dotx differ diff --git a/cv.thmx b/cv.thmx deleted file mode 100644 index 97d178c3128375242d0290bd9650ddba2228e6c3..0000000000000000000000000000000000000000 100644 Binary files a/cv.thmx and /dev/null differ diff --git a/~$CV.docx b/~$CV.docx deleted file mode 100644 index a938d1922414b7485829851f230fe71618892034..0000000000000000000000000000000000000000 100644 Binary files a/~$CV.docx and /dev/null differ diff --git a/contents/[Content_Types].xml b/contents/[Content_Types].xml new file mode 100644 index 0000000..942889d 100644 --- /dev/null +++ a/contents/[Content_Types].xml @@ -1,0 +1,2 @@ + +diff --git a/examples/CV.docx b/examples/CV.docx new file mode 100644 index 0000000000000000000000000000000000000000..fa41516f3503c90a6cb22b3881be0e16faa46706 100644 Binary files /dev/null and a/examples/CV.docx differ diff --git a/examples/CV.pdf b/examples/CV.pdf new file mode 100644 index 0000000000000000000000000000000000000000..abd4a4d473629eb70a70627ead7da8f1cdb965a2 100644 Binary files /dev/null and a/examples/CV.pdf differ diff --git a/python_build/compile_vba.py b/python_build/compile_vba.py new file mode 100644 index 0000000..8a41eb8 100644 --- /dev/null +++ a/python_build/compile_vba.py @@ -1,0 +1,27 @@ +from vbaProjectCompiler.vbaProject import VbaProject +from vbaProjectCompiler.ole_file import OleFile + +def compile_vba(input_dir, docm_file): + # Initialize the VbaProject object + vba_project = VbaProject() + + # Load the VBA project from the extracted directory + vba_project.addDirectory(input_dir) + + # Create the OLE file with the VBA project + ole_file = OleFile(vba_project) + ole_file.writeFile(docm_file) + + print(f"VBA project compiled and saved to {docm_file}") + +if __name__ == "__main__": + import sys + + if len(sys.argv) != 3: + print("Usage: python compile_vba.py ") + sys.exit(1) + + input_dir = sys.argv[1] + docm_file = sys.argv[2] + + compile_vba(input_dir, docm_file) diff --git a/python_build/extract_vba.py b/python_build/extract_vba.py new file mode 100644 index 0000000..9429ad8 100644 --- /dev/null +++ a/python_build/extract_vba.py @@ -1,0 +1,32 @@ +from oletools.olevba import VBA_Parser +import os + +def extract_vba(docm_file, output_dir): + # Ensure output directory exists + os.makedirs(output_dir, exist_ok=True) + + # Parse the .docm file to extract VBA code + vba_parser = VBA_Parser(docm_file) + if vba_parser.detect_vba_macros(): + for (filename, stream_path, vba_filename, vba_code) in vba_parser.extract_macros(): + # Save each extracted VBA file to the output directory + output_file_path = os.path.join(output_dir, vba_filename) + with open(output_file_path, 'w') as vba_file: + vba_file.write(vba_code) + print(f"Extracted {vba_filename} to {output_file_path}") + else: + print("No VBA macros found in the document.") + + vba_parser.close() + +if __name__ == "__main__": + import sys + + if len(sys.argv) != 3: + print("Usage: python extract_vba.py ") + sys.exit(1) + + docm_file = sys.argv[1] + output_dir = sys.argv[2] + + extract_vba(docm_file, output_dir) diff --git a/contents/_rels/.rels b/contents/_rels/.rels new file mode 100644 index 0000000..fdd8c4f 100644 --- /dev/null +++ a/contents/_rels/.rels @@ -1,0 +1,2 @@ + +diff --git a/contents/customXml/item1.xml b/contents/customXml/item1.xml new file mode 100644 index 0000000..df14848 100644 --- /dev/null +++ a/contents/customXml/item1.xml @@ -1,0 +1,1 @@ +diff --git a/contents/customXml/itemProps1.xml b/contents/customXml/itemProps1.xml new file mode 100644 index 0000000..9402714 100644 --- /dev/null +++ a/contents/customXml/itemProps1.xml @@ -1,0 +1,2 @@ + +diff --git a/contents/docProps/app.xml b/contents/docProps/app.xml new file mode 100644 index 0000000..0282abe 100644 --- /dev/null +++ a/contents/docProps/app.xml @@ -1,0 +1,2 @@ + +496100Microsoft Office Word000falseTitle1false0falsefalse16.0000diff --git a/contents/docProps/core.xml b/contents/docProps/core.xml new file mode 100644 index 0000000..53ee84d 100644 --- /dev/null +++ a/contents/docProps/core.xml @@ -1,0 +1,2 @@ + +Jacob WalchukJacob Walchuk12024-08-20T16:37:00Z2024-08-21T00:53:00Zdiff --git a/contents/word/document.xml b/contents/word/document.xml new file mode 100644 index 0000000..2e8ffdb 100644 --- /dev/null +++ a/contents/word/document.xml @@ -1,0 +1,2 @@ + +diff --git a/contents/word/fontTable.xml b/contents/word/fontTable.xml new file mode 100644 index 0000000..a0065f3 100644 --- /dev/null +++ a/contents/word/fontTable.xml @@ -1,0 +1,2 @@ + +diff --git a/contents/word/numbering.xml b/contents/word/numbering.xml new file mode 100644 index 0000000..eefd20c 100644 --- /dev/null +++ a/contents/word/numbering.xml @@ -1,0 +1,2 @@ + +diff --git a/contents/word/settings.xml b/contents/word/settings.xml new file mode 100644 index 0000000..d51770c 100644 --- /dev/null +++ a/contents/word/settings.xml @@ -1,0 +1,2 @@ + +diff --git a/contents/word/styles.xml b/contents/word/styles.xml new file mode 100644 index 0000000..2d1dcd8 100644 --- /dev/null +++ a/contents/word/styles.xml @@ -1,0 +1,2 @@ + +diff --git a/contents/word/webSettings.xml b/contents/word/webSettings.xml new file mode 100644 index 0000000..74c1519 100644 --- /dev/null +++ a/contents/word/webSettings.xml @@ -1,0 +1,2 @@ + +diff --git a/src/Class Modules/YAML.cls b/src/Class Modules/YAML.cls new file mode 100644 index 0000000..92b84ad 100644 --- /dev/null +++ a/src/Class Modules/YAML.cls @@ -1,0 +1,353 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "YAML" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +' Const yamlPath As String = "\\Mac\iCloud\Development\cv\cv.yml" + +' enums + +Public yamlPath As String +Public yamlSerialised As Dictionary + +Private Const ID_SELF As String = "___self___" +Private Const ID_TYPE As String = "___type___" + +Private Const MESSAGE_ERROR_GENERIC As String = "YAML Error in " & yamlPath +Private Const MESSAGE_MALFORMED_TYPE As String = "Malformed YAML code at " & yamlPath & " on line " +Private Const MESSAGE_MALFORMED_YAML As String = "Malformed type error - this is a problem with the internal dictionary" +Private Const MESSAGE_GETPROP_NOT_STR As String = "Your module has tried to use getProp(), which is meant for type String, on a " +Private Const MESSAGE_GETPROP_NOT_FOUND As String = "Property not found." + +Private Function RemoveEmptyStrings(arr() As String) As String() + Dim tempArray() As String + Dim i As Integer, j As Integer: j = 0 + ReDim tempArray(LBound(arr) To UBound(arr)) + j = 0 + For i = LBound(arr) To UBound(arr) + If Len(arr(i)) > 0 Then + tempArray(j) = arr(i) + j = j + 1 + End If + Next i + ReDim Preserve tempArray(0 To j - 1) + RemoveEmptyStrings = tempArray +End Function + + +Private Function RegexMatch(inputString As String, pattern As String, Optional isGlobal As Boolean = True) As Boolean + ' checks for regex match without instantiating 80 gazillion objects + + ' parameters + ' isGlobal: whether the regex check is global + + Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") + Regex.pattern = pattern + Regex.Global = isGlobal + RegexMatch = Regex.Test(inputString) +End Function + +Private Function RegexSplit(inputString As String, pattern As String, Optional onlyFirst As Boolean = False, Optional splitBefore As Boolean = False) As String() + ' splits array at any pattern that matches a regex + + ' parameters + ' onlyFirst: if true, only splits the first instance of the match, creating an array of length 2 + ' splitBefore: if true, preserves the actual instance of the match + + Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") + Dim matches As Object + Dim match As Object + Dim splitParts() As String: ReDim splitParts(0 To 0) + Dim pos As Integer + Dim lastPos As Integer: lastPos = 1 + Dim i As Integer: i = 0 + + ' set regex flags + Regex.Global = True + Regex.IgnoreCase = False + Regex.pattern = pattern + + Set matches = Regex.Execute(inputString) + + ' lastPos = 1 + ' i = 0 + + For Each match In matches + pos = match.FirstIndex + 1 + ReDim Preserve splitParts(i) + splitParts(i) = Mid(inputString, lastPos, pos - lastPos) + If splitBefore Then + lastPos = pos + Else + lastPos = pos + Len(match.Value) + End If + i = i + 1 + If onlyFirst Then Exit For + Next match + + If lastPos <= Len(inputString) Then + ReDim Preserve splitParts(i) + splitParts(i) = Mid(inputString, lastPos) + End If + + ' retvrn + RegexSplit = RemoveEmptyStrings(splitParts) +End Function + +Private Function RegexSubstitute(inputString As String, pattern As String, Optional substitution As String = "") + ' does what it says on the tin + Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") + Regex.pattern = pattern + Regex.IgnoreCase = False + Regex.Global = True + RegexSubstitute = Regex.Replace(inputString, substitution) +End Function + +' YAML Layer Parser Pseudocode +' ==== +' function GetYAMLLayerAsCollection(String fromYAML) { +' Collection mainDictionary = New Collection(); +' if (fromYAML.containsRegex(/\n[A-Za-z]/)) { +' // is a dictionary +' String[] temporaryArray = fromYAML.split(/\n[A-Za-z]/); +' for each x in temporaryArray { +' x.splitByFirstInstanceOf(':\n'); +' x[1].replaceAllInstancesOf(' +' mainDictionary.add(x[0], x[1]); +' } +' } else if (fromYAML.containsRegex(/\n-/)) { +' // if array, process the array and return it as "self" +' String[] temporaryArray = fromYAML.splitBy('\n-'); +' for each x in temporaryArray { +' x.removeAllInstancesOf('\n- '); +' x.replaceAllInstancesOf('\n ', '\n'); +' mainDictionary.add("self", temporaryArray); +' } +' } else if (fromYAML.startsWith('"')) { +' mainDictionary.add("self", removeQuotes(fromYAML)); +' } else { +' MsgBox("Processing error: neither array, dictionary, nor string"); +' } +' } + + +Private Function GetYAMLLayerAsDictionary(fromYAML As String) As Dictionary + Dim mainDictionary As Dictionary: Set mainDictionary = New Dictionary + ' create regex objects to test for dict, array, and string + + 'Dim regEx_dict As Object: Set regEx_dict = CreateObject("VBScript.RegExp") + 'Dim regEx_arry As Object: Set regEx_arry = CreateObject("VBScript.RegExp") + 'Dim regEx_strn As Object: Set regEx_strn = CreateObject("VBScript.RegExp") + + 'regEx_dict.Global = True: regEx_dict.Pattern = "\n[A-Za-z]" + 'regEx_arry.Global = True: regEx_arry.Pattern = "\n-\s" + 'regEx_strn.Global = False: regEx_strn.Pattern = "^\s*""(.*?)""\s*$" + + Dim parts() As String + + If RegexMatch(fromYAML, "(?:\n|\^)\w+:", True) Then + ' is a dictionary + parts = RegexSplit(fromYAML, "\n\w+:", False, True) + Dim part As Variant ' not sure why it can't be as string but whatever billy gates + Call mainDictionary.Add(typeIdentifier, "Dictionary") ' identify as dict + For Each part In parts + Dim keyValue() As String: keyValue = RegexSplit(CStr(part), ":\s", True) + ' trim trailing \n from category + If UBound(keyValue) > 0 Then + keyValue(0) = RegexSubstitute(keyValue(0), "^\n+") + ' trim 2 spaces off of each line if they're there + keyValue(1) = RegexSubstitute(keyValue(1), "^\s{2}") + keyValue(1) = RegexSubstitute(keyValue(1), "\n\s{2}", vbLf) + Call mainDictionary.Add(keyValue(0), keyValue(1)) + End If + Next part + ElseIf RegexMatch(fromYAML, "^-\s", True) Then + ' is an array + Call mainDictionary.Add(typeIdentifier, "Array") + parts = RegexSplit(fromYAML, "(^|\n)-\s", False) + Dim i As Integer + For i = LBound(parts) To UBound(parts) + parts(i) = RegexSubstitute(parts(i), "\n\s{2}", vbLf) + Next i + Call mainDictionary.Add(selfIdentifier, parts) + ElseIf RegexMatch(fromYAML, "^\s*""(.*?)""\s*$", True) Then + ' is a string + Call mainDictionary.Add(typeIdentifier, "String") + Call mainDictionary.Add(selfIdentifier, RegexSubstitute(fromYAML, """", "")) + Else + Call mainDictionary.Add(selfIdentifier, "") + Debug.Print _ + "Neither array, dictionary, nor string:" & _ + vbCrLf & vbCrLf & fromYAML & vbCrLf & vbCrLf & _ + "Make sure all strings are enclosed in double quotes." ', _ + 'vbOKOnly, "YAML Error") + End If + + Set GetYAMLLayerAsDictionary = mainDictionary +End Function + +' YAML Traverser Pseudocode +' === +' +' function TraverseYAML(String fromYAML) { +' Dictionary mainDictionary = GetYAMLLayerAsDictionary(fromYAML); +' if mainDictionary.___type___ = "Dictionary" { +' for each entry in mainDictionary { +' TraverseYAML(entry) +' } +' return mainDictionary; +' } else if mainDictionary.___type___ = "Array" { +' for each entry in mainDictionary.___self___ { +' TraverseYAML(entry) +' } +' return mainDictionary; +' } else if mainDictionary.___type___ = "String" { +' return mainDictionary; +' } else { +' MsgBox("Internal YAML Error") +' } +' } +Private Function GetYAMLAsDictionary(fromYAML As String) As Dictionary + Dim mainDictionary As Object: Set mainDictionary = GetYAMLLayerAsDictionary(fromYAML) + Dim entry As Variant + If mainDictionary(typeIdentifier) = "Dictionary" Then + For Each entry In mainDictionary + Debug.Print "=== PROCESSING DICTIONARY ENTRY ===" + Debug.Print entry & " => " & mainDictionary(entry) + If entry <> typeIdentifier And entry <> selfIdentifier Then + Set mainDictionary(entry) = GetYAMLAsDictionary(mainDictionary(entry)) + End If + Next entry + ElseIf mainDictionary(typeIdentifier) = "Array" Then + Dim i As Integer + Dim subArray() As Object + For i = LBound(mainDictionary(selfIdentifier)) To UBound(mainDictionary(selfIdentifier)) + Debug.Print "=== PROCESSING ARRAY ENTRY ===" + Debug.Print mainDictionary(selfIdentifier)(i) + 'Set subDictionary = GetYAMLAsDictionary(mainDictionary(selfIdentifier)(i)) + 'Set mainDictionary(selfIdentifier)(i) = subDictionary + ReDim Preserve subArray(i) + Set subArray(i) = GetYAMLAsDictionary(CStr(mainDictionary(selfIdentifier)(i))) + Next i + + mainDictionary(selfIdentifier) = subArray + ElseIf mainDictionary(typeIdentifier) <> "String" Then + Debug.Print malformedTypeError ', vbOKOnly, errIdentifier) + End If + Set GetYAMLAsDictionary = mainDictionary +End Function + +' YAML Cleaner Pseudocode +' ===== +' function YAMLCleaner(Dictionary mainDictionary) { +' for each entry in mainDictionary { +' if entry(typeIdentifier) == "Dictionary" { +' for each secondOrderEntry in entry { +' YAMLCleaner(secondOrderEntry) +' } +' } else if entry(typeIdentifier) == "Array" { +' for each secondOrderEntry in entry(selfIdentifier) { +' YAMLCleaner(secondOrderEntry) +' } +' } +' if entry(typeIdentifier) != "Dictionary" { +' mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) +' } +' } +' return mainDictionary; +' } + +'Function YAMLCleaner(mainDictionary As Dictionary) As Dictionary +' Dim entry As Variant +' If mainDictionary(typeIdentifier) = "Array" Then ' go through array and yamlclean it +' Dim i As Integer +' Debug.Print JsonConverter.ConvertToJson(mainDictionary) +' For i = LBound(mainDictionary(selfIdentifier)) To UBound(mainDictionary(selfIdentifier)) +' +' 'If IsObject(mainDictionary(selfIdentifier)(i)) Then +' 'Set mainDictionary(selfIdentifier)(i) = YAMLCleaner(mainDictionary(selfIdentifier)(i)) +' 'Else +' ' Debug.Print "encountered non-object" +' 'End If +' Next i +' End If +' If mainDictionary(typeIdentifier) = "Dictionary" Then 'iterate through dict and yamlclena it +' For Each entry In mainDictionary +' If entry <> typeIdentifier Then +' Set mainDictionary(entry) = YAMLCleaner(mainDictionary(entry)) +' End If +' Next entry +' End If +' +' For Each entry In mainDictionary +' If mainDictionary(typeIdentifier) = "Dictionary" And mainDictionary(entry)(typeIdentifier) <> "Dictionary" And entry <> typeIdentifier And entry <> selfIdentifier Then +' Debug.Print "processing " & entry & " which is " & mainDictionary(entry)(typeIdentifier) +' If IsObject(mainDictionary(entry)(selfIdentifier)) Then +' Set mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) +' Else +' mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) +' End If +' End If +' Next entry +' +' ' destroy type identifier? +' Set YAMLCleaner = mainDictionary +'End Function + +Private Function GetFileAsString(filePath As String) As String + ' Dim fileContent As String + Dim line As String + Dim fileNumber As Integer + + 'filePath = "\\Mac\iCloud\Development\cv\cv.yml" + + fileNumber = FreeFile() + + Open filePath For Input As fileNumber + + Do While Not EOF(fileNumber) + Line Input #fileNumber, line + GetFileAsString = GetFileAsString & line & vbCrLf + Loop +End Function + +Public Property Let path(thePath As String) + yamlPath = thePath +End Property + +Public Property Get path() As String + path = yamlPath +End Property + +Public Property Get props() As Dictionary + Set props = GetYAMLAsDictionary(GetFileAsString(yamlPath)) +End Property + +' YAML Indexer Pseudocode [implement later] +' ===== +' function index(string theIndex) { +' Variant[] mainArray = theIndex.split("."); +' Dictionary mainDictionary = yamlProps; +' for each entry in mainArray { +' if entry is { +' +' .... + + +'Public Sub TryFunction() +' Dim fileString As String: fileString = GetFileAsString("\\Mac\iCloud\Development\cv\cv.yml") +' Dim yamlLayer As Object +' Set yamlLayer = GetYAMLLayerAsDictionary(fileString) +' Dim yamlWholeDict As Object: Set yamlWholeDict = GetYAMLAsDictionary(fileString) +' 'Debug.Print JsonConverter.ConvertToJson(yamlWholeDict, 2, 2) +' Dim yamlCleanDict As Object: Set yamlCleanDict = YAMLCleaner(yamlWholeDict) +' Debug.Print JsonConverter.ConvertToJson(yamlCleanDict, 2, 2) +'End Sub + + diff --git a/src/Modules/NewMacros.bas b/src/Modules/NewMacros.bas new file mode 100644 index 0000000..96f47ca 100644 --- /dev/null +++ a/src/Modules/NewMacros.bas @@ -1,0 +1,58 @@ +Attribute VB_Name = "NewMacros" +Option Explicit + +Sub Macro1() +Attribute Macro1.VB_ProcData.VB_Invoke_Func = "Normal.NewMacros.Macro1" +' +' Macro1 Macro +' +' + Selection.Style = ActiveDocument.Styles("Title") + Selection.TypeText Text:="This is a title" + Selection.TypeParagraph + Selection.TypeParagraph + Selection.Style = ActiveDocument.Styles("Heading 1") + Selection.TypeText Text:="Heading 1" + Selection.TypeParagraph + Selection.Style = ActiveDocument.Styles("No Spacing") + Selection.TypeText Text:="Whatababab" + Selection.TypeParagraph + With ListGalleries(wdBulletGallery).ListTemplates(1).ListLevels(1) + .NumberFormat = ChrW(61623) + .TrailingCharacter = wdTrailingTab + .NumberStyle = wdListNumberStyleBullet + .NumberPosition = InchesToPoints(0.25) + .Alignment = wdListLevelAlignLeft + .TextPosition = InchesToPoints(0.5) + .TabPosition = wdUndefined + .ResetOnHigher = 0 + .StartAt = 1 + With .Font + .Bold = wdUndefined + .Italic = wdUndefined + .StrikeThrough = wdUndefined + .Subscript = wdUndefined + .Superscript = wdUndefined + .Shadow = wdUndefined + .Outline = wdUndefined + .Emboss = wdUndefined + .Engrave = wdUndefined + .AllCaps = wdUndefined + .Hidden = wdUndefined + .Underline = wdUndefined + .Color = wdUndefined + .Size = wdUndefined + .Animation = wdUndefined + .DoubleStrikeThrough = wdUndefined + .Name = "Symbol" + End With + .LinkedStyle = "" + End With + ListGalleries(wdBulletGallery).ListTemplates(1).Name = "" + Selection.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _ + ListGalleries(wdBulletGallery).ListTemplates(1), ContinuePreviousList:= _ + False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _ + wdWord10ListBehavior + Selection.TypeText Text:="This is a bulletted list created manually" + Selection.EscapeKey +End Sub diff --git a/src/Modules/YAMLParser_old.bas b/src/Modules/YAMLParser_old.bas new file mode 100644 index 0000000..cfcd417 100644 --- /dev/null +++ a/src/Modules/YAMLParser_old.bas @@ -1,0 +1,313 @@ +Attribute VB_Name = "YAMLParser_old" +Option Explicit + +Const yamlPath As String = "\\Mac\iCloud\Development\cv\cv.yml" + +Const selfIdentifier As String = "___self___" +Const typeIdentifier As String = "___type___" +Const errIdentifier As String = "YAML Error in " & yamlPath + +Const malformedTypeError As String = "Malformed YAML code at " & yamlPath & " on line " +Const malformedYAMLError As String = "Malformed type error - this is a problem with the internal dictionary" + +Function RemoveEmptyStrings(arr() As String) As String() + Dim tempArray() As String + Dim i As Integer, j As Integer: j = 0 + ReDim tempArray(LBound(arr) To UBound(arr)) + j = 0 + For i = LBound(arr) To UBound(arr) + If Len(arr(i)) > 0 Then + tempArray(j) = arr(i) + j = j + 1 + End If + Next i + ReDim Preserve tempArray(0 To j - 1) + RemoveEmptyStrings = tempArray +End Function + + +Function RegexMatch(inputString As String, pattern As String, Optional isGlobal As Boolean = True) As Boolean + ' checks for regex match without instantiating 80 gazillion objects + + ' parameters + ' isGlobal: whether the regex check is global + + Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") + Regex.pattern = pattern + Regex.Global = isGlobal + RegexMatch = Regex.Test(inputString) +End Function + +Function RegexSplit(inputString As String, pattern As String, Optional onlyFirst As Boolean = False, Optional splitBefore As Boolean = False) As String() + ' splits array at any pattern that matches a regex + + ' parameters + ' onlyFirst: if true, only splits the first instance of the match, creating an array of length 2 + ' splitBefore: if true, preserves the actual instance of the match + + Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") + Dim matches As Object + Dim match As Object + Dim splitParts() As String: ReDim splitParts(0 To 0) + Dim pos As Integer + Dim lastPos As Integer: lastPos = 1 + Dim i As Integer: i = 0 + + ' set regex flags + Regex.Global = True + Regex.IgnoreCase = False + Regex.pattern = pattern + + Set matches = Regex.Execute(inputString) + + ' lastPos = 1 + ' i = 0 + + For Each match In matches + pos = match.FirstIndex + 1 + ReDim Preserve splitParts(i) + splitParts(i) = Mid(inputString, lastPos, pos - lastPos) + If splitBefore Then + lastPos = pos + Else + lastPos = pos + Len(match.Value) + End If + i = i + 1 + If onlyFirst Then Exit For + Next match + + If lastPos <= Len(inputString) Then + ReDim Preserve splitParts(i) + splitParts(i) = Mid(inputString, lastPos) + End If + + ' retvrn + RegexSplit = RemoveEmptyStrings(splitParts) +End Function + +Function RegexSubstitute(inputString As String, pattern As String, Optional substitution As String = "") + ' does what it says on the tin + Dim Regex As Object: Set Regex = CreateObject("VBScript.RegExp") + Regex.pattern = pattern + Regex.IgnoreCase = False + Regex.Global = True + RegexSubstitute = Regex.Replace(inputString, substitution) +End Function + +' YAML Layer Parser Pseudocode +' ==== +' function GetYAMLLayerAsCollection(String fromYAML) { +' Collection mainDictionary = New Collection(); +' if (fromYAML.containsRegex(/\n[A-Za-z]/)) { +' // is a dictionary +' String[] temporaryArray = fromYAML.split(/\n[A-Za-z]/); +' for each x in temporaryArray { +' x.splitByFirstInstanceOf(':\n'); +' x[1].replaceAllInstancesOf(' +' mainDictionary.add(x[0], x[1]); +' } +' } else if (fromYAML.containsRegex(/\n-/)) { +' // if array, process the array and return it as "self" +' String[] temporaryArray = fromYAML.splitBy('\n-'); +' for each x in temporaryArray { +' x.removeAllInstancesOf('\n- '); +' x.replaceAllInstancesOf('\n ', '\n'); +' mainDictionary.add("self", temporaryArray); +' } +' } else if (fromYAML.startsWith('"')) { +' mainDictionary.add("self", removeQuotes(fromYAML)); +' } else { +' MsgBox("Processing error: neither array, dictionary, nor string"); +' } +' } + + +Function GetYAMLLayerAsDictionary(fromYAML As String) As Dictionary + Dim mainDictionary As Dictionary: Set mainDictionary = New Dictionary + ' create regex objects to test for dict, array, and string + + 'Dim regEx_dict As Object: Set regEx_dict = CreateObject("VBScript.RegExp") + 'Dim regEx_arry As Object: Set regEx_arry = CreateObject("VBScript.RegExp") + 'Dim regEx_strn As Object: Set regEx_strn = CreateObject("VBScript.RegExp") + + 'regEx_dict.Global = True: regEx_dict.Pattern = "\n[A-Za-z]" + 'regEx_arry.Global = True: regEx_arry.Pattern = "\n-\s" + 'regEx_strn.Global = False: regEx_strn.Pattern = "^\s*""(.*?)""\s*$" + + Dim parts() As String + + If RegexMatch(fromYAML, "(?:\n|\^)\w+:", True) Then + ' is a dictionary + parts = RegexSplit(fromYAML, "\n\w+:", False, True) + Dim part As Variant ' not sure why it can't be as string but whatever billy gates + Call mainDictionary.Add(typeIdentifier, "Dictionary") ' identify as dict + For Each part In parts + Dim keyValue() As String: keyValue = RegexSplit(CStr(part), ":\s", True) + ' trim trailing \n from category + If UBound(keyValue) > 0 Then + keyValue(0) = RegexSubstitute(keyValue(0), "^\n+") + ' trim 2 spaces off of each line if they're there + keyValue(1) = RegexSubstitute(keyValue(1), "^\s{2}") + keyValue(1) = RegexSubstitute(keyValue(1), "\n\s{2}", vbLf) + Call mainDictionary.Add(keyValue(0), keyValue(1)) + End If + Next part + ElseIf RegexMatch(fromYAML, "^-\s", True) Then + ' is an array + Call mainDictionary.Add(typeIdentifier, "Array") + parts = RegexSplit(fromYAML, "(^|\n)-\s", False) + Dim i As Integer + For i = LBound(parts) To UBound(parts) + parts(i) = RegexSubstitute(parts(i), "\n\s{2}", vbLf) + Next i + Call mainDictionary.Add(selfIdentifier, parts) + ElseIf RegexMatch(fromYAML, "^\s*""(.*?)""\s*$", True) Then + ' is a string + Call mainDictionary.Add(typeIdentifier, "String") + Call mainDictionary.Add(selfIdentifier, RegexSubstitute(fromYAML, """", "")) + Else + Call mainDictionary.Add(selfIdentifier, "") + Debug.Print _ + "Neither array, dictionary, nor string:" & _ + vbCrLf & vbCrLf & fromYAML & vbCrLf & vbCrLf & _ + "Make sure all strings are enclosed in double quotes." ', _ + 'vbOKOnly, "YAML Error") + End If + + Set GetYAMLLayerAsDictionary = mainDictionary +End Function + +' YAML Traverser Pseudocode +' === +' +' function TraverseYAML(String fromYAML) { +' Dictionary mainDictionary = GetYAMLLayerAsDictionary(fromYAML); +' if mainDictionary.___type___ = "Dictionary" { +' for each entry in mainDictionary { +' TraverseYAML(entry) +' } +' return mainDictionary; +' } else if mainDictionary.___type___ = "Array" { +' for each entry in mainDictionary.___self___ { +' TraverseYAML(entry) +' } +' return mainDictionary; +' } else if mainDictionary.___type___ = "String" { +' return mainDictionary; +' } else { +' MsgBox("Internal YAML Error") +' } +' } +Function GetYAMLAsDictionary(fromYAML As String) As Dictionary + Dim mainDictionary As Object: Set mainDictionary = GetYAMLLayerAsDictionary(fromYAML) + Dim entry As Variant + If mainDictionary(typeIdentifier) = "Dictionary" Then + For Each entry In mainDictionary + Debug.Print "=== PROCESSING DICTIONARY ENTRY ===" + Debug.Print entry & " => " & mainDictionary(entry) + If entry <> typeIdentifier And entry <> selfIdentifier Then + Set mainDictionary(entry) = GetYAMLAsDictionary(mainDictionary(entry)) + End If + Next entry + ElseIf mainDictionary(typeIdentifier) = "Array" Then + Dim i As Integer + Dim subArray() As Object + For i = LBound(mainDictionary(selfIdentifier)) To UBound(mainDictionary(selfIdentifier)) + Debug.Print "=== PROCESSING ARRAY ENTRY ===" + Debug.Print mainDictionary(selfIdentifier)(i) + 'Set subDictionary = GetYAMLAsDictionary(mainDictionary(selfIdentifier)(i)) + 'Set mainDictionary(selfIdentifier)(i) = subDictionary + ReDim Preserve subArray(i) + Set subArray(i) = GetYAMLAsDictionary(CStr(mainDictionary(selfIdentifier)(i))) + Next i + + mainDictionary(selfIdentifier) = subArray + ElseIf mainDictionary(typeIdentifier) <> "String" Then + Debug.Print malformedTypeError ', vbOKOnly, errIdentifier) + End If + Set GetYAMLAsDictionary = mainDictionary +End Function + +' YAML Cleaner Pseudocode +' ===== +' function YAMLCleaner(Dictionary mainDictionary) { +' for each entry in mainDictionary { +' if entry(typeIdentifier) == "Dictionary" { +' for each secondOrderEntry in entry { +' YAMLCleaner(secondOrderEntry) +' } +' } else if entry(typeIdentifier) == "Array" { +' for each secondOrderEntry in entry(selfIdentifier) { +' YAMLCleaner(secondOrderEntry) +' } +' } +' if entry(typeIdentifier) != "Dictionary" { +' mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) +' } +' } +' return mainDictionary; +' } + +Function YAMLCleaner(mainDictionary As Dictionary) As Dictionary + Dim entry As Variant + If mainDictionary(typeIdentifier) = "Array" Then ' go through array and yamlclean it + Dim i As Integer + Debug.Print JsonConverter.ConvertToJson(mainDictionary) + For i = LBound(mainDictionary(selfIdentifier)) To UBound(mainDictionary(selfIdentifier)) + + 'If IsObject(mainDictionary(selfIdentifier)(i)) Then + 'Set mainDictionary(selfIdentifier)(i) = YAMLCleaner(mainDictionary(selfIdentifier)(i)) + 'Else + ' Debug.Print "encountered non-object" + 'End If + Next i + End If + If mainDictionary(typeIdentifier) = "Dictionary" Then 'iterate through dict and yamlclena it + For Each entry In mainDictionary + If entry <> typeIdentifier Then + Set mainDictionary(entry) = YAMLCleaner(mainDictionary(entry)) + End If + Next entry + End If + + For Each entry In mainDictionary + If mainDictionary(typeIdentifier) = "Dictionary" And mainDictionary(entry)(typeIdentifier) <> "Dictionary" And entry <> typeIdentifier And entry <> selfIdentifier Then + Debug.Print "processing " & entry & " which is " & mainDictionary(entry)(typeIdentifier) + If IsObject(mainDictionary(entry)(selfIdentifier)) Then + Set mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) + Else + mainDictionary(entry) = mainDictionary(entry)(selfIdentifier) + End If + End If + Next entry + + ' destroy type identifier? + Set YAMLCleaner = mainDictionary +End Function + +Function GetFileAsString(filePath As String) As String + ' Dim fileContent As String + Dim line As String + Dim fileNumber As Integer + + 'filePath = "\\Mac\iCloud\Development\cv\cv.yml" + + fileNumber = FreeFile() + + Open filePath For Input As fileNumber + + Do While Not EOF(fileNumber) + Line Input #fileNumber, line + GetFileAsString = GetFileAsString & line & vbCrLf + Loop +End Function + +Sub TryFunction() + Dim fileString As String: fileString = GetFileAsString("\\Mac\iCloud\Development\cv\cv.yml") + Dim yamlLayer As Object + Set yamlLayer = GetYAMLLayerAsDictionary(fileString) + Dim yamlWholeDict As Object: Set yamlWholeDict = GetYAMLAsDictionary(fileString) + 'Debug.Print JsonConverter.ConvertToJson(yamlWholeDict, 2, 2) + Dim yamlCleanDict As Object: Set yamlCleanDict = YAMLCleaner(yamlWholeDict) + Debug.Print JsonConverter.ConvertToJson(yamlCleanDict, 2, 2) +End Sub diff --git a/contents/customXml/_rels/item1.xml.rels b/contents/customXml/_rels/item1.xml.rels new file mode 100644 index 0000000..a9c831d 100644 --- /dev/null +++ a/contents/customXml/_rels/item1.xml.rels @@ -1,0 +1,2 @@ + +diff --git a/contents/word/_rels/document.xml.rels b/contents/word/_rels/document.xml.rels new file mode 100644 index 0000000..94cfc8a 100644 --- /dev/null +++ a/contents/word/_rels/document.xml.rels @@ -1,0 +1,2 @@ + +diff --git a/contents/word/_rels/numbering.xml.rels b/contents/word/_rels/numbering.xml.rels new file mode 100644 index 0000000..7a29daa 100644 --- /dev/null +++ a/contents/word/_rels/numbering.xml.rels @@ -1,0 +1,2 @@ + +diff --git a/contents/word/_rels/settings.xml.rels b/contents/word/_rels/settings.xml.rels new file mode 100644 index 0000000..9c2cfc4 100644 --- /dev/null +++ a/contents/word/_rels/settings.xml.rels @@ -1,0 +1,2 @@ + +diff --git a/contents/word/media/image1.png b/contents/word/media/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..f49c18fe5782b85bac4c8e90e8a1e481d1ed87ac 100644 Binary files /dev/null and a/contents/word/media/image1.png differ diff --git a/contents/word/theme/theme1.xml b/contents/word/theme/theme1.xml new file mode 100644 index 0000000..60a57c2 100644 --- /dev/null +++ a/contents/word/theme/theme1.xml @@ -1,0 +1,2 @@ + +-- rgit 0.1.5