diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ee48c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +test +test/* +*.info +*.pms +src/__pycache__ +outfile.info diff --git a/readme.md b/readme.md index 65aa550..4ff72ec 100644 --- a/readme.md +++ b/readme.md @@ -66,6 +66,7 @@ Metadata Tags are substituted by the compiler. - seperator - section - subsection + - include #### header The **header** generates an ASCII-Art banner with the author and title. Example: @@ -141,7 +142,18 @@ Output: 1.1 Hier gehts weiter --------------------- -## Prerequisite + +#### include +The include tag is substituted by the content of the specified file. +Relative path are resolved in context of the current file. + +Example: + + {{gmu.include=./filename.pms}} + + + +## Dependencies python3.7 -m pip install pyfiglet diff --git a/src/main.py b/src/main.py index b7e43d5..0c7bf5c 100644 --- a/src/main.py +++ b/src/main.py @@ -6,13 +6,15 @@ from render import * import pyfiglet import time import uuid -import sys, getopt +import sys, getopt, os +from pathresolve import resolvePathUNIX +from pathlib import Path #### VARS gmuSettings_global = { 'Document' : { - 'defaultWidth': 80, + 'defaultWidth': '80', 'doctype': 'info', 'spacerChar': '#', 'headerPrefix': 'False', @@ -28,7 +30,8 @@ tmpFileUUID = str(uuid.uuid4()) gmuInputFile = '' gmuOutputFile = '' -gmuOutputFileTmp = "/tmp/{}.pmc1".format(tmpFileUUID) +gmuOutputFileTmp1 = "/tmp/{}.pmc1".format(tmpFileUUID) +gmuOutputFileTmp2 = "/tmp/{}.pmc2".format(tmpFileUUID) currentScope = "Document" metatagRegEx = re.compile('^\[\[([\w\d._]*)\=([\w\d\-\":;,._$%&\/\\\ ]*)\]\]$', re.IGNORECASE) @@ -130,14 +133,67 @@ def processLine2(lineNumber, lineContent, tempFile): tempFile.write(lineContent + '\n') -def processFile(path): + +def processFilePhase1(path, depth): + + startTime = time.time() + print("[Phase 1] Processing PrimalMarkupScript-Sourcefile: {}".format(path)) + + tempFile = open(gmuOutputFileTmp1, 'w') + + linkedFileCount = 0 + + def processFile(path, depth, tempFile, linkedFileCount): + try: + linkedFileCount += 1 + inFile = open(path, 'r') + inFileLines = inFile.readlines() + + lineCount = 0 + for line in inFileLines: + lineCount += 1 + + if line[0:6] == "{{gmu.": + # found content-tag + tagData = contenttagRegEx.match(line) + + if not tagData: + abortParseError(lineCount, line, "Cannot parse content-tag") + + tagType = tagData.group(1)[4:] + + if tagType == 'include': + filePath = os.path.dirname(path) + absPath = resolvePathUNIX(filePath, tagData.group(3)) + print("[LINKING] Include {}".format(filePath)) + # resolve filename in relation to current file + processFile(absPath , depth + 1, tempFile , linkedFileCount) + tempFile.write('\n') + continue + + tempFile.write(line) + except IOError: + abortParseError(lineCount,path,"Sourcefile not accessible") + + processFile(path, 0, tempFile, linkedFileCount) + + tempFile.close() + endTime = time.time() + + print("[Phase 1] Linked {} lines in {}s".format(linkedFileCount, (endTime - startTime))) + #print(" => Registered {} Sections".format(gmuSettings_global['counter_section'])) + print(" => Generated pmc-file {}".format(gmuOutputFileTmp1)) + + + +def processFilePhase2(path): try: startTime = time.time() - print("[Phase 1] Processing PrimalMarkupScript-Sourcefile: " + path) + print("[Phase 2] Processing PrimalMarkupScript-Sourcefile: " + path) inFile = open(path, 'r') inFileLines = inFile.readlines() - tempFile = open(gmuOutputFileTmp, 'w') + tempFile = open(gmuOutputFileTmp2, 'w') lineCount = 0 for line in inFileLines: @@ -147,18 +203,18 @@ def processFile(path): tempFile.close() endTime = time.time() - print("[Phase 1] Compiled {} lines in {}s".format(lineCount, (endTime - startTime))) + print("[Phase 2] Compiled {} lines in {}s".format(lineCount, (endTime - startTime))) print(" => Registered {} Sections".format(gmuSettings_global['counter_section'])) - print(" => Generated pmc1-file {}".format(gmuOutputFileTmp)) + print(" => Generated pmc-file {}".format(gmuOutputFileTmp2)) except IOError: print("Sourcefile not accessible") -def processFileRound2(path): +def processFilePhase3(path): try: startTime = time.time() - print("[Phase 2] Processing pmc1-file: " + path) + print("[Phase 3] Processing pmc1-file: " + path) inFile = open(path, 'r') inFileLines = inFile.readlines() @@ -172,7 +228,7 @@ def processFileRound2(path): tempFile.close() endTime = time.time() - print("[Phase 2] Generated Content-Table in {}s".format((endTime - startTime))) + print("[Phase 3] Generated Content-Table in {}s".format((endTime - startTime))) print(" => Generated info-file {}".format(gmuOutputFile)) except IOError: print("Sourcefile not accessible") @@ -205,13 +261,13 @@ printHeader() for current_argument, current_value in arguments: if current_argument in ("-i", "--input"): - gmuInputFile = current_value + gmuInputFile = Path(current_value).resolve() elif current_argument in ("-h", "--help"): print ("Specify Input with -i or --input") print ("Specify Output with -o or --output") exit(0) elif current_argument in ("-o", "--output"): - gmuOutputFile = current_value + gmuOutputFile = Path(current_value).resolve() if gmuInputFile == '': print("[ERROR] You need to specify an input file") @@ -223,7 +279,8 @@ if gmuOutputFile == '': #check if files exist -processFile(gmuInputFile) -processFileRound2(gmuOutputFileTmp) +processFilePhase1(gmuInputFile,0) +processFilePhase2(gmuOutputFileTmp1) +processFilePhase3(gmuOutputFileTmp2) print("\nDone! Compiled 1 File.") \ No newline at end of file diff --git a/src/pathresolve.py b/src/pathresolve.py new file mode 100644 index 0000000..b4d68f0 --- /dev/null +++ b/src/pathresolve.py @@ -0,0 +1,24 @@ +class RelPathInavlid(Exception): + """Raised when the relative path is invalid""" + pass + +def resolvePathUNIX(abs, rel): + newPath = '' + if rel[0:2] == './': + newPath = abs + rel[1:] + elif rel[0:3] == '../': + absSegs = abs.split("/") + relSegs = rel.split("/") + backLevels = sum(x == ".." for x in relSegs) + if backLevels >= len(absSegs): + raise RelPathInavlid + newPathArr = absSegs[1:(backLevels * -1)] + for relLevel in relSegs: + if relLevel != '..': + newPathArr.append(relLevel) + for lvl in newPathArr: + newPath = newPath + '/' + lvl + else: + raise RelPathInavlid + + return newPath \ No newline at end of file diff --git a/src/render.py b/src/render.py index 4bdf852..ce40804 100644 --- a/src/render.py +++ b/src/render.py @@ -3,7 +3,7 @@ import pyfiglet def renderSeperator(properties): outString = '' - for i in range(0, properties['Document']['defaultWidth']): + for i in range(0, int(properties['Document']['defaultWidth'])): outString = "{}{}".format(outString, properties['Document']['spacerChar']) return outString