diff --git a/.ci/generateIndex.py b/.ci/generateIndex.py index b09107308449bb917b322e95a5c8edb901ccf3e9..b60cac50d05d2ca84d52ab2c06884907f365b7a0 100644 --- a/.ci/generateIndex.py +++ b/.ci/generateIndex.py @@ -1,7 +1,9 @@ import os, re from os import path +from os.path import exists from natsort import natsorted from pathlib import Path +import yaml def line_prepender(filename, line): with open(filename, 'r+') as f: @@ -9,6 +11,16 @@ def line_prepender(filename, line): f.seek(0, 0) f.write(line.rstrip('\r\n') + '\n' + content) +def get_subdirs(p): + for fname in os.listdir(p): + if os.path.isdir(os.path.join(p, fname)): + yield os.path.join(p, fname) + +def has_subdirs(p): + folders = list(get_subdirs(p)) + return len(folders) != 0 + + def build_link(title, href): # strip the number of the title @@ -20,16 +32,13 @@ def build_link(title, href): return f'\t\t\t<li><a href="{href}">{title}</a></li>\n' -def root_handbook(href): +def root_href(href): # remove sym link reference in href if ('handbook-additional' in href): href = href.replace('handbook-additional', 'handbook').strip() elif ('handbook-annexes' in href): href = href.replace('handbook-annexes', 'handbook').strip() - return href - -def root_lab(href): # remove sym link reference in href if ('lab-software' in href): href = href.replace('lab-software', 'lab').strip() @@ -37,6 +46,14 @@ def root_lab(href): href = href.replace('lab-equipment', 'lab').strip() elif ('lab-hsa' in href): href = href.replace('lab-hsa', 'lab').strip() + elif ('lab-integrity' in href): + href = href.replace('lab-integrity', 'lab').strip() + + # remove sym link reference in href + if ('qms-policies' in href): + href = href.replace('qms-policies', 'qms').strip() + elif ('qms-sops' in href): + href = href.replace('qms-sops', 'qms').strip() return href @@ -50,6 +67,9 @@ def build_section_start(title, shortcut): title = title.replace("Lab software", "Lab: Software") title = title.replace("Lab equipment", "Lab: Equipment") title = title.replace("Lab hsa", "Lab: Health & Safety, Access") + title = title.replace("Lab integrity", "Lab: Integrity") + title = title.replace("Qms sops", "QMS: Standard Operating Procedures (SOPS)") + title = title.replace("Qms policies", "QMS: Policies") return f'\n\t<div class="index-box noborderbox" id="{shortcut}-card">\n\t\t<h3>{title}</h3>\n\t\t<ul>\n' @@ -62,12 +82,23 @@ def save_tag(localroot, root, filename, tag): length_tag = len(tag) - with open(filename, 'r') as f: - for line in f: - # check for the start of the section - if line[0:length_tag+1] == tag + ":": - return_tag = line[length_tag+2:] - break + if "yml" in filename: + with open(filename, "r") as stream: + try: + metadata = list(yaml.load_all(stream, Loader=yaml.FullLoader)) + except yaml.YAMLError as exc: + print(exc) + + return_tag = metadata[0][tag] + + else: + with open(filename, 'r') as f: + for line in f: + # check for the start of the section + if line[0:length_tag+1] == tag + ":": + return_tag = line[length_tag+2:] + return_tag = return_tag.replace('"', '') + break # change back to the local root os.chdir(localroot) @@ -84,7 +115,8 @@ def get_ignore(): "assets", "help.md", "index.md", - "pagination.md" + "pagination.md", + ".gitkeep", ] def save_legacy_from(localroot, root, filename): @@ -149,7 +181,19 @@ def remove_header(localroot, root, filename): return n -def generate_header(folder, permalink, shortcut, order, legacy_from, title, description): +def element_header(prefix, permalink, element): + + if ( + ("handbook-annexes" in permalink or "handbook-additional" in permalink) or + ("lab-software" in permalink or "lab-equipment" in permalink or "lab-hsa" in permalink) or + ("qms-policies" in permalink or "qms-sops" in permalink) + ): + element += prefix + "/cards/" + root_href(shortcut) + "\n" + element += prefix + "/" + folder + "/cards/" + root_href(shortcut) + "\n" + + return element + +def generate_header(folder, permalink, shortcut, order, legacy_from, title, description, qms_yml): header = "---\n" if len(order) > 0: @@ -157,18 +201,13 @@ def generate_header(folder, permalink, shortcut, order, legacy_from, title, desc header += "layout: page\n" header += "permalink: " + permalink + "\n" - header += "shortcut: " + root_handbook(shortcut) + "\n" + header += "shortcut: " + root_href(shortcut) + "\n" header += "redirect_from:\n" header += " - /cards/" + shortcut + "\n" header += " - /" + folder + "/cards/" + shortcut + "\n" - # special case of handbook - if "handbook-annexes" in permalink or "handbook-additional" in permalink: - header += " - /cards/" + root_handbook(shortcut) + "\n" - header += " - /" + folder + "/cards/" + root_handbook(shortcut) + "\n" - # separate lab section - if "lab-software" in permalink or "lab-equipment" in permalink or "lab-hsa" in permalink: - header += " - /cards/" + root_lab(shortcut) + "\n" - header += " - /" + folder + "/cards/" + root_lab(shortcut) + "\n" + + # generate specific redirects + header = element_header(" - ", shortcut, header) # include the legacy section in the redirect_from section if len(legacy_from) > 0: @@ -188,6 +227,10 @@ def generate_header(folder, permalink, shortcut, order, legacy_from, title, desc else: header += "---" + # add title for QMS documents + if "qms" in shortcut and qms_yml: + header += "\n# " + title + return header def generate_whitelist_entry(folder, permalink, shortcut): @@ -195,16 +238,40 @@ def generate_whitelist_entry(folder, permalink, shortcut): wl_entry += "/?" + shortcut + "\n" wl_entry += "/cards/" + shortcut + "\n" wl_entry += "/" + folder + "/cards/" + shortcut + "\n" - if "handbook-annexes" in permalink or "handbook-additional" in permalink: - wl_entry += "/cards/" + root_handbook(shortcut) + "\n" - wl_entry += "/" + folder + "/cards/" + root_handbook(shortcut) + "\n" - # separate lab section - if "lab-software" in permalink or "lab-equipment" in permalink or "lab-hsa" in permalink: - wl_entry += "/cards/" + root_lab(shortcut) + "\n" - wl_entry += "/" + folder + "/cards/" + root_lab(shortcut) + "\n" + + wl_entry = element_header("", permalink, wl_entry) return wl_entry +def prepare_qms(localroot, root, filename): + + os.chdir(root) + + filedata = "" + with open(filename, 'r') as file : + for line in file: + filedata += line + + # shift the subtitles by 1 level down + filedata = filedata.replace("# ", "## ") + + # replace latex command for titles + filedata = filedata.replace("{-}", "##") + + # deal with img location + filedata = filedata.replace("policies/"+filename[:-3]+"/", "") + filedata = filedata.replace("sops/"+filename[:-3]+"/", "") + + # replace img attributes + filedata = filedata.replace("{ width=50% }", "") + + # Write the file out again + with open(filename, 'w') as file: + file.write(filedata) + + # change back to the local root + os.chdir(localroot) + # loop through the entire internal tree localroot = os.getcwd() @@ -212,17 +279,17 @@ localroot = os.getcwd() ignore = get_ignore() # generate the index properly speaking -cardDirs = ["internal", "external", "policies"] +cardDirs = ["internal", "external"] sections = [] # determine first the directories for direct in cardDirs: - if path.isdir(direct): + if path.isdir(direct) and has_subdirs(direct): dirs = os.listdir(direct) dirs = natsorted(dirs) for d in dirs: - if d[0] != "." and d not in ignore: + if d[0] != "." and d not in ignore and has_subdirs(direct + "/" + d): sections.append(d) sections = list(set(sections)) @@ -246,7 +313,7 @@ for folder in cardDirs: dirs = natsorted(dirs) for d in dirs: - if d[0] != "." and d not in ignore: + if d[0] != "." and d not in ignore and has_subdirs(folder + "/" + d): # set the header of the section #index += "\n### " + d.replace("-", " ").capitalize() + "\n" @@ -273,6 +340,16 @@ for folder in cardDirs: title = save_tag(localroot, root, file, "title") description = save_tag(localroot, root, file, "description") + # extract the title from the QMS metadata + qms_yml = False + if "qms" in root: + if exists(os.path.join(root, file[:-3] + ".yml")): + title = save_tag(localroot, root, file[:-3] + ".yml", "title") + prepare_qms(localroot, root, file) + qms_yml = True + else: + print("QMS document is not formatted properly.") + # remove the previous header n = remove_header(localroot, root, file) @@ -305,7 +382,7 @@ for folder in cardDirs: orderArr[indexS] = [] # generate the header for each card - header = generate_header(folder, permalink, shortcut, order, legacy_from, title, description) + header = generate_header(folder, permalink, shortcut, order, legacy_from, title, description, qms_yml) # add autogenerated links to whitelist whiteList += generate_whitelist_entry(folder, permalink, shortcut) @@ -314,23 +391,29 @@ for folder in cardDirs: line_prepender(fileName, header) # open file and get the title after the header - count = 0 - title = "" - bp = n + 1 - - with open(fileName, 'r') as f: - for line in f: - count += 1 - if count == bp: - if len(line) > 2: - title = line - break - else: - bp += 1 - - # remove first and last chars - title = title.rstrip("\n\r") - title = title[2:] + if "qms" in root: + header_offset = 3 + else: + header_offset = 1 + + if not qms_yml: + count = 0 + title = "" + bp = n + header_offset + + with open(fileName, 'r') as f: + for line in f: + count += 1 + if count == bp: + if len(line) > 2: + title = line + break + else: + bp += 1 + + # remove first and last chars + title = title.rstrip("\n\r") + title = title[2:] localIndexArr[indexS].append(build_link(title, root)) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d960dae7c6d6b4728082dda94b7aae702a061a09..01a1a01873a9091267c14a74e8ea92a102680140 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ prepare:index: - if: $CI_COMMIT_REF_NAME - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_MESSAGE !~ /tmpBranch/ && $CI_COMMIT_MESSAGE !~ /Update index/' before_script: - - pip install natsort + - pip install -r requirements.txt script: - python .ci/generateIndex.py - mkdir .tmp diff --git a/assets/js/box_hider.js b/assets/js/box_hider.js index 48aa48bdb0009749a279c59ef4143a08cc858af6..bd20a7d4b6f34bac94d7a42bc5e398620a1c4805 100644 --- a/assets/js/box_hider.js +++ b/assets/js/box_hider.js @@ -24,7 +24,7 @@ window.boxHider = (function() { function GetSelectedBoxElement(id) { var allBoxesArray = GetAllBoxElementsArray(); // note: handbook and lab are actually grouped sections - if (id.startsWith('handbook') || id.startsWith('lab')) { + if (id.startsWith('handbook') || id.startsWith('lab') || id.startsWith('qms')) { return true; } else { var element = document.getElementById(id); @@ -96,6 +96,14 @@ window.boxHider = (function() { ShowElement(box); } }); + } else if (boxId.startsWith('qms')) { + allBoxes.map(function(box) { + if (!box.id.startsWith('qms')) { + HideElement(box); + } else { + ShowElement(box); + } + }); } else { allBoxes.map(function(box) { if (box != selectedBox) { diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..594a2568e1ee92ed7e0e59b474401de45016b358 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,15 @@ +appnope~=0.1.2 +backcall~=0.2.0 +decorator~=5.1.0 +jedi~=0.18.1 +matplotlib-inline~=0.1.3 +natsort~=7.1.1 +parso~=0.8.3 +pexpect~=4.8.0 +pickleshare~=0.7.5 +prompt-toolkit~=3.0.24 +ptyprocess~=0.7.0 +Pygments~=2.10.0 +PyYAML~=6.0 +traitlets~=5.1.1 +wcwidth~=0.2.5