diff --git a/checks/README.md b/checks/README.md index e8c1fb6..96cfb89 100644 --- a/checks/README.md +++ b/checks/README.md @@ -7,7 +7,9 @@ Tests should be made as Python scripts to allow flexibility of use. Currently th - [GitHub Actions](https://docs.github.com/en/actions) as defined in [workflows](../.github/workflows/), - [VSCode Problem Matchers](https://code.visualstudio.com/docs/editor/tasks#_processing-task-output-with-problem-matchers) as defined in [tasks.json](../.vscode/tasks.json). -## Spellcheck +## Check Types + +### Spellcheck *This linter is defined in [run_spell_check.py](run_spell_check.py) script.* @@ -16,14 +18,14 @@ Spellcheck pipeline settings can be modified in [.spellcheck.yml](../.spellcheck List of custom words can be found in [dictionary.txt](../docs/assets/glossary/dictionary.txt), however you **should not edit this manually**, see [adding-words-to-dictionary](../docs/CONTRIBUTING.md#adding-words-to-dictionary). -### Limitations +#### Limitations Spellchecker does not provide output lineumber / column. In order to get this a regex match is done on the markdown. This means that you might occassionally see a word highlighted inside a context where it should be ignored (e.g. code block), the typo is probably occuring elsewhere in the text in a valid context, fix it here and the first error will resolve. -## Prose Lint +### Prose Lint *This linter is defined in [run_proselint.py](run_proselint.py) script.* @@ -31,26 +33,36 @@ Checks text follows best practice for English language. Individual rules can be disabled/enabled in [.proselint.json](../.proselint.json). -## Markdown Lint +### Markdown Lint -Checks markdown for complience against general [best practice rules](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md). +Checks markdown for compliance against general [best practice rules](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md). Individual rules can be disabled/enabled in [.markdownlint.json](../.markdownlint.json) -## Meta Checks +### Meta Checks *This linter is defined in [run_meta_check.py](run_meta_check.py) script.* Catch-all for custom checks. Currently defined checks are: -- title_redundant, -- title_length, -- meta_missing_description, -- meta_unexpected_key, -- minimum_tags, -- walk_toc. +- title_redundant +- title_length +- meta_missing_description +- meta_unexpected_key +- minimum_tags +- walk_toc +- click_here +- dynamic_slurm_link -## Test Build +### Test Build Does a 'strict' build of the site, capturing any errors emmited by mkdocs. + +### Debugging Checks + +Each type of test has a debug job in VSCode. + +Most will run on the [fail_checks](fail_checks.md) page + + diff --git a/checks/fail_checks.md b/checks/fail_checks.md index 80aa609..334cc7e 100644 --- a/checks/fail_checks.md +++ b/checks/fail_checks.md @@ -29,6 +29,10 @@ Typos should [be ignored](https://www.docs.nesi.org.nz) Typos should [be ignored](../docs/General/FAQs/How_do_I_request_memory.md) +links shouldn't be called [here](../docs/General/FAQs/How_do_I_request_memory.md) +but can be called [where](../docs/General/FAQs/How_do_I_request_memory.md) + + Bad formatting for markdownlint diff --git a/checks/run_aria_check.py b/checks/run_aria_check.py new file mode 100644 index 0000000..aa08dce --- /dev/null +++ b/checks/run_aria_check.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""Check built HTML for broken ARIA id references.""" + +from html.parser import HTMLParser +from pathlib import Path +import sys + + +class AriaParser(HTMLParser): + def __init__(self): + super().__init__() + self.ids = set() + self.refs = [] + + def handle_starttag(self, tag, attrs): + d = dict(attrs) + if "id" in d: + self.ids.add(d["id"]) + for key in ["aria-labelledby", "aria-describedby", "aria-controls"]: + if key in d: + for ref in d[key].split(): + self.refs.append((key, ref, tag)) + + +def main(): + base = Path("public") + if not base.exists(): + print("::error file=checks/run_aria_check.py,title=missing_public_dir::public folder not found. Run mkdocs build first.") + return 1 + + broken = [] + for path in sorted(base.rglob("*.html")): + text = path.read_text(encoding="utf-8", errors="ignore") + parser = AriaParser() + parser.feed(text) + for key, ref, tag in parser.refs: + if ref not in parser.ids: + broken.append((path, key, ref, tag)) + + if broken: + for path, key, ref, tag in broken: + print(f"::error file={path},title=broken_aria_reference,col=0,endColumn=0,line=0::{key} reference '{ref}' missing id in tag <{tag}>") + print(f"Found {len(broken)} broken aria references.") + return 1 + + print("ARIA reference check passed.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/checks/run_meta_check.py b/checks/run_meta_check.py index 581f733..81d03d4 100755 --- a/checks/run_meta_check.py +++ b/checks/run_meta_check.py @@ -11,18 +11,26 @@ import yaml import os import time +from titlecase import titlecase from pathlib import Path # Ignore files if they match this regex -EXCLUDED_FROM_CHECKS = [r"docs/assets/.*", r".*/index\.html", r".*/index\.md", r".*\.pages\.yml"] +EXCLUDED_FROM_CHECKS = [ + r"docs/assets/.*", + r".*/index\.html", + r".*/index\.md", + r".*\.pages\.yml", +] + +msg_count = {"debug": 0, "notice": 0, "warning": 0, "error": 0} msg_count = {"debug": 0, "notice": 0, "warning": 0, "error": 0} # Constants for use in checks. -MAX_TITLE_LENGTH = 28 # As font isn't monospace, this is only approx +MAX_TITLE_LENGTH = 28 # As font isn't monospace, this is only approx MAX_HEADER_LENGTH = 32 # minus 2 per extra header level -MIN_TAGS = 2 +MIN_TAGS = 1 RANGE_SIBLING = [4, 8] DOC_ROOT = "docs" @@ -35,9 +43,9 @@ "status": ["new", "deprecated"], "prereq": "", "postreq": "", - "suggested": "", # Add info here when implimented. + "suggested": "", # Add info here when implimented. "created_at": "", - "tags": "", # Add info here when implimented. + "tags": "", # Add info here when implimented. "search": "", "hide": ["toc", "nav", "tags"], } @@ -45,10 +53,23 @@ def main(): # Per file variables - global input_path, title_from_h1, title_from_filename, title, meta, contents, input_path + global \ + input_path, \ + title_from_h1, \ + title_from_filename, \ + title, \ + meta, \ + contents, \ + input_path # Walk variables - global lineno, line, in_code_block, last_header_level, last_header_lineno, sibling_headers + global \ + lineno, \ + line, \ + in_code_block, \ + last_header_level, \ + last_header_lineno, \ + sibling_headers global toc, toc_parents, header @@ -60,20 +81,39 @@ def main(): continue _nav_check() with open(input_path, "r") as f: - _emit("", {"level": "debug", "file": input_path, "message": f"Checking meta for {f.name}"}) + _emit( + "", + { + "level": "debug", + "file": input_path, + "message": f"Checking meta for {f.name}", + }, + ) try: contents = f.read() match = re.match(r"---\n([\s\S]*?)---", contents, re.MULTILINE) if not match: - _emit("meta.parse", {"file": input_path, "col": 0, "endColumn": 99, "line": 1, - "message": "Meta block missing or malformed."}) + _emit( + "meta.parse", + { + "file": input_path, + "col": 0, + "endColumn": 99, + "line": 1, + "message": "Meta block missing or malformed.", + }, + ) meta = {} else: meta = yaml.safe_load(match.group(1)) title_from_filename = _title_from_filename() title_from_h1 = _title_from_h1() - title = meta["title"] if "title" in meta else "" or title_from_h1 or title_from_filename + title = ( + meta["title"] + if "title" in meta + else "" or title_from_h1 or title_from_filename + ) # global lineno, line, in_code_block, last_header_level, last_header_lineno, sibling_headers header = "" @@ -84,8 +124,13 @@ def main(): for line in contents.split("\n"): lineno += 1 + in_code_block = ( + not in_code_block + if re.match(r"^\s*```\s?\w*$", line) + else in_code_block + ) for check in WALKCHECKS: - in_code_block = not in_code_block if re.match(r"^\s*```\s?\w*$", line) else in_code_block + _get_nav_tree() _run_check(check) for check in ENDCHECKS: @@ -100,9 +145,11 @@ def _run_check(f): def _emit(f, r): - msg_count[r.get('level', 'warning')] += 1 - print(f"::{r.get('level', 'warning')} file={input_path},title={f},col={r.get('col', 0)},\ -endColumn={r.get('endColumn', 99)},line={r.get('line', 1)}::{r.get('message', 'something wrong')}") + msg_count[r.get("level", "warning")] += 1 + print( + f"::{r.get('level', 'warning')} file={input_path},title={f},col={r.get('col', 0)},\ +endColumn={r.get('endColumn', 99)},line={r.get('line', 1)}::{r.get('message', 'something wrong')}" + ) sys.stdout.flush() time.sleep(0.01) @@ -140,7 +187,6 @@ def _unpack(toc, a): if len(a) < 2: return toc[a[0]] return _unpack(toc[a[0]]["children"], a[1:]) - try: if in_code_block: return @@ -157,14 +203,24 @@ def _unpack(toc, a): toc = {header_name: {"lineno": lineno, "children": {}}} toc_parents = [header_name] - while header_level < len(toc_parents)+1: + while header_level < len(toc_parents) + 1: toc_parents.pop(-1) - _unpack(toc, toc_parents)["children"][header_name] = {"level": header_level, "lineno": lineno, "children": {}} + _unpack(toc, toc_parents)["children"][header_name] = { + "level": header_level, + "lineno": lineno, + "children": {}, + } toc_parents += [header_name] except Exception: - _emit("misc.nav", {"level": "error", "file": input_path, - "message": "Failed to parse Nav tree. Something is very wrong."}) + _emit( + "misc.nav", + { + "level": "error", + "file": input_path, + "message": "Failed to parse Nav tree. Something is very wrong.", + }, + ) def _nav_check(): @@ -174,43 +230,82 @@ def _nav_check(): for i in range(1, len(rel_path.parts)): num_siblings = 0 for file_name in os.listdir(doc_root.joinpath(Path(*rel_path.parts[:i]))): - if not any(re.match(pattern, file_name) for pattern in EXCLUDED_FROM_CHECKS): + if not any( + re.match(pattern, file_name) for pattern in EXCLUDED_FROM_CHECKS + ): num_siblings += 1 if num_siblings < RANGE_SIBLING[0]: - _emit("meta.siblings", {"file": input_path, "message": f"Parent category \ - '{rel_path.parts[i-1]}' has too few children ({num_siblings}). Try to nest '{RANGE_SIBLING[0]}' or more \ - items here to justify it's existence."}) + _emit( + "meta.siblings", + { + "file": input_path, + "message": f"Parent category \ + '{rel_path.parts[i - 1]}' has too few children ({num_siblings}). Try to nest '{RANGE_SIBLING[0]}' or more \ + items here to justify it's existence.", + }, + ) elif num_siblings > RANGE_SIBLING[1]: - _emit("meta.siblings", {"file": input_path, "message": f"Parent category \ - '{rel_path.parts[i-1]}' has too many children ({num_siblings}). Try to keep number of items in a category \ - under '{RANGE_SIBLING[1]}', maybe add some new categories?"}) + _emit( + "meta.siblings", + { + "file": input_path, + "message": f"Parent category \ + '{rel_path.parts[i - 1]}' has too many children ({num_siblings}). Try to keep number of items in a category \ + under '{RANGE_SIBLING[1]}', maybe add some new categories?", + }, + ) except ValueError as e: - _emit("meta.nav", {"file": input_path, "level": "error", "message": f"{e}. Nav checks will be skipped"}) + _emit( + "meta.nav", + { + "file": input_path, + "level": "error", + "message": f"{e}. Nav checks will be skipped", + }, + ) def title_redundant(): lineno = _get_lineno(r"^title:.*$") if "title" in meta.keys() and title_from_filename == meta["title"]: - yield {"level": "notice", "line": lineno, "message": "Title set in meta is redundant as it is already set in filename."} + yield { + "level": "notice", + "line": lineno, + "message": "Title set in meta is redundant as it is already set in filename.", + } if "title" in meta.keys() and title_from_h1 == meta["title"]: - yield {"level": "notice", "line": lineno, "message": "Title set in h1 is redundant as it is already set in filename."} + yield { + "level": "notice", + "line": lineno, + "message": "Title set in h1 is redundant as it is already set in filename.", + } if title_from_filename == title_from_h1: - yield {"level": "notice", "line": lineno, "message": "Title set in meta is redundant as it is already set in h1."} + yield { + "level": "notice", + "line": lineno, + "message": "Title set in meta is redundant as it is already set in h1.", + } def meta_unexpected_key(): """ Check for unexpected keys. """ + def _test(v): if v not in EXPECTED_PARAMETERS[key]: - yield {"level": "error", "line": _get_lineno(f"^{key}:.*$"), - "message": f"'{value}' is not valid for {key}. [{','.join(EXPECTED_PARAMETERS[key])}]"} + yield { + "level": "error", + "line": _get_lineno(f"^{key}:.*$"), + "message": f"'{value}' is not valid for {key}. [{','.join(EXPECTED_PARAMETERS[key])}]", + } for key, value in meta.items(): if key not in EXPECTED_PARAMETERS.keys(): - yield {"line": _get_lineno(r"^" + key + r":.*$"), - "message": f"Unexpected parameter in front-matter '{key}'"} + yield { + "line": _get_lineno(r"^" + key + r":.*$"), + "message": f"Unexpected parameter in front-matter '{key}'", + } elif EXPECTED_PARAMETERS[key]: if isinstance(value, list): for v in value: @@ -226,17 +321,30 @@ def meta_missing_description(): def title_length(): if len(title) > MAX_TITLE_LENGTH: - yield {"line": _get_lineno(r"^title:.*$"), - "message": f"Title '{title}' is too long. \ -Try to keep it under {MAX_TITLE_LENGTH} characters to avoid word wrapping in the nav."} - + yield { + "line": _get_lineno(r"^title:.*$"), + "message": f"Title '{title}' is too long. \ +Try to keep it under {MAX_TITLE_LENGTH} characters to avoid word wrapping in the nav.", + } + +def title_capitalisation(): + correct_title = titlecase(title) + if title != correct_title: + yield { + "line": _get_lineno(r"^title:.*$"), + "message": f"Title '{title}' uses incorrect capitalisation. \ +'{correct_title}' is preferred", + } def minimum_tags(): if "tags" not in meta or not isinstance(meta["tags"], list): yield {"message": "'tags' property in meta is missing or malformed."} elif len(meta["tags"]) < MIN_TAGS: - yield {"line": _get_lineno(r"^tags:.*$"), "message": "Try to include at least 2 'tags'\ -(helps with search optimisation)."} + yield { + "line": _get_lineno(r"^tags:.*$"), + "message": "Try to include at least 2 'tags'\ +(helps with search optimisation).", + } def click_here(): @@ -246,9 +354,14 @@ def click_here(): if in_code_block: return - m1 = re.search(r"\[.*\s?here\s?.*\]\(.*\)", line, re.IGNORECASE) + m1 = re.search(r"(\[.*\s?|\[)here\s?.*\]\(.*\)", line, re.IGNORECASE) if m1: - yield {"line": lineno, "col": m1.start()+1, "endColumn": m1.end()-1, "message": "Don't use 'here' for link text, impedes accessability."} + yield { + "line": lineno, + "col": m1.start() + 1, + "endColumn": m1.end() - 1, + "message": "Don't use 'here' for link text, impedes accessibility.", + } # Impliment check for html links when I can be fd. # m2 = re.search(r"\[here\]\(.*\)", line) @@ -259,16 +372,23 @@ def walk_toc(): Checks if toc is sensible. """ def _count_children(d): - only_child = (len(d["children"]) == 1) + only_child = len(d["children"]) == 1 for title, c in d["children"].items(): if only_child: - yield {"line": c['lineno'], "message": f"Header '{title}' is a useless only-child. Give it siblings or remove it."} + yield { + "line": c["lineno"], + "message": f"Header '{title}' is a useless only-child. Give it siblings or remove it.", + } # As header gets deeper nested, it will have less horizontal room in toc. - if len(title) > (MAX_HEADER_LENGTH - (2*c["level"])): - yield {"line": c['lineno'], "message": f"Header '{title}' is too long. \ - Try to keep it under {MAX_HEADER_LENGTH} characters to avoid word wrapping in the toc."} + if len(title) > (MAX_HEADER_LENGTH - (2 * c["level"])): + yield { + "line": c["lineno"], + "message": f"Header '{title}' is too long. \ + Try to keep it under {MAX_HEADER_LENGTH} characters to avoid word wrapping in the toc.", + } for y in _count_children(c): yield y + for d in toc.values(): for y in _count_children(d): yield y @@ -283,10 +403,35 @@ def dynamic_slurm_link(): print(m1.group(2)) yield {"line": lineno,"message": f"Link '{m1.group(0)}', does not use dynamic slurm version. Use 'https://slurm.schedmd.com/archive/{{{{ config.extra.slurm }}}}/{m1.group(2)}"} +def dynamic_slurm_link(): + """ + Checks if slurm links point to right version of docs. + """ + m1 = re.search( + r".*\(https?:\/\/slurm.schedmd.com(?!\/archive\/{{\s*config\.extra\.slurm\s*}})(.*)\/(.*)\)", + line, + re.IGNORECASE, + ) + if m1: + print(m1.group(1)) + print(m1.group(2)) + yield { + "line": lineno, + "message": f"Link '{m1.group(0)}', does not use dynamic slurm version. Use 'https://slurm.schedmd.com/archive/{{{{ config.extra.slurm }}}}/{m1.group(2)}", + } + + # Define checks here # For checks to run on page as a whole -ENDCHECKS = [title_redundant, title_length, meta_missing_description, meta_unexpected_key, minimum_tags, - walk_toc] +ENDCHECKS = [ + title_redundant, + title_length, + title_capitalisation, + meta_missing_description, + meta_unexpected_key, + minimum_tags, + walk_toc, +] # Checks to be run on each line WALKCHECKS = [click_here, dynamic_slurm_link] diff --git a/checks/run_proselint.py b/checks/run_proselint.py index 2b17e0b..4add8ba 100755 --- a/checks/run_proselint.py +++ b/checks/run_proselint.py @@ -10,6 +10,10 @@ import proselint from proselint import config, tools +from proselint.checks import __register__ +from proselint.registry import CheckRegistry + +ALLOWABLE_NOTICES = 5 ALLOWABLE_NOTICES = 5 @@ -20,18 +24,17 @@ count_notices = 0 # Load defaults from config. - config_custom = tools.load_options( - config_file_path=".proselint.json", conf_default=config.default - ) + config_custom = config.load_from(Path(".proselint.json")) + CheckRegistry().register_many(__register__) for file in files: print(f"::DEBUG file={file},line=0,col=0,endColumn=0,title=file:: Running proselint on '{file}'") content = Path(file).read_text(encoding="utf8") - for notice in proselint.tools.lint(content, config=config_custom): + for notice in tools.LintFile(file, content=content).lint(config_custom): print( - f"::{notice[7]} file={file},line={notice[2]+1}," - f"col={notice[3]+2},endColumn={notice[2]+notice[6]+1}," - f"title={notice[0]}::'{notice[1]}'", + f"::warning file={file},line={notice.pos[0]}," + f"col={notice.check_result.span[0]},endColumn={notice.check_result.span[1]}," + f"title={notice.check_result.check_path}::'{notice.check_result.message}'", flush=True ) count_notices += 1 diff --git a/checks/run_spell_check.py b/checks/run_spell_check.py index d014af8..a89b1a5 100755 --- a/checks/run_spell_check.py +++ b/checks/run_spell_check.py @@ -16,7 +16,7 @@ count_typos = 0 for file in sys.argv[1:]: - print(f"::DEBUG file={file},line=0,col=0,endColumn=0,title=file:: Running proselint on '{file}'") + print(f"::DEBUG file={file},line=0,col=0,endColumn=0,title=file:: Running pyspelling on '{file}'") results = spellcheck( ".spellcheck.yml", diff --git a/checks/run_test_build.py b/checks/run_test_build.py index d3e404a..4ff7e42 100755 --- a/checks/run_test_build.py +++ b/checks/run_test_build.py @@ -7,7 +7,7 @@ import sys import re import time -import mkdocs_awesome_pages_plugin.navigation as nav +import mkdocs_awesome_nav.nav as nav """ diff --git a/docs/assets/glossary/dictionary.txt b/docs/assets/glossary/dictionary.txt index 50e1c6e..eefda04 100644 --- a/docs/assets/glossary/dictionary.txt +++ b/docs/assets/glossary/dictionary.txt @@ -239,8 +239,6 @@ CubeLib's CubeLib CubeWriter's CubeWriter -Cufflinks's -Cufflinks Cylc Cytoscape's Cytoscape @@ -270,6 +268,8 @@ DeconSeq's DeconSeq DeePMD-kit's DeePMD-kit +DeePMD-plugin's +DeePMD-plugin DeepLabCut's DeepLabCut Delft3D's @@ -296,8 +296,6 @@ EMAN2 EMBOSS's EMBOSS EOL -ESMF's -ESMF ETE's ETE EasyBuild's @@ -350,6 +348,8 @@ FastQ_Screen's FastQ_Screen FastTree's FastTree +Fastsimcoal2's +Fastsimcoal2 File-Rename's File-Rename FileSender's @@ -362,6 +362,8 @@ FlexiBLAS's FlexiBLAS Flye's Flye +Foldseek's +Foldseek Fortran FragGeneScan's FragGeneScan @@ -399,6 +401,8 @@ GMAP-GSNAP's GMAP-GSNAP GMP's GMP +GMT's +GMT GNU GOLD's GOLD @@ -454,6 +458,8 @@ Glib GlimmerHMM's GlimmerHMM Globus +Globus-CLI's +Globus-CLI GlobusID Go's Go @@ -613,6 +619,8 @@ MCL MCR's MCR MD5 +MDI's +MDI MEGAHIT's MEGAHIT METABOLIC's @@ -647,6 +655,7 @@ MashMap's MashMap Mashtree's Mashtree +Matplotlib Maven's Maven MaxBin's @@ -772,6 +781,7 @@ Nsight-Compute's Nsight-Compute Nsight-Systems's Nsight-Systems +NumPy Nvidia OBITools's OBITools @@ -830,6 +840,8 @@ PCRE's PCRE PCRE2's PCRE2 +PDAL's +PDAL PEAR's PEAR PETSc's @@ -1031,6 +1043,7 @@ ScaLAPAC ScaLAPACK's ScaLAPACK Schrödinger +SciPy SeisSol's SeisSol SeqAn's @@ -1045,8 +1058,6 @@ Siesta's Siesta SignalP's SignalP -Singularity's -Singularity Skylake Slurm Sniffles's @@ -1129,8 +1140,12 @@ TurboVNC's TurboVNC UCC's UCC +UCC-CUDA's +UCC-CUDA UCX's UCX +UCX-CUDA's +UCX-CUDA UDF UDUNITS's UDUNITS @@ -1183,6 +1198,8 @@ VirHostMatcher's VirHostMatcher VirSorter's VirSorter +Voro++'s +Voro++ WAAFLE's WAAFLE WCRP @@ -1211,8 +1228,6 @@ Xquartz YAML YAXT's YAXT -Yasm's -Yasm Z3's Z3 Zealander @@ -1298,6 +1313,8 @@ chewBBACA chiplets chopper's chopper +cimfomfa's +cimfomfa code-server's code-server collapsable @@ -1319,12 +1336,14 @@ ctffind ctrl cuDNN's cuDNN +curation customisable customisations cutadapt's cutadapt cuteSV's cuteSV +cylc cyvcf2's cyvcf2 dadi's @@ -1378,8 +1397,6 @@ fastStructure's fastStructure fastp's fastp -fastq-tools's -fastq-tools fgbio's fgbio filesets @@ -1407,8 +1424,6 @@ funcx-endpoint's funcx-endpoint g2clib's g2clib -g2lib's -g2lib gcloud's gcloud geany's @@ -1426,8 +1441,11 @@ gettext's gettext gfastats's gfastats +gfatools's +gfatools gffread's gffread +gfortran giflib's giflib gimkl's @@ -1465,12 +1483,8 @@ hwloc's hwloc hyperthreaded hyperthreading -icc's -icc iccifort's iccifort -ifort's -ifort iimpi's iimpi imkl's @@ -1507,6 +1521,8 @@ jq's jq json-c's json-c +json-fortran's +json-fortran jvarkit's jvarkit kaitiaki @@ -1534,6 +1550,10 @@ libarchive's libarchive libcircle's libcircle +libcuda-stub's +libcuda-stub +libdeepmd's +libdeepmd libdeflate's libdeflate libdrm's @@ -1621,6 +1641,8 @@ mapDamage's mapDamage matlab-proxy's matlab-proxy +mctc-lib's +mctc-lib md medaka's medaka @@ -1638,6 +1660,8 @@ miniBUSCO's miniBUSCO miniasm's miniasm +minigraph's +minigraph minimap2's minimap2 miniprot's @@ -1748,6 +1772,7 @@ pplacer precompiled prepend prepending +preprocessor preseq's preseq procurements @@ -1936,6 +1961,8 @@ x264's x264 x265's x265 +xPore's +xPore xkbcommon's xkbcommon xtb's diff --git a/docs/assets/stylesheets/theme.css b/docs/assets/stylesheets/theme.css index 6823ad7..3e11346 100644 --- a/docs/assets/stylesheets/theme.css +++ b/docs/assets/stylesheets/theme.css @@ -1,39 +1,80 @@ -:root{ - --nesi-grey : #414f5c; +:root { + --nesi-grey: #414f5c; --nesi-grey--light: #94a5ad; - --nesi-yellow :#fcce06; + --nesi-yellow: #fcce06; --nesi-purple: rgb(202, 159, 213); - --nesi-orange : rgb(244, 121, 37); - --nesi-blue : #4fbaed; - --nesi-red:#ef315e; + --nesi-orange: rgb(244, 121, 37); + --nesi-blue: #4fbaed; + --nesi-red: #ef315e; --nesi-green: #cce310; - --reannz-blue : rgb(0,185, 228); - --reannz-blue--shade-negative1:rgb(0, 127, 156); - --reannz-blue--dark: rgb(0,28, 54); + --reannz-blue: rgb(0, 185, 228); + --reannz-blue--shade-negative1: rgb(0, 127, 156); + --reannz-blue--dark: rgb(0, 28, 54); --reannz-blue--dark-shade1: #2c485d; - --reannz-grey : rgb(195,200, 200); - --reannz-black : rgb(25,25, 25); + --reannz-grey: rgb(195, 200, 200); + --reannz-black: rgb(25, 25, 25); --reannz-green: rgb(190, 184, 6); --reannz-green--dark: rgb(0, 170, 136); --reannz-orange: rgb(241, 128, 0); --reannz-purple: rgb(132, 121, 183); - [data-md-color-scheme="default"]{ - --md-primary-fg-color: var(--reannz-blue--dark); - --md-accent-fg-color: var(--reannz-blue); - } +[data-md-color-scheme="default"] { + --md-primary-fg-color: var(--reannz-blue--dark); /* head bar background color */ + --md-accent-fg-color: var(--reannz-blue); /* hover color for sidebar links */ + /* --md-accent-bg-color: var(--reannz-orange); */ /* cannot figure what this one does */ + /* --md-primary-fg-color--light: var(--reannz-orange); */ /* cannot figure what this one does */ + /*--md-primary-bg-color: var(--reannz-orange); */ /* text/icon color for head bar */ + /* --md-accent-fg-color--light: var(--reannz-orange); */ /* cannot figure what this one does */ + /* --md-default-fg-color: var(--reannz-orange); */ /* main text color, sub H1 headers too */ + /* --md-default-bg-color: var(--reannz-orange); */ /* main background color */ + /* --md-code-fg-color: var(--reannz-orange); */ /* main color for code text */ + /* --md-code-bg-color: var(--reannz-orange); */ /* main color for code background */ + /* --md-typeset-color: var(--reannz-orange); */ /* main text color, sub H1 headers too */ +} - /* --md-accent-bg-color: rgb(210,227,235); */ - [data-md-color-scheme="slate"] { - --md-primary-fg-color: var(--reannz-blue--dark); - --md-accent-fg-color: var(--reannz-blue--darkish); + /* --md-accent-bg-color: rgb(210,227,235); */ +[data-md-color-scheme="slate"] { + --md-primary-fg-color: var(--reannz-blue--dark); /* head bar background color */ + --md-accent-fg-color: var(--reannz-blue); /* hover color for sidebar links */ + /* --md-accent-bg-color: var(--reannz-orange); */ /* cannot figure what this one does */ + /* --md-primary-fg-color--light: var(--reannz-orange); */ /* cannot figure what this one does */ + /*--md-primary-bg-color: var(--reannz-orange); */ /* text/icon color for head bar */ + /* --md-accent-fg-color--light: var(--reannz-orange); */ /* cannot figure what this one does */ + /* --md-default-fg-color: var(--reannz-orange); */ /* main text color, sub H1 headers too */ + /* --md-default-bg-color: var(--reannz-orange); */ /* main background color */ + /* --md-code-fg-color: var(--reannz-orange); */ /* main color for code text */ + /* --md-code-bg-color: var(--reannz-orange); */ /* main color for code background */ + /* --md-typeset-color: var(--reannz-orange); */ /* main text color, sub H1 headers too */ + --md-typeset-a-color: rgb(0, 206, 255); /* sidebar active link color */ - .nt-card-image>img { - filter: brightness(0) invert(1); - } + .nt-card-image>img { + filter: brightness(0) invert(1); } } + + --md-status--tutorial: url('data:image/svg+xml;charset=utf-8,'); + --md-admonition-icon--prerequisite: url('data:image/svg+xml;charset=utf-8,'); + --md-admonition-icon--time: url('data:image/svg+xml;charset=utf-8,'); +} + +/* e.g. inactive link text */ +.md-typeset a { + color: var(--reannz-blue--shade-negative1); +} + +.md-typeset a:hover { + color: var(--reannz-blue); +} + +[data-md-color-scheme="slate"] .md-typeset a:hover { + color: rgb(0, 206, 255); +} + +[data-md-color-scheme="slate"] .md-typeset a { + color: var(--reannz-blue); +} + /* Logo biggification */ /* COMMENTED OUT FOR REANNZ LOGO */ /* .md-header__button.md-logo img, .md-header__button.md-logo svg { @@ -41,65 +82,58 @@ margin: -2rem; } */ +.md-status--tutorial::after { + mask-image: var(--md-status--tutorial); + -webkit-mask-image: var(--md-status--tutorial); +} + /* Version table stuff */ -.md-tag.md-tag-ver{ +.md-tag.md-tag-ver { color: var(--md-code-fg-color); } + .md-tag.md-tag-ver-shown { - outline: var(--md-primary-fg-color) 2px solid; + outline: var(--md-primary-fg-color) 2px solid; } .md-tag-ver-warn { text-decoration: line-through; } + .md-typeset__table { width: 100%; } + .md-typeset__table table:not([class]) { display: table } + /* convenience class. Not sure if it is used */ -.hidden{ - display: none; +.hidden { + display: none; } + /* Get support button */ -.md-button-support{ +.md-button-support { position: absolute; margin: -2rem 0 0 1rem; width: 80%; text-align: center; font-size: 0.7rem; } + /* Don't duplicate header title */ -.md-nav--primary > .md-nav__title { - display: none; +.md-nav--primary>.md-nav__title { + display: none; } + /* fix neotiri card colors */ - /* Make button more buttony */ +/* Make button more buttony */ .md-button--primary { box-shadow: grey 2px 2px 2px; } -/* prerequisite custom admonition */ -:root { - --md-admonition-icon--prerequisite: url('data:image/svg+xml;charset=utf-8,') -} - -.md-typeset .admonition.prerequisite, -.md-typeset details.prerequisite { - border-color: var(--reannz-green); -} -.md-typeset .prerequisite > .admonition-title, -.md-typeset .prerequisite > summary { - background-color: rgba(190, 184, 6, 0.1); /*above color*/ -} -.md-typeset .prerequisite > .admonition-title::before, -.md-typeset .prerequisite > summary::before { - background-color: var(--reannz-green); - -webkit-mask-image: var(--md-admonition-icon--prerequisite); - mask-image: var(--md-admonition-icon--prerequisite); -} /* Footer */ #new-footer { font-family: Lato; @@ -109,70 +143,273 @@ background-color: var(--reannz-black); } -/* e.g. inactive link text */ -.md-typeset a { - color: var(--reannz-blue--shade-negative1); -} -.md-typeset a:hover { - color: var(--reannz-blue); -} /* Make deprecated logo stand out */ span.md-status.md-status--deprecated { - filter: invert(50%) sepia(100%) saturate(1000%) hue-rotate(330deg) brightness(70%) contrast(1000%); + filter: invert(50%) sepia(100%) saturate(1000%) hue-rotate(330deg) brightness(70%) contrast(1000%); } /* Warning symbols for licence server */ -.badge-licence-noup{ - padding: 0; - color: red; - cursor: default; -} -.badge-licence-lowup{ - padding: 0; - color: yellow; - cursor: default; -} - - -/* Not sure what this is for. Maybe Kahu knows */ -/*start Pillar style*/ -.pillarwrapper { - display: flex; - padding: 20px 20px 0px 20px; -} - -.pillarwrapper > div { - flex-grow: 1; - padding: 20px 20px 0px 20px; - height:auto; - overflow:hidden; - transition: ease-in-out 200ms; - /*box-shadow: 0.05rem 0.05rem 0.075rem 0.075rem gainsboro; */ - box-shadow: 0px 10px 10px rgba(30, 30, 30, 0.08); - /*background: linear-gradient(to right bottom, #f7fafc, #fff);*/ - /* background-color: #ffffff; */ - border-collapse: collapse; - cursor: default; /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ -} - -.pillarwrapper > div:first-of-type { margin-right:10px } -.pillarwrapper > div:nth-of-type(2) { margin-right:10px } -.pillarwrapper > div:nth-of-type(3) { } - -.pillarwrapper > h2 { margin-top:0 margin-bottom:0 } - -.pillarwrapper > div:hover { - box-shadow: 0px 10px 20px rgba(30, 30, 30, 0.16); -} - -.pillarcard { -padding-bottom:0px; -width:33vw; -} -.pillarcard img { -opacity: 0.8; -transition: ease-in-out 200ms; -} -.pillarcard:hover img { -opacity: 1.0; +.badge-licence-noup { + padding: 0; + color: red; + cursor: default; +} + +.badge-licence-lowup { + padding: 0; + color: yellow; + cursor: default; +} + + +/* Make cards look right */ +.md-typeset .grid.cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); + gap: 1rem; + margin: 0 auto; + width: 100%; +} + +.cards>a>img { + width: 50%; + margin: auto; + display: block; + filter: brightness(0); +} + +.cards>a:hover>img { + filter: none; +} + +.cards { + color: var(--md-typeset-color); /* I don't think this does anything */ +} + +.cards>a { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + padding: .8rem; + transition: border .25s, box-shadow .25s; +} + +.cards>a:hover { + border-color: #0000; + box-shadow: var(--md-shadow-z2); +} + +.cards>a>hr, +.cards>a>h3, +.grid.cards>a>h3, +.grid.cards>a>p { + margin: 0; + color: rgba(0, 0, 0, 0.87); +} + +[data-md-color-scheme="slate"] .grid.cards>a>img { + filter: brightness(0) invert(0.75); +} + +[data-md-color-scheme="slate"] .grid.cards>a:hover>img { + filter: invert(0.75); +} + +[data-md-color-scheme="slate"] .grid.cards>a>h3 { + color: var(--md-typeset-color); +} + +[data-md-color-scheme="slate"] .grid.cards>a>p { + color: var(--md-typeset-color); +} + + +/* Tutorial header */ +.tutorial-banner { + display: none; + background: var(--reannz-green); + color: var(--reannz-green--dark); + font-family: inherit; + padding: 0.01em; + margin: 0; + border-radius: 0.8em; +} + +.tutorial-banner>p { + margin: 0; + padding: 0.2em 0.5em; +} + +/* Calendar */ + +.md-event-banner { + background: #fffae6; + border-bottom: 1px solid #ccc; + font-size: 1.2em; + text-align: center; + + z-index: 9999; +} + +.md-event-banner button { + position: absolute; + top: 4px; + right: 6px; + font-size: 2em; + cursor: pointer; +} + +/* custom admonition */ +/* prereq */ + +.md-typeset .admonition.prerequisite, +.md-typeset details.prerequisite { + border-color: var(--reannz-green); +} + +.md-typeset .prerequisite>.admonition-title, +.md-typeset .prerequisite>summary { + background-color: rgba(190, 184, 6, 0.1); + /*above color*/ +} + +.md-typeset .prerequisite>.admonition-title::before, +.md-typeset .prerequisite>summary::before { + background-color: var(--reannz-green); + -webkit-mask-image: var(--md-admonition-icon--prerequisite); + mask-image: var(--md-admonition-icon--prerequisite); +} + +/* postreq */ +.md-typeset .admonition.postrequisite, +.md-typeset details.postrequisite { + border-color: rgb(170, 170, 60); +} + +.md-typeset .postrequisite>.admonition-title, +.md-typeset .postrequisite>summary { + background-color: rgba(170, 170, 60, 0.1); +} + +.md-typeset .postrequisite>.admonition-title::before, +.md-typeset .postrequisite>summary::before { + background-color: rgb(170, 170, 60); + -webkit-mask-image: var(--md-tabbed-icon--next); + mask-image: var(--md-tabbed-icon--next); +} + +/* deprecated */ +.md-typeset .admonition.deprecated, +.md-typeset details.deprecated { + border-color: #ff1744; +} + +.md-typeset .deprecated>.admonition-title, +.md-typeset .deprecated>summary { + background-color: #ff17441a; +} + +.md-typeset .deprecated>.admonition-title::before, +.md-typeset .deprecated>summary::before { + background-color: #ff1744; + -webkit-mask-image: var(--md-status--deprecated); + mask-image: var(--md-status--deprecated); +} + +/* time */ +.md-typeset .admonition.time, +.md-typeset details.time { + border-color: var(--reannz-green--dark); +} + +.md-typeset .time>.admonition-title, +.md-typeset .time>summary { + background-color: rgba(0, 170, 136, 0.1); +} + +.md-typeset .time>.admonition-title::before, +.md-typeset .time>summary::before { + background-color: var(--reannz-green--dark); + -webkit-mask-image: var(--md-admonition-icon--time); + mask-image: var(--md-admonition-icon--time); +} + +/* objectivess */ +.md-typeset .admonition.objectives, +.md-typeset details.time { + border-color: var(--reannz-purple) +} + +.md-typeset .objectives>.admonition-title, +.md-typeset .objectives>summary { + background-color: rgba(132, 121, 183, 0.1); +} + +.md-typeset .objectives>.admonition-title::before, +.md-typeset .objectives>summary::before { + background-color: var(--reannz-purple); + -webkit-mask-image: var(--md-admonition-icon--prerequisite); + mask-image: var(--md-admonition-icon--prerequisite); +} + +/* key[ppoint */ +.md-typeset .admonition.keypoints, +.md-typeset details.keypoints { + border-color: var(--reannz-grey); +} + +.md-typeset .keypoints>.admonition-title, +.md-typeset .keypoints>summary { + background-color: rgba(195, 200, 200, 0.1); +} + +.md-typeset .keypoints>.admonition-title::before, +.md-typeset .keypoints>summary::before { + background-color: var(--reannz-grey); + -webkit-mask-image: var(--md-admonition-icon--prerequisite); + mask-image: var(--md-admonition-icon--prerequisite); +} + +/* Quiz formatting */ +/* Duplicate admonition thmem */ +div.quiz { + border: .075rem solid var(--reannz-orange); + border-radius: .2rem; + box-shadow: var(--md-shadow-z1); + color: var(--md-admonition-fg-color); + display: flow-root; + font-size: .64rem; + margin: 1.5625em 0; + padding: 0 .6rem; + page-break-inside: avoid; + transition: box-shadow 125ms; +} + +.quiz-button{ +position: absolute; + right: auto; + bottom: -1.5rem; + border-radius: 10px; + font-size: 0.8rem; + left: 0.5rem; + right: auto; +} +.quiz-question > .admonition-title{ + background-color: rgba(241, 128, 0, 0.1); +} + +.quiz-question > .admonition-titl e::before{ + mask-image: var(--md-admonition-icon--example); + background-color: var(--reannz-orange); +} + +div.quiz-feedback { + margin: 0 -0.6rem -10px -0.6rem; + border-radius: 0 0 .2rem .2rem; + border-style: none; +} + +/* Formatting a bit broke. hide for now */ +.quiz-header-link{ + display: none; } diff --git a/docs/release-notes/pages.yml b/docs/release-notes/pages.yml index 11b94bb..daf4c3c 100644 --- a/docs/release-notes/pages.yml +++ b/docs/release-notes/pages.yml @@ -1,2 +1,2 @@ nav: - - ... + - "*" diff --git a/docs/user-guides/.pages.yml b/docs/user-guides/.pages.yml index b470eca..a642078 100644 --- a/docs/user-guides/.pages.yml +++ b/docs/user-guides/.pages.yml @@ -8,4 +8,4 @@ nav: - create-and-manage-keypairs - create-and-manage-object-storage - set-up-your-cli-environment - - ... + - "*" diff --git a/docs/user-guides/create-and-manage-networks/with_the_dashboard/.pages.yml b/docs/user-guides/create-and-manage-networks/with_the_dashboard/.pages.yml index 73ed4a0..b214369 100644 --- a/docs/user-guides/create-and-manage-networks/with_the_dashboard/.pages.yml +++ b/docs/user-guides/create-and-manage-networks/with_the_dashboard/.pages.yml @@ -3,4 +3,4 @@ nav: - manage-security-groups-with-the-dashboard.md - create-and-manage-network-ports-with-the-dashboard.md - manage-floating-ips-via-the-dashboard.md - - ... + - "*" diff --git a/docs/user-guides/create-and-manage-object-storage/.pages.yml b/docs/user-guides/create-and-manage-object-storage/.pages.yml index 3b614aa..1487a4a 100644 --- a/docs/user-guides/create-and-manage-object-storage/.pages.yml +++ b/docs/user-guides/create-and-manage-object-storage/.pages.yml @@ -4,4 +4,4 @@ nav: - creating-and-managing-ec2-credentials-via-cli.md - using-boto3-to-interact-with-object-storage.md - using-cyberduck-to-interact-with-object-storage.md - - ... + - "*" diff --git a/docs/user-guides/create-and-manage-volumes/.pages.yml b/docs/user-guides/create-and-manage-volumes/.pages.yml index ac16daa..45073e4 100644 --- a/docs/user-guides/create-and-manage-volumes/.pages.yml +++ b/docs/user-guides/create-and-manage-volumes/.pages.yml @@ -2,4 +2,4 @@ nav: - with_the_dashboard - with_the_cli - format-and-mount-volumes.md - - ... + - "*" diff --git a/docs/user-guides/launch-and-manage-instances/.pages.yml b/docs/user-guides/launch-and-manage-instances/.pages.yml index 55a6388..6b7bda2 100644 --- a/docs/user-guides/launch-and-manage-instances/.pages.yml +++ b/docs/user-guides/launch-and-manage-instances/.pages.yml @@ -5,4 +5,4 @@ nav: - other_tools - connect-to-instance-ssh.md - default-user-nesi-images.md - - ... + - "*" diff --git a/docs/user-guides/upload-and-manage-images/.pages.yml b/docs/user-guides/upload-and-manage-images/.pages.yml index 7d4193a..8845a41 100644 --- a/docs/user-guides/upload-and-manage-images/.pages.yml +++ b/docs/user-guides/upload-and-manage-images/.pages.yml @@ -4,4 +4,4 @@ nav: - with-the-cli - converting_image-types.md - image-filter.md -- ... +- "*" diff --git a/docs/user-guides/upload-and-manage-images/with-the-cli/.pages.yml b/docs/user-guides/upload-and-manage-images/with-the-cli/.pages.yml index 676da9f..0617e1f 100644 --- a/docs/user-guides/upload-and-manage-images/with-the-cli/.pages.yml +++ b/docs/user-guides/upload-and-manage-images/with-the-cli/.pages.yml @@ -1,4 +1,4 @@ nav: - upload-an-image-via-cli.md - managing-images-via-cli.md - - ... + - "*" diff --git a/docs/user-guides/upload-and-manage-images/with-the-dashboard/.pages.yml b/docs/user-guides/upload-and-manage-images/with-the-dashboard/.pages.yml index 72c420f..468ceda 100644 --- a/docs/user-guides/upload-and-manage-images/with-the-dashboard/.pages.yml +++ b/docs/user-guides/upload-and-manage-images/with-the-dashboard/.pages.yml @@ -1,4 +1,4 @@ nav: - upload-an-image-via-the-dashboard.md - managing-images-via-the-dashboard.md - - ... + - "*" diff --git a/local-development-environment.md b/local-development-environment.md index 7cb4a39..fd059b0 100644 --- a/local-development-environment.md +++ b/local-development-environment.md @@ -20,4 +20,4 @@ Once the above items are installed you can then serve the files locally with the mkdocs serve ``` -Then browse to http://localhost:8000/ \ No newline at end of file +Then browse to http://localhost:8000/ diff --git a/mkdocs.yml b/mkdocs.yml index 63697d0..f2f05c8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,13 +9,23 @@ theme: language: en logo: assets/icons/logo_reannz.svg palette: - - primary: custom + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" scheme: default toggle: icon: material/lightbulb name: Switch to dark mode - - primary: custom + primary: custom + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" scheme: slate + primary: custom + accent: custom toggle: icon: material/lightbulb-outline name: Switch to light mode @@ -66,7 +76,7 @@ plugins: - git-revision-date-localized: enable_creation_date: true - open-in-new-tab - - awesome-pages: + - awesome-nav: filename: .pages.yml # - git-authors - tags: @@ -75,6 +85,11 @@ plugins: on_error_fail: true verbose: false extra: + slurm: slurm-25.05.6 + status: + - deprecated + - new + - tutorial analytics: provider: google property: G-C9SP9NWT3Z diff --git a/overrides/home.html b/overrides/home.html new file mode 100644 index 0000000..80d5649 --- /dev/null +++ b/overrides/home.html @@ -0,0 +1,4 @@ +{% extends "main.html" -%} +{% block libs %} + {{ super() }} +{% endblock -%} diff --git a/overrides/main.html b/overrides/main.html index cc65e21..b5b2561 100644 --- a/overrides/main.html +++ b/overrides/main.html @@ -31,11 +31,12 @@ {% endif %} {% endblock %} {% block content %} -{% if page.meta and page.meta.status and page.meta.status == "deprecated" %} -
Page Deprecated
-Information you find on this page may be out of date and no longer accurate.
-