# 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. module Pebble # Class of methods for processing Doxygen XML into 'sane' HTML. # rubocop:disable Metrics/ClassLength class DoxygenProcessor def initialize(platform) @platform = platform end def process_summary(node, mapping) process_description(node, mapping) end def process_description(node, mapping) return '' if node.nil? node.children.map { |para| process_paragraph(para, mapping) }.join("\n").strip end # rubocop:disable Metrics/MethodLength, Methods/CyclomaticComplexity # rubocop:disable Methods/AbcSize def process_paragraph(node, mapping) return '' if node.nil? node.name = 'p' node.children.each do |child| case child.name when 'ref' process_node_ref(child, mapping) when 'programlisting' process_code(child) when 'simplesect' # puts node.content.to_s # process_blockquote(child) when 'heading' process_node_heading(child) when 'htmlonly' process_node_htmlonly(child) when 'itemizedlist' process_list(child, mapping) when 'image' process_image(child) when 'computeroutput' process_computer_output(child) when 'emphasis' child.name = 'em' when 'bold' child.name = 'strong' when 'linebreak' child.name = 'br' when 'preformatted' child.name = 'pre' when 'ndash' child.name = 'span' child.content = '-' when 'ulink' child.name = 'a' child['href'] = child['url'].sub(%r{^https?://developer.pebble.com/}, '/') child.remove_attribute('url') when 'text' # SKIP! else # puts child.name, node.content.to_s end end node.to_html.to_s.strip end # rubocop:enable Metrics/MethodLength, Methods/CyclomaticComplexity # rubocop:enable Methods/AbcSize def process_code(node) xml = node.to_xml.gsub('', ' ') doc = Nokogiri::XML(xml) highlight = Pygments.highlight(doc.content.to_s.strip, lexer: 'c') node.content = '' node << Nokogiri::XML(highlight).at_css('pre') node.name = 'div' node['class'] = 'highlight' end def process_node_ref(child, mapping) child.name = 'a' map = mapping.select { |m| m[:id] == child['refid'] }.first child['href'] = map[:url] unless map.nil? end def process_node_heading(node) node.name = 'h' + node['level'] end def process_node_htmlonly(node) decoder = HTMLEntities.new xml = Nokogiri::XML('' + decoder.decode(node.content) + '') node_count = xml.root.children.size process_node_htmlonly_simple(node, xml) if node_count == 2 process_node_htmlonly_complex(node, xml) if node_count > 2 end def process_node_htmlonly_simple(node, xml) child = xml.at_css('root').children[0] node.name = child.name child.attributes.each { |key, value| node[key] = value } node.content = child.content end def process_node_htmlonly_complex(node, xml) node.name = 'div' node.content = '' node << xml.root.children end def process_blockquote(node) node.name = 'blockquote' node['class'] = 'blockquote--' + node['kind'] process_paragraph(node.children[0]) if node.children[0].name == 'para' node.to_html.to_s end def process_list(node, mapping) node.name = 'ul' node.children.each do |child| process_list_item(child, mapping) end end def process_list_item(node, mapping) node.name = 'li' node.children.each do |child| process_paragraph(child, mapping) if child.name == 'para' end end def process_image(node) node.name = 'img' node['src'] = "/assets/images/docs/c/#{@platform}/#{node['name']}" end def process_computer_output(node) node.name = 'code' end end # rubocop:enable Metrics/ClassLength end