102f4aeb0Sopenharmony_ci#!/usr/bin/python3 202f4aeb0Sopenharmony_ci# 302f4aeb0Sopenharmony_ci# Copyright (c) 2013-2014 The Khronos Group Inc. 402f4aeb0Sopenharmony_ci# 502f4aeb0Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 602f4aeb0Sopenharmony_ci# copy of this software and/or associated documentation files (the 702f4aeb0Sopenharmony_ci# "Materials"), to deal in the Materials without restriction, including 802f4aeb0Sopenharmony_ci# without limitation the rights to use, copy, modify, merge, publish, 902f4aeb0Sopenharmony_ci# distribute, sublicense, and/or sell copies of the Materials, and to 1002f4aeb0Sopenharmony_ci# permit persons to whom the Materials are furnished to do so, subject to 1102f4aeb0Sopenharmony_ci# the following conditions: 1202f4aeb0Sopenharmony_ci# 1302f4aeb0Sopenharmony_ci# The above copyright notice and this permission notice shall be included 1402f4aeb0Sopenharmony_ci# in all copies or substantial portions of the Materials. 1502f4aeb0Sopenharmony_ci# 1602f4aeb0Sopenharmony_ci# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1702f4aeb0Sopenharmony_ci# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1802f4aeb0Sopenharmony_ci# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1902f4aeb0Sopenharmony_ci# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 2002f4aeb0Sopenharmony_ci# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2102f4aeb0Sopenharmony_ci# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2202f4aeb0Sopenharmony_ci# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 2302f4aeb0Sopenharmony_ci 2402f4aeb0Sopenharmony_ciimport io, os, re, string, sys; 2502f4aeb0Sopenharmony_ci 2602f4aeb0Sopenharmony_ciif __name__ == '__main__': 2702f4aeb0Sopenharmony_ci if (len(sys.argv) != 5): 2802f4aeb0Sopenharmony_ci print('Usage:', sys.argv[0], ' gendir srcdir accordfilename flatfilename', file=sys.stderr) 2902f4aeb0Sopenharmony_ci exit(1) 3002f4aeb0Sopenharmony_ci else: 3102f4aeb0Sopenharmony_ci gendir = sys.argv[1] 3202f4aeb0Sopenharmony_ci srcdir = sys.argv[2] 3302f4aeb0Sopenharmony_ci accordfilename = sys.argv[3] 3402f4aeb0Sopenharmony_ci flatfilename = sys.argv[4] 3502f4aeb0Sopenharmony_ci # print(' gendir = ', gendir, ' srcdir = ', srcdir, 'accordfilename = ', accordfilename, 'flatfilename = ', flatfilename) 3602f4aeb0Sopenharmony_cielse: 3702f4aeb0Sopenharmony_ci print('Unknown invocation mode', file=sys.stderr) 3802f4aeb0Sopenharmony_ci exit(1) 3902f4aeb0Sopenharmony_ci 4002f4aeb0Sopenharmony_ci# Various levels of indentation in generated HTML 4102f4aeb0Sopenharmony_ciind1 = ' ' 4202f4aeb0Sopenharmony_ciind2 = ind1 + ind1 4302f4aeb0Sopenharmony_ciind3 = ind2 + ind1 4402f4aeb0Sopenharmony_ciind4 = ind2 + ind2 4502f4aeb0Sopenharmony_ci 4602f4aeb0Sopenharmony_ci# Symbolic names 4702f4aeb0Sopenharmony_cinotAlias = False 4802f4aeb0Sopenharmony_ciisAlias = True 4902f4aeb0Sopenharmony_ci 5002f4aeb0Sopenharmony_ci# Page title 5102f4aeb0Sopenharmony_cipageTitle = 'EGL Reference Pages' 5202f4aeb0Sopenharmony_ci 5302f4aeb0Sopenharmony_ci# Docbook source and generated HTML 5 file extensions 5402f4aeb0Sopenharmony_cisrcext = '.xml' 5502f4aeb0Sopenharmony_cigenext = '.xhtml' 5602f4aeb0Sopenharmony_ci 5702f4aeb0Sopenharmony_ci# List of generated files 5802f4aeb0Sopenharmony_cifiles = os.listdir(gendir) 5902f4aeb0Sopenharmony_ci 6002f4aeb0Sopenharmony_ci# Feature - class representing a command or function to be indexed, used 6102f4aeb0Sopenharmony_ci# as dictionary values keyed by the feature name to be indexed. 6202f4aeb0Sopenharmony_ci# 6302f4aeb0Sopenharmony_ci# Members 6402f4aeb0Sopenharmony_ci# file - name of file containing the feature 6502f4aeb0Sopenharmony_ci# feature - feature name for the index (basis for the dictionary key). 6602f4aeb0Sopenharmony_ci# alias - True if this is an alias of another feature in the file. 6702f4aeb0Sopenharmony_ci# Usually if alias is False, feature is the basename of file. 6802f4aeb0Sopenharmony_ci# apiCommand - True if this is an API command, or should be grouped 6902f4aeb0Sopenharmony_ci# like one 7002f4aeb0Sopenharmony_ciclass Feature: 7102f4aeb0Sopenharmony_ci def __init__(self, 7202f4aeb0Sopenharmony_ci file = None, 7302f4aeb0Sopenharmony_ci feature = None, 7402f4aeb0Sopenharmony_ci alias = False, 7502f4aeb0Sopenharmony_ci apiCommand = None): 7602f4aeb0Sopenharmony_ci self.file = file 7702f4aeb0Sopenharmony_ci self.feature = feature 7802f4aeb0Sopenharmony_ci self.alias = alias 7902f4aeb0Sopenharmony_ci self.apiCommand = apiCommand 8002f4aeb0Sopenharmony_ci # This is the API-dependent command prefix 8102f4aeb0Sopenharmony_ci self.prefix = 'egl' 8202f4aeb0Sopenharmony_ci self.prefixLen = len(self.prefix) 8302f4aeb0Sopenharmony_ci def makeKey(self): 8402f4aeb0Sopenharmony_ci # Return dictionary / sort key based on the feature name 8502f4aeb0Sopenharmony_ci if (self.apiCommand and self.feature[0:self.prefixLen] 8602f4aeb0Sopenharmony_ci == self.prefix): 8702f4aeb0Sopenharmony_ci return self.feature[self.prefixLen:] 8802f4aeb0Sopenharmony_ci else: 8902f4aeb0Sopenharmony_ci return self.feature 9002f4aeb0Sopenharmony_ci 9102f4aeb0Sopenharmony_ci# Add dictionary entry for specified Feature. 9202f4aeb0Sopenharmony_ci# The key used is the feature name, with the leading 'gl' stripped 9302f4aeb0Sopenharmony_ci# off if this is an API command 9402f4aeb0Sopenharmony_cidef addkey(dict, feature): 9502f4aeb0Sopenharmony_ci key = feature.makeKey() 9602f4aeb0Sopenharmony_ci if (key in dict.keys()): 9702f4aeb0Sopenharmony_ci print('Key', key, ' already exists in dictionary!') 9802f4aeb0Sopenharmony_ci else: 9902f4aeb0Sopenharmony_ci dict[key] = feature 10002f4aeb0Sopenharmony_ci 10102f4aeb0Sopenharmony_ci# Create list of entry point names to be indexed. 10202f4aeb0Sopenharmony_ci# Unlike the old Perl script, this proceeds as follows: 10302f4aeb0Sopenharmony_ci# - Each .xhtml page with a parent .xml page gets an 10402f4aeb0Sopenharmony_ci# index entry for its base name. 10502f4aeb0Sopenharmony_ci# - Additionally, each <function> tag inside a <funcdef> 10602f4aeb0Sopenharmony_ci# in the parent page gets an aliased index entry. 10702f4aeb0Sopenharmony_ci# - Each .xhtml page *without* a parent is reported but 10802f4aeb0Sopenharmony_ci# not indexed. 10902f4aeb0Sopenharmony_ci# - Each collision in index terms is reported. 11002f4aeb0Sopenharmony_ci# - Index terms are keys in a dictionary whose entries 11102f4aeb0Sopenharmony_ci# are [ pagename, alias, glPrefix ] where pagename is 11202f4aeb0Sopenharmony_ci# the base name of the indexed page and alias is True 11302f4aeb0Sopenharmony_ci# if this index isn't the same as pagename. 11402f4aeb0Sopenharmony_ci# - API keys have their glPrefix value set to True, 11502f4aeb0Sopenharmony_ci# GLSL keys to False. There is a simplistic way of 11602f4aeb0Sopenharmony_ci# telling the files apart based on the file name: 11702f4aeb0Sopenharmony_ci# 11802f4aeb0Sopenharmony_ci# * Everything starting with 'egl[A-Z]' is API 11902f4aeb0Sopenharmony_ci# * 'removedTypes.*' is API (more may be added) 12002f4aeb0Sopenharmony_ci# * Everything else is GLSL 12102f4aeb0Sopenharmony_ci 12202f4aeb0Sopenharmony_cidef isAPIfile(entrypoint): 12302f4aeb0Sopenharmony_ci if (re.match('^egl[A-Z]', entrypoint) or entrypoint == 'removedTypes'): 12402f4aeb0Sopenharmony_ci return True 12502f4aeb0Sopenharmony_ci else: 12602f4aeb0Sopenharmony_ci return False 12702f4aeb0Sopenharmony_ci 12802f4aeb0Sopenharmony_ci# Dictionary of all keys mapped to Feature values 12902f4aeb0Sopenharmony_cirefIndex = {} 13002f4aeb0Sopenharmony_ci 13102f4aeb0Sopenharmony_cifor file in files: 13202f4aeb0Sopenharmony_ci # print('Processing file', file) 13302f4aeb0Sopenharmony_ci (entrypoint,ext) = os.path.splitext(file) 13402f4aeb0Sopenharmony_ci if (ext == genext): 13502f4aeb0Sopenharmony_ci parent = srcdir + '/' + entrypoint + srcext 13602f4aeb0Sopenharmony_ci # Determine if this is an API or GLSL page 13702f4aeb0Sopenharmony_ci apiCommand = isAPIfile(entrypoint) 13802f4aeb0Sopenharmony_ci if (os.path.exists(parent)): 13902f4aeb0Sopenharmony_ci addkey(refIndex, Feature(file, entrypoint, False, apiCommand)) 14002f4aeb0Sopenharmony_ci # Search parent file for <function> tags inside <funcdef> tags 14102f4aeb0Sopenharmony_ci # This doesn't search for <varname> inside <fieldsynopsis>, because 14202f4aeb0Sopenharmony_ci # those aren't on the same line and it's hard. 14302f4aeb0Sopenharmony_ci fp = open(parent) 14402f4aeb0Sopenharmony_ci for line in fp.readlines(): 14502f4aeb0Sopenharmony_ci # Look for <function> tag contents and add as aliases 14602f4aeb0Sopenharmony_ci # Don't add the same key twice 14702f4aeb0Sopenharmony_ci for m in re.finditer(r"<funcdef>.*<function>(.*)</function>.*</funcdef>", line): 14802f4aeb0Sopenharmony_ci funcname = m.group(1) 14902f4aeb0Sopenharmony_ci if (funcname != entrypoint): 15002f4aeb0Sopenharmony_ci addkey(refIndex, Feature(file, funcname, True, apiCommand)) 15102f4aeb0Sopenharmony_ci fp.close() 15202f4aeb0Sopenharmony_ci else: 15302f4aeb0Sopenharmony_ci print('No parent page for', file, ', will not be indexed') 15402f4aeb0Sopenharmony_ci 15502f4aeb0Sopenharmony_ci# Some utility functions for generating the navigation table 15602f4aeb0Sopenharmony_ci# Opencl_tofc.html uses style.css instead of style-index.css 15702f4aeb0Sopenharmony_ci# flatMenu - if True, don't include accordion JavaScript, 15802f4aeb0Sopenharmony_ci# generating a flat (expanded) menu. 15902f4aeb0Sopenharmony_ci# letters - if not None, include per-letter links to within 16002f4aeb0Sopenharmony_ci# the indices for each letter in the list. 16102f4aeb0Sopenharmony_ci# altMenu - if not None, the name of the alternate index to 16202f4aeb0Sopenharmony_ci# link to. 16302f4aeb0Sopenharmony_cidef printHeader(fp, flatMenu = False, letters = None, altMenu = None): 16402f4aeb0Sopenharmony_ci if (flatMenu): 16502f4aeb0Sopenharmony_ci scriptInclude = ' <!-- Don\'t include accord.js -->' 16602f4aeb0Sopenharmony_ci else: 16702f4aeb0Sopenharmony_ci scriptInclude = ' <?php include \'accord.js\'; ?>' 16802f4aeb0Sopenharmony_ci 16902f4aeb0Sopenharmony_ci print('<html>', 17002f4aeb0Sopenharmony_ci '<head>', 17102f4aeb0Sopenharmony_ci ' <link rel="stylesheet" type="text/css" href="style-index.css" />', 17202f4aeb0Sopenharmony_ci ' <title>' + pageTitle + '</title>', 17302f4aeb0Sopenharmony_ci scriptInclude, 17402f4aeb0Sopenharmony_ci '</head>', 17502f4aeb0Sopenharmony_ci '<body>', 17602f4aeb0Sopenharmony_ci sep='\n', file=fp) 17702f4aeb0Sopenharmony_ci 17802f4aeb0Sopenharmony_ci if (altMenu): 17902f4aeb0Sopenharmony_ci if (flatMenu): 18002f4aeb0Sopenharmony_ci altLabel = '(accordion-style)' 18102f4aeb0Sopenharmony_ci else: 18202f4aeb0Sopenharmony_ci altLabel = '(flat)' 18302f4aeb0Sopenharmony_ci print(' <a href="' + altMenu + '">' + 18402f4aeb0Sopenharmony_ci 'Use alternate ' + altLabel + ' index' + 18502f4aeb0Sopenharmony_ci '</a>', file=fp) 18602f4aeb0Sopenharmony_ci 18702f4aeb0Sopenharmony_ci if (letters): 18802f4aeb0Sopenharmony_ci print(' <center>\n<div id="container">', file=fp) 18902f4aeb0Sopenharmony_ci for letter in letters: 19002f4aeb0Sopenharmony_ci print(' <b><a href="#' + 19102f4aeb0Sopenharmony_ci letter + 19202f4aeb0Sopenharmony_ci '" style="text-decoration:none">' + 19302f4aeb0Sopenharmony_ci letter + 19402f4aeb0Sopenharmony_ci '</a></b> ', file=fp) 19502f4aeb0Sopenharmony_ci print(' </div>\n</center>', file=fp) 19602f4aeb0Sopenharmony_ci 19702f4aeb0Sopenharmony_ci print(' <div id="navwrap">', 19802f4aeb0Sopenharmony_ci ' <ul id="containerul"> <!-- Must wrap entire list for expand/contract -->', 19902f4aeb0Sopenharmony_ci ' <li class="Level1">', 20002f4aeb0Sopenharmony_ci ' <a href="start.html" target="pagedisplay">Introduction</a>', 20102f4aeb0Sopenharmony_ci ' </li>', 20202f4aeb0Sopenharmony_ci sep='\n', file=fp) 20302f4aeb0Sopenharmony_ci 20402f4aeb0Sopenharmony_cidef printFooter(fp, flatMenu = False): 20502f4aeb0Sopenharmony_ci print(' </div> <!-- End containerurl -->', file=fp) 20602f4aeb0Sopenharmony_ci if (not flatMenu): 20702f4aeb0Sopenharmony_ci print(' <script type="text/javascript">initiate();</script>', file=fp) 20802f4aeb0Sopenharmony_ci print('</body>', 20902f4aeb0Sopenharmony_ci '</html>', 21002f4aeb0Sopenharmony_ci sep='\n', file=fp) 21102f4aeb0Sopenharmony_ci 21202f4aeb0Sopenharmony_ci# Add a nav table entry. key = link name, feature = Feature info for key 21302f4aeb0Sopenharmony_cidef addMenuLink(key, feature, fp): 21402f4aeb0Sopenharmony_ci file = feature.file 21502f4aeb0Sopenharmony_ci linkname = feature.feature 21602f4aeb0Sopenharmony_ci 21702f4aeb0Sopenharmony_ci print(ind4 + '<li><a href="' + file + '" target="pagedisplay">' 21802f4aeb0Sopenharmony_ci + linkname + '</a></li>', 21902f4aeb0Sopenharmony_ci sep='\n', file=fp) 22002f4aeb0Sopenharmony_ci 22102f4aeb0Sopenharmony_ci# Begin index section for a letter, include an anchor to link to 22202f4aeb0Sopenharmony_cidef beginLetterSection(letter, fp): 22302f4aeb0Sopenharmony_ci print(ind2 + '<a name="' + letter + '"></a>', 22402f4aeb0Sopenharmony_ci ind2 + '<li>' + letter, 22502f4aeb0Sopenharmony_ci ind3 + '<ul class="Level3">', 22602f4aeb0Sopenharmony_ci sep='\n', file=fp) 22702f4aeb0Sopenharmony_ci 22802f4aeb0Sopenharmony_ci# End index section for a letter 22902f4aeb0Sopenharmony_cidef endLetterSection(opentable, fp): 23002f4aeb0Sopenharmony_ci if (opentable == 0): 23102f4aeb0Sopenharmony_ci return 23202f4aeb0Sopenharmony_ci print(ind3 + '</ul> <!-- End Level3 -->', 23302f4aeb0Sopenharmony_ci ind2 + '</li>', 23402f4aeb0Sopenharmony_ci sep='\n', file=fp) 23502f4aeb0Sopenharmony_ci 23602f4aeb0Sopenharmony_ci# Return the keys in a dictionary sorted by name. 23702f4aeb0Sopenharmony_ci# Select only keys matching whichKeys (see genDict below) 23802f4aeb0Sopenharmony_cidef sortedKeys(dict, whichKeys): 23902f4aeb0Sopenharmony_ci list = [] 24002f4aeb0Sopenharmony_ci for key in dict.keys(): 24102f4aeb0Sopenharmony_ci if (whichKeys == 'all' or 24202f4aeb0Sopenharmony_ci (whichKeys == 'api' and dict[key].apiCommand) or 24302f4aeb0Sopenharmony_ci (whichKeys == 'glsl' and not dict[key].apiCommand)): 24402f4aeb0Sopenharmony_ci list.append(key) 24502f4aeb0Sopenharmony_ci list.sort(key=str.lower) 24602f4aeb0Sopenharmony_ci return list 24702f4aeb0Sopenharmony_ci 24802f4aeb0Sopenharmony_ci# Generate accordion menu for this dictionary, titled as specified. 24902f4aeb0Sopenharmony_ci# 25002f4aeb0Sopenharmony_ci# If whichKeys is 'all', generate index for all features 25102f4aeb0Sopenharmony_ci# If whichKeys is 'api', generate index only for API features 25202f4aeb0Sopenharmony_ci# If whichKeys is 'glsl', generate index only for GLSL features 25302f4aeb0Sopenharmony_ci# 25402f4aeb0Sopenharmony_ci# fp is the file to write to 25502f4aeb0Sopenharmony_cidef genDict(dict, title, whichKeys, fp): 25602f4aeb0Sopenharmony_ci print(ind1 + '<li class="Level1">' + title, 25702f4aeb0Sopenharmony_ci ind2 + '<ul class="Level2">', 25802f4aeb0Sopenharmony_ci sep='\n', file=fp) 25902f4aeb0Sopenharmony_ci 26002f4aeb0Sopenharmony_ci # Print links for sorted keys in each letter section 26102f4aeb0Sopenharmony_ci curletter = '' 26202f4aeb0Sopenharmony_ci opentable = 0 26302f4aeb0Sopenharmony_ci 26402f4aeb0Sopenharmony_ci # Determine which letters are in the table of contents for this 26502f4aeb0Sopenharmony_ci # dictionary. If apiPrefix is set, strip the API prefix from each 26602f4aeb0Sopenharmony_ci # key containing it first. 26702f4aeb0Sopenharmony_ci 26802f4aeb0Sopenharmony_ci # Generatesorted list of page indexes. Select keys matching whichKeys. 26902f4aeb0Sopenharmony_ci keys = sortedKeys(dict, whichKeys) 27002f4aeb0Sopenharmony_ci 27102f4aeb0Sopenharmony_ci # print('@ Sorted list of page indexes:\n', keys) 27202f4aeb0Sopenharmony_ci 27302f4aeb0Sopenharmony_ci for key in keys: 27402f4aeb0Sopenharmony_ci # Character starting this key 27502f4aeb0Sopenharmony_ci c = str.lower(key[0]) 27602f4aeb0Sopenharmony_ci 27702f4aeb0Sopenharmony_ci if (c != curletter): 27802f4aeb0Sopenharmony_ci endLetterSection(opentable, fp) 27902f4aeb0Sopenharmony_ci # Start a new subtable for this letter 28002f4aeb0Sopenharmony_ci beginLetterSection(c, fp) 28102f4aeb0Sopenharmony_ci opentable = 1 28202f4aeb0Sopenharmony_ci curletter = c 28302f4aeb0Sopenharmony_ci addMenuLink(key, dict[key], fp) 28402f4aeb0Sopenharmony_ci endLetterSection(opentable, fp) 28502f4aeb0Sopenharmony_ci 28602f4aeb0Sopenharmony_ci print(ind2 + '</ul> <!-- End Level2 -->', 28702f4aeb0Sopenharmony_ci ind1 + '</li> <!-- End Level1 -->', 28802f4aeb0Sopenharmony_ci sep='\n', file=fp) 28902f4aeb0Sopenharmony_ci 29002f4aeb0Sopenharmony_ci###################################################################### 29102f4aeb0Sopenharmony_ci 29202f4aeb0Sopenharmony_ci# Generate the accordion menu 29302f4aeb0Sopenharmony_cifp = open(accordfilename, 'w') 29402f4aeb0Sopenharmony_ciprintHeader(fp, flatMenu = False, altMenu = flatfilename) 29502f4aeb0Sopenharmony_ci 29602f4aeb0Sopenharmony_cigenDict(refIndex, 'EGL Entry Points', 'all', fp) 29702f4aeb0Sopenharmony_ci 29802f4aeb0Sopenharmony_ciprintFooter(fp, flatMenu = False) 29902f4aeb0Sopenharmony_cifp.close() 30002f4aeb0Sopenharmony_ci 30102f4aeb0Sopenharmony_ci###################################################################### 30202f4aeb0Sopenharmony_ci 30302f4aeb0Sopenharmony_ci# Generate the non-accordion menu, with combined API and GLSL sections 30402f4aeb0Sopenharmony_cifp = open(flatfilename, 'w') 30502f4aeb0Sopenharmony_ci 30602f4aeb0Sopenharmony_ci# Set containing all index letters 30702f4aeb0Sopenharmony_ciindices = { key[0].lower() for key in refIndex.keys() } 30802f4aeb0Sopenharmony_ciletters = [c for c in indices] 30902f4aeb0Sopenharmony_ciletters.sort() 31002f4aeb0Sopenharmony_ci 31102f4aeb0Sopenharmony_ciprintHeader(fp, flatMenu = True, letters = letters, altMenu = accordfilename) 31202f4aeb0Sopenharmony_ci 31302f4aeb0Sopenharmony_cigenDict(refIndex, 'EGL Entry Points', 'all', fp) 31402f4aeb0Sopenharmony_ci 31502f4aeb0Sopenharmony_ciprintFooter(fp, flatMenu = True) 31602f4aeb0Sopenharmony_cifp.close() 317