From 68106a49e401433fe1a613d4e2d5206d014631f4 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Thu, 12 Dec 2024 18:24:19 +0100 Subject: [PATCH] more docs --- _plugins/api.rb | 1 + _plugins/generator-workflows.rb | 26 ++- _plugins/gtn.rb | 8 +- _plugins/jekyll-duration.rb | 201 ++++++++++++----------- _plugins/jekyll-environment_variables.rb | 1 + _plugins/jekyll-figurify.rb | 1 + _plugins/jekyll-tool-tag.rb | 16 ++ 7 files changed, 151 insertions(+), 103 deletions(-) diff --git a/_plugins/api.rb b/_plugins/api.rb index d092d390b3cc0d..a86532cb6ac9ed 100644 --- a/_plugins/api.rb +++ b/_plugins/api.rb @@ -67,6 +67,7 @@ module Jekyll module Generators ## # This class generates the GTN's "api" by writing out a folder full of JSON files. + # TODO: could be a post-write hook. class APIGenerator < Generator ## diff --git a/_plugins/generator-workflows.rb b/_plugins/generator-workflows.rb index 7829f19484e88f..84c74974165cae 100644 --- a/_plugins/generator-workflows.rb +++ b/_plugins/generator-workflows.rb @@ -4,12 +4,32 @@ module Jekyll ## - # Generators are Jekyll's way to let you generate files at runtime, without needing them to exist on disk. + # {Jekyll Generators}[https://jekyllrb.com/docs/plugins/generators/] are a way to let you generate files at runtime, without needing them to exist on disk. # # We use generators for lots of purposes, e.g. # - # +Jekyll::Generators::WorkflowPageGenerator+ emits a webpage for every workflow in the GTN - # +Jekyll::Generators::AuthorPageGenerator+ emits a hall-of-fame entry for every contributor, organisation, and grant listed in our site metadata. + # Real Generators, the way Jekyll intended: + # + # - Jekyll::Generators::APIGenerator - outputs our API + # - Jekyll::Generators::PlaintextSlidesGenerator - turns slides.html into plain text non-JS versions. + # - Jekyll::Generators::RecordingPageGenerator - emits a webpage for every tutorial that has recordings, in the GTN + # - Jekyll::Generators::WorkflowPageGenerator - emits a webpage for every workflow in the GTN + # - Jekyll::Generators::AuthorPageGenerator - emits a hall-of-fame entry for every contributor, organisation, and grant listed in our site metadata. + # - Jekyll::Generators::RmarkdownGenerator - outputs the RMarkdown notebooks for tutorials that want them. + # - Jekyll::Generators::SitemapGenerator2 - alternative for the jekyll-sitemap plugin that's a bit faster. + # - Jekyll::Generators::SyntheticTopicGenerator - our synthetic tag based topics + # - Jekyll::Generators::TagPageGenerator - topic page for every tag + # - Jekyll::Generators::WorkflowPageGenerator + # + # Muck with page contents generators (probably should be hooks): + # + # - Jekyll::Generators::Abbreviate - turns +{something}+ into an abbreviation tag + # - Jekyll::Generators::Figurify - handles our modified markdown for images + # - Jekyll::Generators::Boxify - turns +blah ... {: .box}+ into GTN boxes. + # + # Other generators (also probably should be hooks): + # + # - Jekyll::Generators::EnvironmentVariablesGenerator - adds git revision, tags, and other environment variables to the site object module Generators ## diff --git a/_plugins/gtn.rb b/_plugins/gtn.rb index c992f8d72aec38..0a452b59085cae 100644 --- a/_plugins/gtn.rb +++ b/_plugins/gtn.rb @@ -23,7 +23,13 @@ version_parts = RUBY_VERSION.split('.') Jekyll.logger.warn '[GTN] WARNING: This Ruby is pretty old, you might want to update.' if version_parts[0].to_i < 3 - +## +# We have several sub-areas of Jekyll namespaced things that are useful to know about. +# +# - Jekyll::Filters - Liquid Filters that are useful in rendering your HTML +# - Jekyll::Tags - Liquid Tags can be used to access certain internals in HTML +# - Jekyll::Generators - Generators emit files at runtime, e.g. the hall of fame pages. +# - Jekyll::GtnFunctions - Generally miscellaneous Liquid Functions, could be refactored into Jekyll::Filters and Jekyll::Tags module Jekyll ## # This module contains functions that are used in the GTN, our internal functions that is. diff --git a/_plugins/jekyll-duration.rb b/_plugins/jekyll-duration.rb index 315229d916c3a9..574564e3d8d84f 100644 --- a/_plugins/jekyll-duration.rb +++ b/_plugins/jekyll-duration.rb @@ -1,123 +1,126 @@ # frozen_string_literal: true module Jekyll - # This module contains a filter for converting a duration string into a human readable string. - module DurationFilter - ## - # This function converts a duration string into a human readable string. - # Params: - # +duration+:: The duration string to convert (e.g. 1H30M, RFC 3339 formatted minus the leading P/T) - # Returns: - # +String+:: The human readable string - # - # Example: - # {{ "T1H30M" | duration_to_human }} - # => "1 hour 30 minutes" - def duration_to_human(duration) - seconds = parse_rfc3339(duration) - if seconds.nil? - return duration + module Filters + + # This module contains a filter for converting a duration string into a human readable string. + module DurationFilter + ## + # This function converts a duration string into a human readable string. + # Params: + # +duration+:: The duration string to convert (e.g. 1H30M, RFC 3339 formatted minus the leading P/T) + # Returns: + # +String+:: The human readable string + # + # Example: + # {{ "T1H30M" | duration_to_human }} + # => "1 hour 30 minutes" + def duration_to_human(duration) + seconds = parse_rfc3339(duration) + if seconds.nil? + return duration + end + return fmt_duration(seconds) end - return fmt_duration(seconds) - end - def fmt_duration(seconds) - d = resolve_hms(seconds) + def fmt_duration(seconds) + d = resolve_hms(seconds) - # Otherwise append english terms for the various parts - duration_parts = [] - - hour = 'hour' - hours = 'hours' - minutes = 'minutes' - if @context.registers[:page]&.key?('lang') && (@context.registers[:page]['lang'] != 'en') - lang = @context.registers[:page]['lang'] - hour = @context.registers[:site].data['lang'][lang]['hour'] - hours = @context.registers[:site].data['lang'][lang]['hours'] - minutes = @context.registers[:site].data['lang'][lang]['minutes'] - end + # Otherwise append english terms for the various parts + duration_parts = [] - # Hours - if d[:hours] > 0 - if d[:hours] == 1 - duration_parts.push("#{d[:hours]} " + hour) - else - duration_parts.push("#{d[:hours]} " + hours) + hour = 'hour' + hours = 'hours' + minutes = 'minutes' + if @context.registers[:page]&.key?('lang') && (@context.registers[:page]['lang'] != 'en') + lang = @context.registers[:page]['lang'] + hour = @context.registers[:site].data['lang'][lang]['hour'] + hours = @context.registers[:site].data['lang'][lang]['hours'] + minutes = @context.registers[:site].data['lang'][lang]['minutes'] end - end - # Minutes - assuming no one uses `1 minute` - duration_parts.push("#{d[:minutes]} " + minutes) if d[:minutes] > 0 + # Hours + if d[:hours] > 0 + if d[:hours] == 1 + duration_parts.push("#{d[:hours]} " + hour) + else + duration_parts.push("#{d[:hours]} " + hours) + end + end - # Hopefully no one uses seconds - duration_parts.push("#{d[:seconds]} seconds") if d[:seconds] > 0 + # Minutes - assuming no one uses `1 minute` + duration_parts.push("#{d[:minutes]} " + minutes) if d[:minutes] > 0 - duration_parts.join(' ') - end + # Hopefully no one uses seconds + duration_parts.push("#{d[:seconds]} seconds") if d[:seconds] > 0 - ## - # Sum the durations correctly for multiple RFC3339 formatted durations. - # Params: - # +s+:: The RFC3339 formatted duration string - # Returns: - # +d+:: a number of seconds - def parse_rfc3339(s) - if s == 0 - return 0 + duration_parts.join(' ') end - # Match the different parts of the string, must match entire string or it - # will fail. - match = /^T?(?:([0-9]*)[Hh])*(?:([0-9]*)[Mm])*(?:([0-9.]*)[Ss])*$/.match(s) + ## + # Sum the durations correctly for multiple RFC3339 formatted durations. + # Params: + # +s+:: The RFC3339 formatted duration string + # Returns: + # +d+:: a number of seconds + def parse_rfc3339(s) + if s == 0 + return 0 + end - # If it doesn't match, pass through unedited so we don't cause unexpected - # issues. - if match.nil? - Jekyll.logger.debug "[GTN/Durations]:", "Could not parse time: #{s}" - return nil - end + # Match the different parts of the string, must match entire string or it + # will fail. + match = /^T?(?:([0-9]*)[Hh])*(?:([0-9]*)[Mm])*(?:([0-9.]*)[Ss])*$/.match(s) - return match[1].to_i * 3600 + match[2].to_i * 60 + match[3].to_i - end + # If it doesn't match, pass through unedited so we don't cause unexpected + # issues. + if match.nil? + Jekyll.logger.debug "[GTN/Durations]:", "Could not parse time: #{s}" + return nil + end - ## - # Turn a count of seconds into hours/minutes/seconds. - # Params: - # +Int+:: A number of seconds - # Returns: - # +Hash+:: A hash with keys for hours, minutes, and seconds - # - # Example: - # resolve_hms(5400) - # => { hours: 1, minutes: 30, seconds: 0 } - def resolve_hms(seconds) - # Normalize the total - minutes = seconds / 60 - seconds = seconds % 60 - hours = minutes / 60 - minutes = minutes % 60 - - { hours: hours, minutes: minutes, seconds: seconds } - end + return match[1].to_i * 3600 + match[2].to_i * 60 + match[3].to_i + end + + ## + # Turn a count of seconds into hours/minutes/seconds. + # Params: + # +Int+:: A number of seconds + # Returns: + # +Hash+:: A hash with keys for hours, minutes, and seconds + # + # Example: + # resolve_hms(5400) + # => { hours: 1, minutes: 30, seconds: 0 } + def resolve_hms(seconds) + # Normalize the total + minutes = seconds / 60 + seconds = seconds % 60 + hours = minutes / 60 + minutes = minutes % 60 + + { hours: hours, minutes: minutes, seconds: seconds } + end - ## - # Sum the durations correctly for multiple RFC3339 formatted durations. - # Params: - # +materials+:: The GTN material objects - # Returns: - # +String+:: The human total duration - def sum_duration(materials) - Jekyll.logger.debug "[GTN/Durations]: sum durations with #{materials.length} materials." - total = 0 - materials.each do |material| - if ! material['time_estimation'].nil? - Jekyll.logger.debug " [GTN/Durations]: #{material['time_estimation']} #{material['title']} -> #{parse_rfc3339(material['time_estimation'])}" - total += parse_rfc3339(material['time_estimation']) + ## + # Sum the durations correctly for multiple RFC3339 formatted durations. + # Params: + # +materials+:: The GTN material objects + # Returns: + # +String+:: The human total duration + def sum_duration(materials) + Jekyll.logger.debug "[GTN/Durations]: sum durations with #{materials.length} materials." + total = 0 + materials.each do |material| + if ! material['time_estimation'].nil? + Jekyll.logger.debug " [GTN/Durations]: #{material['time_estimation']} #{material['title']} -> #{parse_rfc3339(material['time_estimation'])}" + total += parse_rfc3339(material['time_estimation']) + end end + fmt_duration(total) end - fmt_duration(total) end end end -Liquid::Template.register_filter(Jekyll::DurationFilter) +Liquid::Template.register_filter(Jekyll::Filters::DurationFilter) diff --git a/_plugins/jekyll-environment_variables.rb b/_plugins/jekyll-environment_variables.rb index 4f201e3eb11577..becfdcbf4bce4e 100644 --- a/_plugins/jekyll-environment_variables.rb +++ b/_plugins/jekyll-environment_variables.rb @@ -9,6 +9,7 @@ module Jekyll module Generators # This module contains a generator for adding environment variables to the `site` object in Liquid templates + # TODO: definitely could be a hook instead of a generator class EnvironmentVariablesGenerator < Generator ## # Environment variables are added to the `site` object in Liquid templates. diff --git a/_plugins/jekyll-figurify.rb b/_plugins/jekyll-figurify.rb index 0b7e4b75081951..0aa1825283744d 100644 --- a/_plugins/jekyll-figurify.rb +++ b/_plugins/jekyll-figurify.rb @@ -5,6 +5,7 @@ module Jekyll module Generators # Our modifications to the markdown renderer to process images with figure captions + # TODO: probably could be a hook post_read. class Figurify < Jekyll::Generator safe true diff --git a/_plugins/jekyll-tool-tag.rb b/_plugins/jekyll-tool-tag.rb index 01e8e65cda76d5..6073e13bb7141e 100644 --- a/_plugins/jekyll-tool-tag.rb +++ b/_plugins/jekyll-tool-tag.rb @@ -1,6 +1,22 @@ # frozen_string_literal: true module Jekyll + ## + # Tags are useful in liquid to process data and access internal functions. Ruby functions are *always* faster than liquid templates, so, when possible, consider writing a custom Ruby filter or tag. + # + # + # - Jekyll::Tags::BibTag - {% bibliography %} + # - Jekyll::Tags::CiteTag - {% cite hiltemann2023galaxy, %} + # - Jekyll::Tags::CiteUrlTag - {% cite_url Batut2018 %} + # - Jekyll::Tags::ColorPickerTag - {% color_picker #ff0000 %} + # - Jekyll::Tags::CustomLinkTag - {% link file.md %} + # - Jekyll::Tags::DumpSearchDataTag - {% dump_search_view testing %} + # - Jekyll::Tags::FileExistsTag - {% file_exists path.md %} + # - Jekyll::Tags::IconTag - {% icon email %} + # - Jekyll::Tags::IconTagVar - {% icon var1 %} + # - Jekyll::Tags::SnippetIncludeTag - {% snippet %} + # - Jekyll::Tags::ToolTag - {% tool [My Tool](Grouping1) %} + # - Jekyll::Tags::WorkflowTag - unused? module Tags # The tool tag which allows us to do fancy tool links