1#!/usr/local/bin/python3.8 2# coding: utf-8 3# Dear future self, 4# 5# You're looking at this file because 6# the parse function finally broke. 7# 8# It's not fixable. You have to rewrite it. 9# Sincerely, past self 10# 11# Also, it's probably at least 12# 2013. Did you ever take 13# that trip to Iceland? 14 15import re 16 17def get_type_link(typ, file): 18 from gen_doc import objects 19 20 if typ == '': 21 return "void" 22 else: 23 if typ in objects: 24 return "cinnamon-js-" + objects[typ].prefix 25 elif file.name + "." + typ in objects: 26 return "cinnamon-js-" + objects[file.name + "." + typ].prefix 27 elif typ.endswith("s") and typ[:-1] in objects: 28 return "cinnamon-js-" + objects[typ[:-1]].prefix 29 elif typ.endswith("s") and file.name + "." + typ[:-1] in objects: 30 return "cinnamon-js-" + objects[file.name + "." + typ[:-1]].prefix 31 elif typ.startswith("Gio"): 32 return typ.replace("Gio.", "G") 33 elif typ.startswith("GLib"): 34 return typ.replace("GLib.", "G") 35 else: 36 return typ.replace('.', '') 37 38def markup(line, obj): 39 line = re.sub('@(\w*)', '<code>\g<1></code>', line) 40 line = re.sub('`([^`]*)`', '<code>\g<1></code>', line) 41 line = re.sub('\*\*([^*]*)\*\*', '<emphasis role="strong">\g<1></emphasis>', line) 42 line = re.sub('\*([^*]*)\*', '<emphasis>\g<1></emphasis>', line) 43 44 def format_type_link(match): 45 res = match.group(1) 46 return '<link linkend="{link}"><code>{name}</code></link>'.format( 47 link = get_type_link(res, obj.file), 48 name = res) 49 50 line = re.sub('#(([\w]*\.)?[\w]+)', format_type_link, line) 51 52 def format_ext_link(match): 53 if match.group(1): 54 full = match.group(1) + match.group(3) 55 else: 56 full = match.group(3) 57 58 if match.group(4): 59 full += match.group(4) 60 61 owner = match.group(1) 62 if owner: 63 owner = owner[:-1] # remove trailing . 64 else: 65 owner = "this" 66 67 thing = match.group(3) 68 69 from gen_doc import objects 70 71 object = None 72 if owner == "this": 73 object = obj.object 74 if owner in objects: 75 object = objects[owner] 76 elif obj.file.name + "." + owner in objects: 77 object = objects[obj.file.name + "." + owner] 78 79 if object is None: 80 return '<code>{name}</code>'.format(name = full) 81 82 func_names = [x.name for x in object.functions] 83 enum_names = [x.name for x in object.enums] 84 prop_names = [x.name for x in object.properties] 85 86 if thing in prop_names and not full.endswith("()"): 87 return '<link linkend="cinnamon-js-{prefix}--{thing}"><code>{full}</code></link>'.format( 88 prefix = object.prefix, 89 thing = thing, 90 full = full) 91 elif thing in func_names or (thing in enum_names and not full.endswith("()")): 92 return '<link linkend="cinnamon-js-{prefix}-{thing}"><code>{full}</code></link>'.format( 93 prefix = object.prefix, 94 thing = thing, 95 full = full) 96 else: 97 return '<code>{name}</code>'.format(name = full) 98 99 line = re.sub('%(([\w]+\.)?[\w]+\.)?([\w]+)(\(\))?', format_ext_link, line) 100 101 return line 102 103class JSThing(): 104 def append_description(self, desc): 105 self.description += desc.replace('<', '<').replace('>', '>') 106 107 def get_xml_description(self, description = None): 108 if description is None: 109 description = self.description 110 111 stuff = description.split('\n') 112 joined = [''] 113 114 in_code = False 115 in_list = False 116 117 for line in stuff: 118 if line.strip() == '```': 119 if in_code: 120 joined[-1] += '```' 121 joined.append('') 122 else: 123 if in_list: 124 joined[-1] += '\n```' 125 else: 126 joined.append('```\n') 127 in_code = not in_code 128 continue 129 130 if in_code: 131 joined[-1] += '\n' + line 132 continue 133 134 line = line.strip() 135 if line == '\\' and in_list: 136 joined[-1] += '\n\n' 137 elif len(line) == 0 or line == '\\': 138 # New line if empty 139 joined.append('') 140 in_list = False 141 else: 142 if joined[-1] == '' and line.startswith('- '): 143 in_list = True 144 if line.startswith('- '): 145 joined.append('') 146 147 joined[-1] += ' ' + line 148 149 description = '' 150 in_list = False 151 152 list_buffer = [] 153 for line in joined: 154 if line.split('\n')[0].strip() == '```': 155 description += '<informalexample><programlisting>{0}</programlisting></informalexample>'\ 156 .format(line.replace('```', '')) 157 continue 158 159 if line == '': 160 continue 161 162 line = line.strip() 163 if line.startswith('-'): 164 in_list = True 165 list_buffer.append(self.get_xml_description(line[1:])) 166 continue 167 168 if in_list: 169 description += '<itemizedlist>' + \ 170 '\n'.join('<listitem>{0}</listitem>'.format(item) for item in list_buffer) + \ 171 '</itemizedlist>' 172 list_buffer = [] 173 in_list = False 174 175 line = markup(line, self) 176 description += '<para>{0}</para>'.format(line) 177 178 if in_list: 179 description += '<itemizedlist>' + \ 180 '\n'.join('<listitem>{0}</listitem>'.format(item) for item in list_buffer) + \ 181 '</itemizedlist>' 182 list_buffer = [] 183 184 return description 185 186 def add_property(self, prop): 187 if prop.name == "short_description": 188 self.short_description = prop 189 else: 190 self.properties.append(prop) 191 prop.file = self.file 192 prop.object = self.object 193 194class JSSignal(JSThing): 195 def __init__ (self, name): 196 self.name = name 197 self.description = '' 198 self.short_description = JSProperty(None, '', '') 199 self.properties = [] 200 201class JSFunction(JSThing): 202 def __init__ (self, name): 203 self.name = name 204 self.description = '' 205 self.short_description = JSProperty(None, '', '') 206 self.properties = [] 207 self.return_value = JSProperty(None, '', '') 208 209 def set_return(self, retval): 210 self.return_value = retval 211 retval.file = self.file 212 retval.obj = self.object 213 214class JSProperty(JSThing): 215 def __init__ (self, name, arg_type, desc): 216 self.name = name 217 self.arg_type = arg_type if arg_type else '' 218 self.description = '' 219 self.append_description(desc + "\n") 220 221class JSFile(JSThing): 222 def __init__ (self, directory, name): 223 self.directory = directory 224 self.name = name[0].capitalize() + name[1:] 225 self.orig_name = self.name 226 self.imports = "imports.{0}.{1}".format(directory, name) 227 self.prefix = directory + "-" + name 228 self.description = '' 229 self.short_description = JSProperty(None, '', '') 230 self.properties = [] 231 self.objects = [] 232 self.signals = [] 233 self.enums = [] 234 self.functions = [] 235 self.file = self 236 self.object = self 237 238 def is_interesting(self): 239 return len(self.functions) + len(self.properties) + len(self.description) > 0 240 241 def add_function(self, func): 242 self.functions.append(func) 243 func.file = self 244 func.object = self 245 246 def add_object(self, obj): 247 self.objects.append(obj) 248 obj.parent = self 249 obj.directory = self.directory 250 obj.prefix = self.prefix + "-" + obj.name 251 obj.name = self.name + "-" + obj.name 252 obj.file = self 253 254 def add_enum(self, obj): 255 self.enums.append(obj) 256 obj.parent = self 257 obj.directory = self.directory 258 obj.prefix = self.prefix + "-" + obj.name 259 obj.file = self 260 261class JSObject(JSThing): 262 def __init__ (self, name): 263 self.name = name 264 self.orig_name = name 265 self.inherit = '' 266 self.description = '' 267 self.short_description = JSProperty(None, '', '') 268 self.parent = None 269 self.directory = None 270 self.prefix = None 271 self.functions = [] 272 self.properties = [] 273 self.signals = [] 274 self.enums = [] 275 self.object = self 276 277 def add_function(self, func): 278 self.functions.append(func) 279 func.file = self.file 280 func.object = self 281 282 def add_signal(self, signal): 283 self.signals.append(signal) 284 signal.file = self 285 signal.object = self 286 287 def set_inherit(self, inherit): 288 self.inherit = inherit 289 290class JSEnum(JSThing): 291 def __init__ (self, name): 292 self.name = name 293 self.description = '' 294 self.short_description = JSProperty(None, '', '') 295 self.properties = [] 296 self.object = self 297 298PART_FORMAT = '''\ 299<?xml version='1.0'?> 300<!DOCTYPE book PUBLIC '-//OASIS//DTD DocBook XML V4.3//EN' 301 'http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd' 302[ 303 <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'"> 304]> 305<part label="imports.{title}"> 306 {chapters} 307</part>''' 308 309SGML_CHAPTER_FORMAT = ''' 310<chapter id="cinnamon-js-{prefix}-section"> 311 <title>{title}</title> 312 {entries} 313</chapter>''' 314 315SGML_ENTRY_FORMAT = '<xi:include href="{directory}/{name}.xml"/>' 316 317FILE_FORMAT = '''\ 318<!DOCTYPE refentry PUBLIC '-//OASIS//DTD DocBook XML V4.3//EN' 319'http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd' 320[ 321<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'"> 322]> 323<refentry id="cinnamon-js-{prefix}"> 324 <refmeta> 325 <refentrytitle role="top_of_page" id="cinnamon-js-{prefix}.top_of_page">{name}</refentrytitle> 326 <manvolnum>3</manvolnum> 327 <refmiscinfo> 328 {name} 329 </refmiscinfo> 330 </refmeta> 331 <refnamediv> 332 <refname>{name}</refname> 333 <refpurpose>{short_description}</refpurpose> 334 </refnamediv> 335 {func_header} 336 {prop_header} 337 {signal_header} 338 {enum_header} 339 {hierarchy} 340 {description} 341 {functions} 342 {properties} 343 {signals} 344 {enums} 345</refentry> 346''' 347 348FUNCTION_HEADER_FORMAT = ''' 349<refsect1 id="cinnamon-js-{prefix}.functions" role="functions_proto"> 350 <title role="functions_proto.title">Functions</title> 351 <informaltable pgwide="1" frame="none"> 352 <tgroup cols="2"> 353 <colspec colname="functions_return" colwidth="150px"/> 354 <colspec colname="functions_name"/> 355 <tbody> 356 {function_headers} 357 </tbody> 358 </tgroup> 359 </informaltable> 360</refsect1> 361''' 362 363FUNCTION_HEADER_ITEM_FORMAT = ''' 364<row> 365 <entry role="function_type"> 366 <link linkend="{return_link}"> 367 <returnvalue>{return_name}</returnvalue> 368 </link> 369 </entry> 370 <entry role="function_name"> 371 <link linkend="cinnamon-js-{prefix}-{name}">{name}</link> <phrase role="c_punctuation">()</phrase> 372 </entry> 373</row> 374''' 375 376PROPERTY_HEADER_FORMAT = ''' 377<refsect1 id="cinnamon-js-{prefix}.properties" role="properties"> 378 <title role="properties.title">Properties</title> 379 <informaltable frame="none"> 380 <tgroup cols="3"> 381 <colspec colname="properties_type" colwidth="150px"/> 382 <colspec colname="properties_name" colwidth="300px"/> 383 <tbody> 384 {property_headers} 385 </tbody> 386 </tgroup> 387 </informaltable> 388</refsect1> 389''' 390 391SIGNAL_HEADER_FORMAT = ''' 392<refsect1 id="cinnamon-js-{prefix}.signals" role="signal_proto"> 393 <title role="signal_proto.title">Signals</title> 394 <informaltable frame="none"> 395 <tgroup cols="3"> 396 <colspec colname="signals_return" colwidth="150px" /> 397 <colspec colname="signals_name" colwidth="300px" /> 398 <tbody> 399 {signal_headers} 400 </tbody> 401 </tgroup> 402 </informaltable> 403</refsect1> 404''' 405 406SIGNAL_HEADER_ITEM_FORMAT = ''' 407<row> 408 <entry role="signal_type"> 409 </entry> 410 <entry role="signal_name"> 411 <link linkend="cinnamon-js-{prefix}-{name}-signal">{name}</link> 412 </entry> 413</row> 414''' 415 416ENUM_HEADER_FORMAT = ''' 417<refsect1 id="cinnamon-js-{prefix}.other" role="other_proto"> 418 <title role="other_proto.title">Types and Values</title> 419 <informaltable role="enum_members_table" pgwide="1" frame="none"> 420 <tgroup cols="2"> 421 <colspec colname="name" colwidth="150px"/> 422 <colspec colname="description"/> 423 <tbody> 424 {enum_headers} 425 </tbody> 426 </tgroup> 427 </informaltable> 428</refsect1> 429''' 430 431ENUM_HEADER_ITEM_FORMAT = ''' 432<row> 433 <entry role="datatype_keyword">enum</entry> 434 <entry role="function_name"> 435 <link linkend="cinnamon-js-{prefix}-{name}">{name}</link> 436 </entry> 437</row> 438''' 439 440PROPERTY_HEADER_ITEM_FORMAT = ''' 441<row> 442 <entry role="property_type"> 443 <link linkend="{type_link}"><type>{type_name}</type></link> 444 </entry> 445 <entry role="property_name"> 446 <link linkend="cinnamon-js-{prefix}--{name}">{name}</link> 447 </entry> 448</row> 449''' 450 451HIERARCHY_FORMAT = ''' 452<refsect1 id="cinnamon-js-{prefix}.object-hierarchy" role="object_hierarchy"> 453 <title role="object_hierarchy.title">Object Hierarchy</title> 454 <screen> 455 <link linkend="Object">Object</link> 456{hierarchy} 457 </screen> 458</refsect1> 459''' 460 461HIERARCHY_ITEM_FORMAT = '{spacing}<phrase role="lineart">╰──</phrase> <link linkend="cinnamon-js-{prefix}">{name}</link>' 462 463DESCRIPTION_FORMAT = ''' 464<refsect1 id="cinnamon-js-{prefix}.description" role="desc"> 465 <title role="desc.title">Description</title> 466 {description} 467</refsect1> 468''' 469 470FUNCTIONS_FORMAT = ''' 471<refsect1 id="cinnamon-js-{prefix}.functions_details" role="details"> 472 <title role="details.title">Functions</title> 473 {functions} 474</refsect1> 475''' 476 477FUNCTION_ITEM_FORMAT = ''' 478<refsect2 id="cinnamon-js-{prefix}-{name}" role="function"> 479 <title>{name} ()</title> 480 <indexterm zone="cinnamon-js-{prefix}-{name}"><primary>{name}</primary></indexterm> 481 <programlisting language="javascript"> 482<link linkend="{return_link}"><returnvalue>{return_type}</returnvalue></link> 483{name} ({inline_params});</programlisting> 484 {description} 485 {params} 486 {return_desc} 487</refsect2> 488''' 489 490SIGNALS_FORMAT = ''' 491<refsect1 id="cinnamon-js-{prefix}.signal-details" role="details"> 492 <title role="details.title">Signal details</title> 493 {signals} 494</refsect1> 495''' 496 497SIGNAL_ITEM_FORMAT = ''' 498<refsect2 id="cinnamon-js-{prefix}-{name}-signal" role="signal"> 499 <title>The <literal>“{name}”</literal> signal</title> 500 <indexterm zone="cinnamon-js-{prefix}-{name}-signal"><primary>{prefix}::{name}</primary></indexterm> 501 <programlisting language="javascript"> 502user_function ({inline_params});</programlisting> 503 {description} 504 {params} 505</refsect2> 506''' 507 508FUNC_PARAMETERS_FORMAT = ''' 509<refsect3 role="parameters"> 510 <title>Parameters</title> 511 <informaltable role="parameters_table" pgwide="1" frame="none"> 512 <tgroup cols="3"> 513 <colspec colname="parameters_name" colwidth="150px"/> 514 <colspec colname="parameters_description"/> 515 <colspec colname="parameters_annotations" colwidth="200px"/> 516 <tbody> 517 {param_items} 518 </tbody> 519 </tgroup> 520 </informaltable> 521</refsect3> 522''' 523 524INLINE_PARAMETER_FORMAT = '<parameter><link linkend="{type_link}"><type>{type_name}</type></link>{name}</parameter>' 525 526FUNC_PARAMETERS_ITEM_FORMAT = ''' 527<row> 528 <entry role="parameter_name"><para>{name}</para></entry> 529 <entry role="parameter_description">{description}</entry> 530 <entry role="parameter_annotations"></entry> 531</row> 532''' 533 534FUNC_RETURN_FORMAT = ''' 535<refsect3 role="returns"> 536 <title>Returns</title> 537 {desc} 538</refsect3> 539''' 540 541PROPERTIES_FORMAT = ''' 542<refsect1 id="cinnamon-js-{prefix}.property-details" role="property_details"> 543 <title role="property_details.title">Property Details</title> 544 {properties} 545</refsect1> 546''' 547 548PROPERTIES_ITEM_FORMAT = ''' 549<refsect2 id="cinnamon-js-{prefix}--{name}" role="property"> 550 <title>The <literal>“{name}”</literal> property</title> 551 <indexterm zone="cinnamon-js-{prefix}--{name}"> 552 <primary>cinnamon-js-{prefix}:{name}</primary> 553 </indexterm> 554 <programlisting> {disp_name} <link linkend="{type_link}"><type>{type_name}</type></link></programlisting> 555 {description} 556</refsect2> 557''' 558 559ENUMS_FORMAT = ''' 560<refsect1 id="CinnamonGlobal.other_details" role="details"> 561 <title role="details.title">Types and Values</title> 562 {enums} 563</refsect1> 564''' 565 566ENUMS_ITEM_FORMAT = ''' 567<refsect2 id="cinnamon-js-{prefix}" role="enum"> 568 <title>enum {name}</title> 569 <indexterm zone="{name}"><primary>{name}</primary></indexterm> 570 {description} 571 <refsect3 role="enum_members"> 572 <title>Members</title> 573 <informaltable role="enum_members_table" pgwide="1" frame="none"> 574 <tgroup cols="2"> 575 <colspec colname="enum_members_name" colwidth="300px"/> 576 <colspec colname="enum_members_description"/> 577 <tbody> 578 {enum_items} 579 </tbody> 580 </tgroup> 581 </informaltable> 582 </refsect3> 583</refsect2> 584''' 585 586ENUMS_ITEM_ROW_FORMAT = ''' 587<row role="constant"> 588 <entry role="enum_member_name"><para id="{name}:CAPS">{name}</para></entry> 589 <entry role="enum_member_description">{description}</entry> 590</row> 591''' 592 593def write_chapters_file(files): 594 chapters = {'ui': [], 'misc': []} 595 596 for _file in files: 597 if not _file.is_interesting() and len(_file.objects) == 0: 598 continue 599 600 entries = [] 601 if _file.is_interesting(): 602 _file.objects.insert(0, _file) 603 604 entries = [SGML_ENTRY_FORMAT.format( 605 directory = _file.directory, 606 name = obj.name) for obj in _file.objects] 607 608 chapters[_file.directory].append(SGML_CHAPTER_FORMAT.format( 609 prefix = _file.prefix, 610 title = _file.imports, 611 entries = "\n".join(entries))) 612 613 for directory, formatted_chapters in chapters.items(): 614 with open(directory + '.xml', 'w') as part_file: 615 part_file.write(PART_FORMAT.format(title=directory, chapters="\n".join(formatted_chapters))) 616 617def create_file(obj): 618 file_obj = open('{0}/{1}.xml'.format(obj.directory, obj.name), 'w', encoding="utf-8") 619 short_description = obj.short_description.description.replace("\n", " ").strip() 620 file_obj.write(FILE_FORMAT.format( 621 prefix = obj.prefix, 622 name = obj.name.replace("-", "."), 623 short_description = markup(short_description, obj), 624 func_header = get_function_header(obj), 625 signal_header = get_signal_header(obj), 626 prop_header = get_properties_header(obj), 627 enum_header = get_enum_header(obj), 628 hierarchy = get_hierarchy(obj), 629 description = get_description(obj), 630 functions = get_functions(obj), 631 signals = get_signals(obj), 632 properties = get_properties(obj), 633 enums = get_enums(obj))) 634 635 file_obj.close() 636 637def get_function_header(obj): 638 if len(obj.functions) == 0: 639 return "" 640 641 functions = [FUNCTION_HEADER_ITEM_FORMAT.format( 642 return_link = get_type_link(func.return_value.arg_type, obj.file), 643 return_name = func.return_value.arg_type, 644 prefix = obj.prefix, 645 name = func.name) for func in obj.functions] 646 647 return FUNCTION_HEADER_FORMAT.format( 648 prefix = obj.prefix, 649 function_headers = "\n".join(functions)) 650 651def get_signal_header(obj): 652 if len(obj.signals) == 0: 653 return "" 654 655 signals = [SIGNAL_HEADER_ITEM_FORMAT.format( 656 prefix = obj.prefix, 657 name = sig.name) for sig in obj.signals] 658 659 return SIGNAL_HEADER_FORMAT.format( 660 prefix = obj.prefix, 661 signal_headers = "\n".join(signals)) 662 663def get_properties_header(obj): 664 if len(obj.properties) == 0: 665 return "" 666 667 properties = [PROPERTY_HEADER_ITEM_FORMAT.format( 668 type_link = get_type_link(prop.arg_type, obj.file), 669 type_name = prop.arg_type, 670 prefix = obj.prefix, 671 name = prop.name) for prop in obj.properties] 672 673 return PROPERTY_HEADER_FORMAT.format( 674 prefix = obj.prefix, 675 property_headers = "\n".join(properties)) 676 677def get_enum_header(obj): 678 if len(obj.enums) == 0: 679 return "" 680 681 enums = [ENUM_HEADER_ITEM_FORMAT.format( 682 prefix = obj.prefix, 683 name = enum.name) for enum in obj.enums] 684 685 return ENUM_HEADER_FORMAT.format( 686 prefix = obj.prefix, 687 enum_headers = "\n".join(enums)) 688 689 690def get_hierarchy(obj): 691 from gen_doc import objects 692 693 if isinstance(obj, JSFile): 694 return "" 695 696 697 name = obj.name.replace('-', '.') 698 hierarchy = [] 699 try: 700 while True: 701 name = objects[name].inherit 702 if name in hierarchy: 703 break 704 if name: 705 hierarchy.insert(0, name) 706 except KeyError: 707 pass 708 709 count = 1 710 hierarchy_strs = [] 711 for item in hierarchy: 712 try: 713 hierarchy_strs.append(HIERARCHY_ITEM_FORMAT.format( 714 spacing = ' ' * count * 4, 715 prefix = objects[item].prefix, 716 name = item)) 717 except KeyError: 718 hierarchy_strs.append(HIERARCHY_ITEM_FORMAT.format( 719 spacing = ' ' * count * 4, 720 prefix = "void", 721 name = item)) 722 count += 1 723 724 hierarchy_strs.append(HIERARCHY_ITEM_FORMAT.format( 725 spacing = ' ' * count * 4, 726 prefix = "void", 727 name = obj.name.replace('-', '.'))) 728 729 return HIERARCHY_FORMAT.format( 730 prefix = obj.prefix, 731 hierarchy = "\n".join(hierarchy_strs)) 732 733def get_description(obj): 734 if len(obj.description) == 0: 735 return "" 736 737 return DESCRIPTION_FORMAT.format( 738 prefix=obj.prefix, 739 description = obj.get_xml_description()) 740 741def get_functions(obj): 742 if len(obj.functions) == 0: 743 return "" 744 745 functions = [] 746 747 for func in obj.functions: 748 inline_params = "" 749 params = "" 750 if len(func.properties) > 0: 751 # Calculate how long the argument types are and make the arguments 752 # align 753 max_length = max(len(x.arg_type) for x in func.properties) + 3 754 # If no parameter has argument types, don't show that silly 755 # whitespace 756 if max_length == 3: 757 max_length = 0 758 759 inline_params = [INLINE_PARAMETER_FORMAT.format( 760 type_link = get_type_link(param.arg_type, obj.file), 761 type_name = param.arg_type, 762 name = " " * (max_length - len(param.arg_type)) + param.name) for param in func.properties] 763 764 inline_params = (',\n' + ' ' * (len(func.name) + 2)).join(inline_params) 765 766 params = [FUNC_PARAMETERS_ITEM_FORMAT.format( 767 name = param.name, 768 description = param.get_xml_description()) for param in func.properties] 769 770 params = FUNC_PARAMETERS_FORMAT.format(param_items = '\n'.join(params)) 771 772 return_desc = "" 773 if func.return_value.name is not None: 774 return_desc = FUNC_RETURN_FORMAT.format(desc=func.return_value.get_xml_description()) 775 776 functions.append(FUNCTION_ITEM_FORMAT.format( 777 prefix = obj.prefix, 778 name = func.name, 779 return_link = get_type_link(func.return_value.arg_type, obj.file), 780 return_type = func.return_value.arg_type, 781 description = func.get_xml_description(), 782 inline_params = inline_params, 783 params = params, 784 return_desc = return_desc)) 785 786 return FUNCTIONS_FORMAT.format( 787 prefix = obj.prefix, 788 functions = "\n".join(functions)) 789 790def get_signals(obj): 791 if len(obj.signals) == 0: 792 return "" 793 794 signals = [] 795 796 for sig in obj.signals: 797 inline_params = "" 798 params = "" 799 if len(sig.properties) > 0: 800 # Calculate how long the argument types are and make the arguments 801 # align 802 max_length = max(len(x.arg_type) for x in sig.properties) + 3 803 # If no parameter has argument types, don't show that silly 804 # whitespace 805 if max_length == 3: 806 max_length = 0 807 808 inline_params = [INLINE_PARAMETER_FORMAT.format( 809 type_link = get_type_link(param.arg_type, obj.file), 810 type_name = param.arg_type, 811 name = " " * (max_length - len(param.arg_type)) + param.name) for param in sig.properties] 812 813 inline_params = (',\n' + ' ' * (len(sig.name) + 2)).join(inline_params) 814 815 params = [FUNC_PARAMETERS_ITEM_FORMAT.format( 816 name = param.name, 817 description = param.get_xml_description()) for param in sig.properties] 818 819 params = FUNC_PARAMETERS_FORMAT.format(param_items = '\n'.join(params)) 820 821 signals.append(SIGNAL_ITEM_FORMAT.format( 822 prefix = obj.prefix, 823 name = sig.name, 824 description = sig.get_xml_description(), 825 inline_params = inline_params, 826 params = params)) 827 828 return SIGNALS_FORMAT.format( 829 prefix = obj.prefix, 830 signals = "\n".join(signals)) 831 832 833def get_properties(obj): 834 if len(obj.properties) == 0: 835 return "" 836 837 properties = [PROPERTIES_ITEM_FORMAT.format( 838 prefix = obj.prefix, 839 name = prop.name, 840 disp_name = ('“' + prop.name + '”').ljust(25), 841 type_link = get_type_link(prop.arg_type, obj.file), 842 type_name = prop.arg_type, 843 description = prop.get_xml_description()) for prop in obj.properties] 844 845 return PROPERTIES_FORMAT.format( 846 prefix = obj.prefix, 847 properties = "\n".join(properties)) 848 849def get_enums(obj): 850 if len(obj.enums) == 0: 851 return "" 852 853 enums = [] 854 855 for enum in obj.enums: 856 items = [ENUMS_ITEM_ROW_FORMAT.format( 857 name = item.name, 858 description = item.get_xml_description()) for item in enum.properties] 859 860 enums.append(ENUMS_ITEM_FORMAT.format( 861 prefix = enum.prefix, 862 name = enum.name, 863 description = enum.get_xml_description(), 864 enum_items = "\n".join(items))) 865 866 return ENUMS_FORMAT.format( 867 prefix = obj.prefix, 868 enums = "\n".join(enums)) 869