# 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_relative 'doc_enum_value.rb' module Pebble # A DocMember is a function, enum, typedef that will become a symbol # and be a part of a documentation page. Belongs to a DocGroup. class DocMember < DocElement attr_accessor :children, :kind, :name, :summary, :children, :position, :data, :id def initialize(root, node, group, platform) super(root, platform) @group = group @children = [] @platforms = [platform] @nodes = { platform => node } @name = node.at_css('name').content.to_s @kind = node['kind'] @id = node['id'] @path = "#{@group.path}##{@name}" @position = node.at_css(' > location')['line'].to_i @doxygen_processor = DoxygenProcessor.new(platform) create_enum_values(node, platform) if @kind == 'enum' end def add_platform(platform, node) @platforms << platform @nodes[platform] = node @data[platform] = {} create_enum_values(node, platform) if @kind == 'enum' end def to_liquid { 'name' => @name, 'url' => url, 'children' => @children, 'position' => @position, 'data' => @data, 'uniform' => uniform?, 'platforms' => @platforms } end def process(mapping, platform) return unless @platforms.include? platform @data[platform]['summary'] = @doxygen_processor.process_summary( @nodes[platform].at_css(' > briefdescription'), mapping ) process_data(@nodes[platform], mapping, platform) @data[platform]['description'] = @doxygen_processor.process_description( @nodes[platform].at_css(' > detaileddescription'), mapping ) @children.each { |child| child.process(mapping, platform) } end def uniform? identical = data['aplite'].to_json == data['basalt'].to_json identical &&= children.all?(&:uniform?) if @kind == 'enum' identical end private def create_enum_values(node, platform) node.css('enumvalue').each do |value| enum_value = DocEnumValue.new(@root, value, @group, platform) existing_value = @children.select { |ev| ev.name == enum_value.name }.first if existing_value.nil? @children << enum_value else existing_value.add_platform(value, platform) end end end def process_data(node, mapping, platform) process_typedef(node, mapping, platform) if @kind == 'typedef' process_function(node, mapping, platform) if @kind == 'function' process_define(node, mapping, platform) if @kind == 'define' process_simplesects(node, mapping, platform) end def process_typedef(node, mapping, platform) process_return_type(node, mapping, platform) @data[platform]['argsstring'] = node.at_css('argsstring').content.to_s process_parameter_list(node, mapping, platform) end def process_function(node, mapping, platform) process_return_type(node, mapping, platform) process_params(node, mapping, platform) unless node.css('param').nil? process_parameter_list(node, mapping, platform) end def process_define(node, mapping, platform) unless node.at_css('initializer').nil? @data[platform]['initializer'] = process_to_html( node.at_css('initializer'), mapping ) end process_return_type(node, mapping, platform) process_parameter_list(node, mapping, platform) process_params(node, mapping, platform) unless node.css('param').nil? end def process_return_type(node, mapping, platform) @data[platform]['type'] = process_to_html(node.at_css('> type'), mapping) end def process_params(node, mapping, platform) @data[platform]['params'] = node.css('param').map do |elem| params = {} unless elem.at_css('declname').nil? params['name'] = elem.at_css('declname').content.to_s end unless elem.at_css('type').nil? params['type'] = process_to_html(elem.at_css('type'), mapping) end unless elem.at_css('defname').nil? params['name'] = elem.at_css('defname').content.to_s end params end end def process_to_html(node, mapping) return '' if node.nil? node.css('ref').each do |ref| @doxygen_processor.process_node_ref(ref, mapping) end node.inner_html.to_s end def process_parameter_list(node, mapping, platform) return if node.at_css('parameterlist').nil? parameter_list = node.at_css('parameterlist').clone node.at_css('parameterlist').remove @data[platform]['parameters'] = parameter_list.css('parameteritem').map do |item| { 'name' => get_parameter_name(item), 'summary' => @doxygen_processor.process_summary(item.at_css('parameterdescription'), mapping) } end end def get_parameter_name(item) name = item.at_css('parameternamelist > parametername') direction = name.attr('direction').to_s direction.nil? || direction == '' ? name.content.to_s : "#{name.content.to_s} (#{direction})" end end end