pebble/devsite/lib/pebble_documentation_c.rb
2025-02-24 18:58:29 -08:00

189 lines
5.5 KiB
Ruby

# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'pygments'
require 'zip'
require 'nokogiri'
require 'htmlentities'
require_relative 'c_docs/doc_group.rb'
module Pebble
# Pebble C documentation processing class.
class DocumentationC < Documentation
MASTER_GROUP_IDS = %w(foundation graphics u_i smartstrap worker standard_c)
def initialize(site, source, root, language='c')
super(site)
@site = site
@url_root = root
@source = source
@tmp_dir = 'tmp/docs/c'
@groups = []
@language = language
run
end
private
def language
@language
end
def run
cleanup
download_and_extract(@source, @tmp_dir)
hack_smartstraps
process
add_images
end
def cleanup
FileUtils.rmtree @tmp_dir
end
def download_and_extract(zip, folder)
open(zip) do | zf |
Zip::File.open(zf.path) do | zipfile |
zipfile.each do | entry |
path = File.join(folder, entry.name).sub('/doxygen_sdk/', '/')
FileUtils.mkdir_p(File.dirname(path))
zipfile.extract(entry, path) unless File.exist?(path)
end
end
end
end
# This is a hack to get around a limitation with the documentation generator.
# At present, it cannot handle the situation where a top level doc group exists on
# Basalt but not Aplite.
# Smartstraps is the only group that fits this pattern at the moment.
# This hack copies the XML doc from the Basalt folder to the Aplite folder and removes
# all of its contents.
def hack_smartstraps
basalt_xml = Nokogiri::XML(File.read("#{@tmp_dir}/basalt/xml/group___smartstrap.xml"))
basalt_xml.search('.//memberdef').remove
basalt_xml.search('.//innerclass').remove
basalt_xml.search('.//sectiondef').remove
File.open("#{@tmp_dir}/aplite/xml/group___smartstrap.xml", 'w') do |file|
file.write(basalt_xml.to_xml)
end
end
def process
DocumentationC::MASTER_GROUP_IDS.each do |id|
@groups << DocGroup.new(@url_root, @tmp_dir, 'aplite', id)
end
@groups.each { |group| group.load_xml('basalt') }
mapping = []
@groups.each { |group| mapping += group.mapping_array }
@groups.each do |group|
group.process(mapping, 'aplite')
group.process(mapping, 'basalt')
end
add_symbols(@groups)
@groups.each { |group| @tree << group.to_branch }
add_pages(@groups)
add_redirects(mapping)
end
def add_images
move_images('aplite')
move_images('basalt')
images = Dir.glob("#{@tmp_dir}/assets/images/**/*.png")
images.each do |img|
source = File.join(@site.source, '../tmp/docs/c/')
if File.exists?(img)
img.sub!('tmp/docs/c', '')
@site.static_files << Jekyll::StaticFile.new(@site, source, '', img)
end
end
end
def move_images(platform)
images = Dir.glob("#{@tmp_dir}/#{platform}/**/*.png")
dir = File.join(@tmp_dir, 'assets', 'images', 'docs', 'c', platform)
FileUtils.mkdir_p(dir)
images.each do |img|
FileUtils.cp(img, File.join(dir, File.basename(img)))
end
end
# TODO: Make the groups handle their own subgroups and members etc
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def add_symbols(groups)
groups.each do |group|
add_symbol(group.to_symbol)
group.members.each do |member|
add_symbol(member.to_symbol)
member.children.each do |child|
add_symbol(child.to_symbol)
end
end
group.classes.each do |child|
add_symbol(child.to_symbol)
# OPINION: I don't think we want to have struct members as symbols.
# struct.children.each do |child|
# add_symbol(child.to_symbol)
# end
end
add_symbols(group.groups)
end
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
def add_pages(groups)
groups.each do |group|
page = group.to_page(@site)
page.set_language(@language)
@pages << page
add_pages(group.groups)
end
end
def add_redirects(mapping)
mapping.each do |map|
next if map[:id].match(/_1/)
@site.pages << Jekyll::RedirectPage.new(@site, @site.source, @url_root, map[:id] + '.html', map[:url])
end
end
end
# Jekyll Page subclass for rendering the C documentation pages.
class PageDocC < Jekyll::Page
attr_reader :group
def initialize(site, root, base, dir, group)
@site = site
@base = base
@dir = root
@name = dir
@group = group
process(@name)
read_yaml(File.join(base, '_layouts', 'docs'), 'c.html')
data['title'] = @group.name
data['platforms'] = %w(aplite basalt)
end
def set_language(language)
data['docs_language'] = language
end
def to_liquid(attrs = ATTRIBUTES_FOR_LIQUID)
super(attrs + %w(group))
end
end
end