From 9f7ebd8b0bee277855d46815c2a8bf90b359c336 Mon Sep 17 00:00:00 2001 From: Anton Strogonoff Date: Mon, 26 Nov 2018 15:54:10 +0800 Subject: [PATCH] feat: Spec builders with PNG diagram as first PoC (#9) --- jekyll-theme-open-project-helpers.gemspec | 1 + lib/jekyll-theme-open-project-helpers.rb | 1 + .../project_data_reader.rb | 74 +++++++++++++++++-- .../spec_builders/png_diagram.html | 31 ++++++++ .../spec_builders/png_diagrams.rb | 66 +++++++++++++++++ .../spec_builders/spec_builder.rb | 33 +++++++++ 6 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 lib/jekyll-theme-open-project-helpers/spec_builders/png_diagram.html create mode 100644 lib/jekyll-theme-open-project-helpers/spec_builders/png_diagrams.rb create mode 100644 lib/jekyll-theme-open-project-helpers/spec_builders/spec_builder.rb diff --git a/jekyll-theme-open-project-helpers.gemspec b/jekyll-theme-open-project-helpers.gemspec index 1b96edc..2f65b4f 100644 --- a/jekyll-theme-open-project-helpers.gemspec +++ b/jekyll-theme-open-project-helpers.gemspec @@ -14,6 +14,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'jekyll', '~> 3.8' s.add_runtime_dependency 'git', '~> 1.4' + s.add_runtime_dependency 'fastimage', '~> 2.1.4' s.add_development_dependency 'rake', '~> 12.0' s.add_development_dependency 'rubocop', '~> 0.50' diff --git a/lib/jekyll-theme-open-project-helpers.rb b/lib/jekyll-theme-open-project-helpers.rb index 6359e18..86fe4f0 100644 --- a/lib/jekyll-theme-open-project-helpers.rb +++ b/lib/jekyll-theme-open-project-helpers.rb @@ -8,6 +8,7 @@ require 'jekyll-theme-open-project-helpers/filterable_index' require 'jekyll-theme-open-project-helpers/blog_index' require 'jekyll-theme-open-project-helpers/external_links' +require 'jekyll-theme-open-project-helpers/spec_builders/spec_builder' module Jekyll diff --git a/lib/jekyll-theme-open-project-helpers/project_data_reader.rb b/lib/jekyll-theme-open-project-helpers/project_data_reader.rb index 7fb354a..7b1a04f 100644 --- a/lib/jekyll-theme-open-project-helpers/project_data_reader.rb +++ b/lib/jekyll-theme-open-project-helpers/project_data_reader.rb @@ -69,8 +69,8 @@ def read if @site.config['is_hub'] fetch_and_read_projects else - fetch_and_read_docs_for_items('software') - fetch_and_read_docs_for_items('specs') + fetch_and_read_software('software') + fetch_and_read_specs('specs') fetch_hub_logo end end @@ -99,14 +99,74 @@ def fetch_and_read_projects project['site']['git_repo_url'], ['assets', '_posts', '_software', '_specs']) - fetch_and_read_docs_for_items('projects') + fetch_and_read_software('projects') + fetch_and_read_specs('projects') end end - def fetch_and_read_docs_for_items(collection_name) - # In this context, “docs” means Jekyll documents. For software it would be - # documentation, and for specs it would be spec contents. - # collection_name would be either software, specs, or (for hub site) projects + def build_and_read_spec_pages(collection_name, index_doc) + item_name = index_doc.id.split('/')[-1] + + repo_checkout = nil + src = index_doc.data['spec_source'] + repo_url = src['git_repo_url'] + repo_subtree = src['git_repo_subtree'] + build = src['build'] + engine = build['engine'] + engine_opts = build['options'] || {} + + spec_checkout_path = "#{index_doc.path.split('/')[0..-2].join('/')}/#{item_name}" + spec_root = if repo_subtree + "#{spec_checkout_path}/#{repo_subtree}" + else + spec_checkout_path + end + + begin + repo_checkout = git_shallow_checkout(spec_checkout_path, repo_url, [repo_subtree]) + rescue + repo_checkout = nil + end + + if repo_checkout + builder = Jekyll::OpenProjectHelpers::SpecBuilder::new( + @site, + index_doc, + spec_root, + "specs/#{item_name}", + engine, + engine_opts) + + builder.build() + builder.built_pages.each do |page| + @site.pages << page + end + + CollectionDocReader.new(site).read( + spec_checkout_path, + @site.collections[collection_name]) + + index_doc.merge_data!({ 'last_update' => repo_checkout[:modified_at] }) + end + end + + def fetch_and_read_specs(collection_name) + # collection_name would be either specs or (for hub site) projects + + return unless @site.collections.key?(collection_name) + + # Get spec entry points + entry_points = @site.collections[collection_name].docs.select do |doc| + doc.data['spec_source'] + end + + entry_points.each do |index_doc| + build_and_read_spec_pages(collection_name, index_doc) + end + end + + def fetch_and_read_software(collection_name) + # collection_name would be either software or (for hub site) projects return unless @site.collections.key?(collection_name) diff --git a/lib/jekyll-theme-open-project-helpers/spec_builders/png_diagram.html b/lib/jekyll-theme-open-project-helpers/spec_builders/png_diagram.html new file mode 100644 index 0000000..cb2568b --- /dev/null +++ b/lib/jekyll-theme-open-project-helpers/spec_builders/png_diagram.html @@ -0,0 +1,31 @@ +{% comment %}Page stub.{% endcomment %} + +
+ + + + diff --git a/lib/jekyll-theme-open-project-helpers/spec_builders/png_diagrams.rb b/lib/jekyll-theme-open-project-helpers/spec_builders/png_diagrams.rb new file mode 100644 index 0000000..c469a26 --- /dev/null +++ b/lib/jekyll-theme-open-project-helpers/spec_builders/png_diagrams.rb @@ -0,0 +1,66 @@ +require 'fastimage' + +module Builder + + class PngDiagramPage < Jekyll::Page + def initialize(site, base, dir, data) + @site = site + @base = base + @dir = dir + @name = 'index.html' + + self.process(@name) + self.data ||= data + + self.data['extra_stylesheets'] = [{ + "href" => "https://unpkg.com/leaflet@1.3.4/dist/leaflet.css", + "integrity" => "sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==", + "crossorigin" => "", + }] + + self.data['extra_scripts'] = [{ + "src" => "https://unpkg.com/leaflet@1.3.4/dist/leaflet.js", + "integrity" => "sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==", + "crossorigin" => "", + }] + + self.data['layout'] = 'spec' + end + end + + def build_spec_pages(site, spec_info, source, destination, opts) + images_path = source + spec_root = destination + stub_path = "#{File.dirname(__FILE__)}/png_diagram.html" + pages = [] + + Dir.glob("#{images_path}/*.png") do |pngfile| + png_name = File.basename(pngfile) + png_name_noext = File.basename(png_name, File.extname(png_name)) + + nav_item = spec_info.data['navigation']['sections'].map { |section| + section['items'] + } .flatten.select { |item| item['path'] == png_name_noext} [0].clone + + png_dimensions = FastImage.size(pngfile) + data = spec_info.data.clone + data['image_path'] = "/#{spec_root}/images/#{png_name}" + data['image_width'] = png_dimensions[0] + data['image_height'] = png_dimensions[1] + data = data.merge(nav_item) + + data['title'] = "#{spec_info['title']}: #{nav_item['title']}" + + page = PngDiagramPage.new( + site, + site.source, + File.join(spec_root, png_name_noext), + data) + page.content = File.read(stub_path) + pages << page + end + + return pages + end + +end diff --git a/lib/jekyll-theme-open-project-helpers/spec_builders/spec_builder.rb b/lib/jekyll-theme-open-project-helpers/spec_builders/spec_builder.rb new file mode 100644 index 0000000..d8e8b54 --- /dev/null +++ b/lib/jekyll-theme-open-project-helpers/spec_builders/spec_builder.rb @@ -0,0 +1,33 @@ +require 'forwardable' + +module Jekyll + module OpenProjectHelpers + class SpecBuilder + + attr_reader :built_pages + + def initialize(site, spec_index_doc, spec_source_base, spec_out_base, engine, opts) + require_relative engine + extend Builder # adds the build_spec_pages method + + @site = site + @spec_index_doc = spec_index_doc + @spec_source_base = spec_source_base + @spec_out_base = spec_out_base + @opts = opts + + @built_pages = [] + end + + def build() + @built_pages = build_spec_pages( + @site, + @spec_index_doc, + @spec_source_base, + @spec_out_base, + @opts) + end + + end + end +end