def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item( '', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) if not prop.implemented: para = nodes.inline('', _('Not implemented.')) warning = nodes.note('', para) definition.append(warning) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if prop.update_allowed: para = nodes.paragraph('', _('Can be updated without replacement.')) definition.append(para) else: para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(para) if prop.required: para = nodes.paragraph('', _('Required property.')) elif prop.default is not None: para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.default) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.MAP: para = nodes.emphasis('', _('Map properties:')) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.LIST: para = nodes.emphasis( '', _('List contents:')) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key in sorted(sub_schema.keys()): sub_prop = sub_schema[sub_prop_key] self.contribute_property(sub_prop_list, sub_prop_key, sub_prop)
def _definition_item(self, term, classifier): item = nodes.definition_list_item() term = nodes.term(text=term) item.append(term) classifier = nodes.classifier(text=classifier) item.append(classifier) return item
def transform_content(self, content_node): """ Appends autofill values to the type information of each key. """ super().transform_content(content_node) fixeddict_type = getattr(vc2_fixeddicts, self.names[0][0], None) autofill_values = vc2_default_values_with_auto.get(fixeddict_type, {}) keys_list = content_node.next_node(lambda node: (isinstance( node, nodes.field_name) and node.astext() == "Keys")).parent for entry_node in keys_list.traverse( make_type_matcher(nodes.definition_list_item)): key = entry_node.next_node(make_type_matcher(nodes.term)).astext() if key in autofill_values: autofill_value = autofill_values[key] autofill_message = nodes.Text( "(autofilled with {!r})".format(autofill_value)) classifier_node = entry_node.next_node( make_type_matcher(nodes.classifier)) if classifier_node is None: classifier_node = nodes.classifier() classifier_node += autofill_message entry_node.insert(1, classifier_node) else: classifier_node += nodes.Text(" ") classifier_node += autofill_message
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item('', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) if not prop.implemented: para = nodes.inline('', _('Not implemented.')) warning = nodes.note('', para) definition.append(warning) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if prop.update_allowed: para = nodes.paragraph('', _('Can be updated without replacement.')) definition.append(para) else: para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(para) if prop.required: para = nodes.paragraph('', _('Required property.')) elif prop.default is not None: para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.default) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.MAP: para = nodes.emphasis('', _('Map properties:')) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.LIST: para = nodes.emphasis('', _('List contents:')) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key in sorted(sub_schema.keys()): sub_prop = sub_schema[sub_prop_key] self.contribute_property(sub_prop_list, sub_prop_key, sub_prop)
def make_definition_list(self, term, definition=None, classifier=None): definition_list = nodes.definition_list_item() if not isinstance(term, nodes.Node): term = nodes.strong(text=term) definition_list.append(term) if classifier is not None: definition_list.append(nodes.classifier(text=classifier)) if definition is not None: if isinstance(definition, (list, tuple)): definition_list.append(nodes.definition('', *definition)) else: definition_list.append(nodes.definition('', definition)) return definition_list
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item( '', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) if prop.support_status.status != support.SUPPORTED: sstatus = prop.support_status.to_dict() msg = _('%(status)s') if sstatus['message'] is not None: msg = _('%(status)s - %(message)s') para = nodes.inline('', msg % sstatus) warning = nodes.note('', para) definition.append(warning) if not prop.implemented: para = nodes.inline('', _('Not implemented.')) warning = nodes.note('', para) definition.append(warning) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if prop.update_allowed: para = nodes.paragraph('', _('Can be updated without replacement.')) definition.append(para) else: para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(para) if prop.required: para = nodes.paragraph('', _('Required property.')) elif prop.default is not None: para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.default) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.Schema.MAP: para = nodes.paragraph() emph = nodes.emphasis('', _('Map properties:')) para.append(emph) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.Schema.LIST: para = nodes.paragraph() emph = nodes.emphasis('', _('List contents:')) para.append(emph) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key, sub_prop in sorted(sub_schema.items(), self.cmp_prop): self.contribute_property( sub_prop_list, sub_prop_key, sub_prop)
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item( '', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) if prop.support_status.status != support.SUPPORTED: sstatus = prop.support_status.to_dict() msg = _('%(status)s') if sstatus['message'] is not None: msg = _('%(status)s - %(message)s') para = nodes.inline('', msg % sstatus) warning = nodes.note('', para) definition.append(warning) if not prop.implemented: para = nodes.inline('', _('Not implemented.')) warning = nodes.note('', para) definition.append(warning) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if prop.update_allowed: para = nodes.paragraph('', _('Can be updated without replacement.')) definition.append(para) else: para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(para) if prop.required: para = nodes.paragraph('', _('Required property.')) elif prop.default is not None: para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.default) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.Schema.MAP: para = nodes.emphasis('', _('Map properties:')) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.Schema.LIST: para = nodes.emphasis( '', _('List contents:')) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key, sub_prop in sorted(sub_schema.items(), self.cmp_prop): self.contribute_property( sub_prop_list, sub_prop_key, sub_prop)
def _document_member(self, name, member): def _add_member_note(definition, member, qualifiers, format_text): if not type(qualifiers) == list: qualifiers = [qualifiers] format_param = { qualifier: getattr(member, qualifier) for qualifier in qualifiers if hasattr(member, qualifier) and getattr(member, qualifier) and type(getattr(member, qualifier)) != types.FunctionType } if len(qualifiers) == len(format_param): definition += _note(text=format_text.format(**format_param)) def _add_member_note_if(definition, member, qualifier, text): if getattr(member, qualifier, False): definition += _note(text=text) node = nodes.definition_list_item() node += nodes.term(text=name) definition = nodes.definition() if member.help_text and len(member.help_text): definition += rst2node(member.help_text) if isinstance(member, StringField): node += nodes.classifier(text="String") elif isinstance(member, EmbeddedDocumentField): node += nodes.classifier(text="JSON object") doctype = member.document_type.__name__ definition += rst2node("This member is an object of type " "`{}`".format(doctype)) # definition += nodes.paragraph(self._document_class(member.document_type) elif isinstance(member, ReferenceField): node += nodes.classifier(text="String containing a " "MongoDB ObjectID") elif isinstance(member, DateTimeField): node += nodes.classifier(text="String containing a Date/Time") _add_member_note( definition, member, 'min_length', "The minimum length for this " "member is {min_length} characters.") _add_member_note( definition, member, 'max_length', "The maximum length for this " "member is {max_length} characters.") _add_member_note(definition, member, 'choices', "Valid values for this member are {choices}.") _add_member_note( definition, member, 'default', "The default value for this " "member is {default!r}.") _add_member_note_if( definition, member, 'required', "This member is required for the creation " "of a new object.") _add_member_note_if( definition, member, 'unique', "Values for this member must be unique to all " "objects.") node += definition return node
def _document_member(self, name, member): def _add_member_note(definition, member, qualifiers, format_text): if not type(qualifiers) == list: qualifiers = [qualifiers] format_param = {qualifier: getattr(member, qualifier) for qualifier in qualifiers if hasattr(member, qualifier) and getattr(member, qualifier) and type(getattr(member, qualifier)) != types.FunctionType} if len(qualifiers) == len(format_param): definition += _note(text=format_text.format(**format_param)) def _add_member_note_if(definition, member, qualifier, text): if getattr(member, qualifier, False): definition += _note(text=text) node = nodes.definition_list_item() node += nodes.term(text=name) definition = nodes.definition() if member.help_text and len(member.help_text): definition += rst2node(member.help_text) if isinstance(member, StringField): node += nodes.classifier(text="String") elif isinstance(member, EmbeddedDocumentField): node += nodes.classifier(text="JSON object") doctype = member.document_type.__name__ definition += rst2node("This member is an object of type " "`{}`".format(doctype)) # definition += nodes.paragraph(self._document_class(member.document_type) elif isinstance(member, ReferenceField): node += nodes.classifier(text="String containing a " "MongoDB ObjectID") elif isinstance(member, DateTimeField): node += nodes.classifier(text="String containing a Date/Time") _add_member_note(definition, member, 'min_length', "The minimum length for this " "member is {min_length} characters.") _add_member_note(definition, member, 'max_length', "The maximum length for this " "member is {max_length} characters.") _add_member_note(definition, member, 'choices', "Valid values for this member are {choices}.") _add_member_note(definition, member, 'default', "The default value for this " "member is {default!r}.") _add_member_note_if(definition, member, 'required', "This member is required for the creation " "of a new object.") _add_member_note_if(definition, member, 'unique', "Values for this member must be unique to all " "objects.") node += definition return node
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item('', nodes.term('', prop_key)) prop_list.append(prop_item) prop_type = prop.get('Type') classifier = prop_type if prop.get('MinValue'): classifier += _(' from %s') % prop.get('MinValue') if prop.get('MaxValue'): classifier += _(' up to %s') % prop.get('MaxValue') if prop.get('MinLength'): classifier += _(' from length %s') % prop.get('MinLength') if prop.get('MaxLength'): classifier += _(' up to length %s') % prop.get('MaxLength') prop_item.append(nodes.classifier('', classifier)) definition = nodes.definition() prop_item.append(definition) if not prop.get('Implemented', True): para = nodes.inline('', _('Not implemented.')) warning = nodes.note('', para) definition.append(warning) return description = prop.get('Description') if description: para = nodes.paragraph('', description) definition.append(para) if prop.get('Required'): para = nodes.paragraph('', _('Required property.')) elif prop.get('Default'): para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.get('Default')) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) if prop.get('AllowedPattern'): para = nodes.paragraph( '', _('Value must match pattern: %s') % prop.get('AllowedPattern')) definition.append(para) if prop.get('AllowedValues'): allowed = [ str(a) for a in prop.get('AllowedValues') if a is not None ] para = nodes.paragraph( '', _('Allowed values: %s') % ', '.join(allowed)) definition.append(para) sub_schema = None if prop.get('Schema') and prop_type == 'Map': para = nodes.emphasis('', _('Map properties:')) definition.append(para) sub_schema = prop.get('Schema') elif prop_type == 'List' and prop.get('Schema', {}).get('Schema'): para = nodes.emphasis('', _('List contains maps with the properties:')) definition.append(para) sub_schema = prop.get('Schema').get('Schema') if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key in sorted(sub_schema.keys()): sub_prop = sub_schema[sub_prop_key] self.contribute_property(sub_prop_list, sub_prop_key, sub_prop)
def run(self): env = self.state.document.settings.env # generate the linkback node for this option targetid = "option-%s" % self.options['config'] targetnode = nodes.target('', '', ids=[targetid]) # Each option will be outputted as a single-item definition list # (just like it was doing before we used this extension) dl = nodes.definition_list() dl['classes'].append('mrjob-opt') dli = nodes.definition_list_item() term = nodes.term() # config option shall be bold if 'config' in self.options: cfg = self.options['config'] term.append(nodes.strong(cfg, cfg)) if 'switch' in self.options: term.append(nodes.Text(' (', ' (')) # switch shall be comma-separated literals if 'switch' in self.options: switches = self.options['switch'].split(', ') for i, s in enumerate(switches): if i > 0: term.append(nodes.Text(', ', ', ')) term.append(nodes.literal(s, s)) if 'config' in self.options: term.append(nodes.Text(')', ')')) dli.append(term) # classifier is either plain text or a link to some more docs, so parse # its contents classifier = nodes.classifier() type_nodes, messages = self.state.inline_text( self.options.get('type', ''), self.lineno) classifier.extend(type_nodes) dli.append(classifier) # definition holds the description defn = nodes.definition() # add a default if any default_nodes = [] if 'default' in self.options: default_par = nodes.paragraph() default_par.append(nodes.strong('Default: ', 'Default: ')) textnodes, messages = self.state.inline_text( self.options['default'], self.lineno) default_nodes = textnodes default_par.extend(textnodes) defn.append(default_par) # parse the description like a nested block (see # sphinx.compat.make_admonition) desc_par = nodes.paragraph() self.state.nested_parse(self.content, self.content_offset, desc_par) defn.append(desc_par) dli.append(defn) dl.append(dli) if not hasattr(env, 'optionlist_all_options'): env.optionlist_all_options = [] env.optionlist_indexed_options = {} # store info for the optionlist traversal to find info = { 'docname': env.docname, 'lineno': self.lineno, 'options': self.options, 'content': self.content, 'target': targetnode, 'type_nodes': type_nodes, 'default_nodes': default_nodes, } env.optionlist_all_options.append(info) env.optionlist_indexed_options[self.options['config']] = info return [targetnode, dl]
def run(self): content = [] # First, add a short description supplied by the directive. text = '\n'.join(self.content) text_node = nodes.paragraph(rawsource=text) # Parse the directive contents. self.state.nested_parse(self.content, self.content_offset, text_node) content.append(text_node) klass_name = self.arguments[0] klass = get_class(klass_name) definition_list = nodes.definition_list() # Now, go over the class and find and interogate all the properties. raw_text = "" for attribute in klass.__class_schema_nodes__: list_item = nodes.definition_list_item() # TODO: Make it parse in restructuredtext from the nodes themselves. term = nodes.term(text=attribute.name) # Add two classifiers; one for the type and the other # if it's required or optional. node_type = nodes.classifier(text=attribute.typ.__class__.__name__) required_text = 'Optional' if attribute.required: required_text = 'Required' required = nodes.classifier(text=required_text) # Set up the description, adding in full stops if needed. definition = nodes.definition() description_text = attribute.title if not attribute.title.endswith('.'): description_text += '.' description_text += ' ' + attribute.description if not description_text.endswith('.'): description_text += '.' description = nodes.paragraph(text=description_text) definition += description if attribute.default != colander.null: # There is a default set. Add it. if isinstance(attribute.default, bool): # Convert boolean's str() output to lowercase. # Why? In yaml it must be lowercase, so having it in the # docs as uppercase is confusing to users. default_text = "Default value: %s" % str(attribute.default).lower() else: default_value = str(attribute.default) if len(default_value) == 0: default_value = "''" default_text = "Default value: %s" % default_value default = nodes.paragraph(text=default_text) definition += default list_item += term list_item += node_type list_item += required list_item += definition definition_list += list_item content.append(definition_list) content.append(nodes.paragraph(text="Original class: %s" % klass)) return content
def contribute_property(self, prop_list, prop_key, prop, upd_para=None): prop_item = nodes.definition_list_item( '', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) self._status_str(prop.support_status, definition) if not prop.implemented: para = nodes.paragraph('', _('Not implemented.')) note = nodes.note('', para) definition.append(note) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if upd_para is not None: definition.append(upd_para) else: if prop.update_allowed: upd_para = nodes.paragraph( '', _('Can be updated without replacement.')) definition.append(upd_para) elif prop.immutable: upd_para = nodes.paragraph('', _('Updates are not supported. ' 'Resource update will fail on' ' any attempt to update this ' 'property.')) definition.append(upd_para) else: upd_para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(upd_para) if prop.default is not None: para = nodes.paragraph('', _('Defaults to "%s".') % prop.default) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.Schema.MAP: para = nodes.paragraph() emph = nodes.emphasis('', _('Map properties:')) para.append(emph) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.Schema.LIST: para = nodes.paragraph() emph = nodes.emphasis('', _('List contents:')) para.append(emph) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key, sub_prop in sorted(sub_schema.items(), self.cmp_prop): if sub_prop.support_status.status != support.HIDDEN: self.contribute_property( sub_prop_list, sub_prop_key, sub_prop, upd_para)
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item( '', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) self._status_str(prop.support_status, definition) if not prop.implemented: para = nodes.paragraph('', _('Not implemented.')) note = nodes.note('', para) definition.append(note) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if prop.update_allowed: para = nodes.paragraph('', _('Can be updated without replacement.')) definition.append(para) elif prop.immutable: para = nodes.paragraph('', _('Updates are not supported. ' 'Resource update will fail on any ' 'attempt to update this property.')) definition.append(para) else: para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(para) if prop.required: para = nodes.paragraph('', _('Required property.')) elif prop.default is not None: para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.default) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.Schema.MAP: para = nodes.paragraph() emph = nodes.emphasis('', _('Map properties:')) para.append(emph) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.Schema.LIST: para = nodes.paragraph() emph = nodes.emphasis('', _('List contents:')) para.append(emph) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key, sub_prop in sorted(sub_schema.items(), self.cmp_prop): self.contribute_property( sub_prop_list, sub_prop_key, sub_prop)
def run(self): env = self.state.document.settings.env # generate the linkback node for this option targetid = "option-%d" % env.new_serialno('mrjob-opt') targetnode = nodes.target('', '', ids=[targetid]) # Each option will be outputted as a single-item definition list # (just like it was doing before we used this extension) dl = nodes.definition_list() dli = nodes.definition_list_item() term = nodes.term() # config option shall be bold if 'config' in self.options: cfg = self.options['config'] term.append(nodes.strong(cfg, cfg)) if 'switch' in self.options: term.append(nodes.Text(' (', ' (')) # switch shall be comma-separated literals if 'switch' in self.options: switches = self.options['switch'].split(', ') for i, s in enumerate(switches): if i > 0: term.append(nodes.Text(', ', ', ')) term.append(nodes.literal(s, s)) if 'config' in self.options: term.append(nodes.Text(')', ')')) dli.append(term) # classifier is either plan text or a link to some more docs, so parse # its contents classifier = nodes.classifier() type_nodes, messages = self.state.inline_text( self.options.get('type', ''), self.lineno) # failed attempt at a markup shortcut; may be able to make this work # later #t = option_info['options']['type'] #refnode = addnodes.pending_xref( # t, reftarget='data-type-%s' % t, # refexplicit=True, reftype='ref') #print refnode #refnode += nodes.Text(t, t) #type_nodes = [refnode] classifier.extend(type_nodes) dli.append(classifier) # definition holds the description defn = nodes.definition() # add a default if any default_nodes = [] if 'default' in self.options: default_par = nodes.paragraph() default_par.append(nodes.strong('Default: ', 'Default: ')) textnodes, messages = self.state.inline_text( self.options['default'], self.lineno) default_nodes = textnodes default_par.extend(textnodes) defn.append(default_par) # parse the description like a nested block (see # sphinx.compat.make_admonition) desc_par = nodes.paragraph() self.state.nested_parse(self.content, self.content_offset, desc_par) defn.append(desc_par) dli.append(defn) dl.append(dli) if not hasattr(env, 'optionlist_all_options'): env.optionlist_all_options = [] # store info for the optionlist traversal to find env.optionlist_all_options.append({ 'docname': env.docname, 'lineno': self.lineno, 'options': self.options, 'content': self.content, 'target': targetnode, 'type_nodes': [n.deepcopy() for n in type_nodes], 'default_nodes': [n.deepcopy() for n in default_nodes] }) return [targetnode, dl]
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item( '',nodes.term('', prop_key)) prop_list.append(prop_item) prop_type = prop.get('Type') classifier = prop_type if prop.get('MinValue'): classifier += _(' from %s') % prop.get('MinValue') if prop.get('MaxValue'): classifier += _(' up to %s') % prop.get('MaxValue') if prop.get('MinLength'): classifier += _(' from length %s') % prop.get('MinLength') if prop.get('MaxLength'): classifier += _(' up to length %s') % prop.get('MaxLength') prop_item.append(nodes.classifier('', classifier)) definition = nodes.definition() prop_item.append(definition) if not prop.get('Implemented', True): para = nodes.inline('', _('Not implemented.')) warning = nodes.note('', para) definition.append(warning) return description = prop.get('Description') if description: para = nodes.paragraph('', description) definition.append(para) if prop.get('Required'): para = nodes.paragraph('', _('Required property.')) elif prop.get('Default'): para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.get('Default')) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) if prop.get('AllowedPattern'): para = nodes.paragraph('', _( 'Value must match pattern: %s') % prop.get('AllowedPattern')) definition.append(para) if prop.get('AllowedValues'): allowed = [str(a) for a in prop.get('AllowedValues') if a is not None] para = nodes.paragraph('', _( 'Allowed values: %s') % ', '.join(allowed)) definition.append(para) sub_schema = None if prop.get('Schema') and prop_type == 'Map': para = nodes.emphasis('', _('Map properties:')) definition.append(para) sub_schema = prop.get('Schema') elif prop_type == 'List' and prop.get('Schema', {}).get('Schema'): para = nodes.emphasis( '', _('List contains maps with the properties:')) definition.append(para) sub_schema = prop.get('Schema').get('Schema') if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key in sorted(sub_schema.keys()): sub_prop = sub_schema[sub_prop_key] self.contribute_property(sub_prop_list, sub_prop_key, sub_prop)
def run(self): content = [] # First, add a short description supplied by the directive. text = '\n'.join(self.content) text_node = nodes.paragraph(rawsource=text) # Parse the directive contents. self.state.nested_parse(self.content, self.content_offset, text_node) content.append(text_node) klass_name = self.arguments[0] klass = get_class(klass_name) definition_list = nodes.definition_list() # Now, go over the class and find and interogate all the properties. raw_text = "" for attribute in klass.__class_schema_nodes__: list_item = nodes.definition_list_item() # TODO: Make it parse in restructuredtext from the nodes themselves. term = nodes.term(text=attribute.name) # Add two classifiers; one for the type and the other # if it's required or optional. node_type = nodes.classifier(text=attribute.typ.__class__.__name__) required_text = 'Optional' if attribute.required: required_text = 'Required' required = nodes.classifier(text=required_text) # Set up the description, adding in full stops if needed. definition = nodes.definition() description_text = attribute.title if not attribute.title.endswith('.'): description_text += '.' description_text += ' ' + attribute.description if not description_text.endswith('.'): description_text += '.' description = nodes.paragraph(text=description_text) definition += description if attribute.default != colander.null: # There is a default set. Add it. if isinstance(attribute.default, bool): # Convert boolean's str() output to lowercase. # Why? In yaml it must be lowercase, so having it in the # docs as uppercase is confusing to users. default_text = "Default value: %s" % str( attribute.default).lower() else: default_value = str(attribute.default) if len(default_value) == 0: default_value = "''" default_text = "Default value: %s" % default_value default = nodes.paragraph(text=default_text) definition += default list_item += term list_item += node_type list_item += required list_item += definition definition_list += list_item content.append(definition_list) content.append(nodes.paragraph(text="Original class: %s" % klass)) return content
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item( '', nodes.term('', prop_key)) prop_list.append(prop_item) prop_item.append(nodes.classifier('', prop.type)) definition = nodes.definition() prop_item.append(definition) if prop.support_status.status != support.SUPPORTED: para = nodes.paragraph('', self._status_str(prop.support_status)) note = nodes.note('', para) definition.append(note) if (prop.support_status.status == support.SUPPORTED and prop.support_status.version is not None): tag = prop.support_status.version.title() message = (_('Available since %s.') % self._version_str(tag)) para = nodes.paragraph('', message) note = nodes.note('', para) definition.append(note) if not prop.implemented: para = nodes.paragraph('', _('Not implemented.')) note = nodes.note('', para) definition.append(note) return if prop.description: para = nodes.paragraph('', prop.description) definition.append(para) if prop.update_allowed: para = nodes.paragraph('', _('Can be updated without replacement.')) definition.append(para) elif prop.immutable: para = nodes.paragraph('', _('Updates are not supported. ' 'Resource update will fail on any ' 'attempt to update this property.')) definition.append(para) else: para = nodes.paragraph('', _('Updates cause replacement.')) definition.append(para) if prop.required: para = nodes.paragraph('', _('Required property.')) elif prop.default is not None: para = nodes.paragraph( '', _('Optional property, defaults to "%s".') % prop.default) else: para = nodes.paragraph('', _('Optional property.')) definition.append(para) for constraint in prop.constraints: para = nodes.paragraph('', str(constraint)) definition.append(para) sub_schema = None if prop.schema and prop.type == properties.Schema.MAP: para = nodes.paragraph() emph = nodes.emphasis('', _('Map properties:')) para.append(emph) definition.append(para) sub_schema = prop.schema elif prop.schema and prop.type == properties.Schema.LIST: para = nodes.paragraph() emph = nodes.emphasis('', _('List contents:')) para.append(emph) definition.append(para) sub_schema = prop.schema if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key, sub_prop in sorted(sub_schema.items(), self.cmp_prop): self.contribute_property( sub_prop_list, sub_prop_key, sub_prop)
def contribute_property(self, prop_list, prop_key, prop): prop_item = nodes.definition_list_item("", nodes.term("", prop_key)) prop_list.append(prop_item) prop_type = prop.get("Type") classifier = prop_type if prop.get("MinValue"): classifier += _(" from %s") % prop.get("MinValue") if prop.get("MaxValue"): classifier += _(" up to %s") % prop.get("MaxValue") if prop.get("MinLength"): classifier += _(" from length %s") % prop.get("MinLength") if prop.get("MaxLength"): classifier += _(" up to length %s") % prop.get("MaxLength") prop_item.append(nodes.classifier("", classifier)) definition = nodes.definition() prop_item.append(definition) if not prop.get("Implemented", True): para = nodes.inline("", _("Not implemented.")) warning = nodes.note("", para) definition.append(warning) return description = prop.get("Description") if description: para = nodes.paragraph("", description) definition.append(para) if prop.get("Required"): para = nodes.paragraph("", _("Required property.")) elif prop.get("Default"): para = nodes.paragraph("", _('Optional property, defaults to "%s".') % prop.get("Default")) else: para = nodes.paragraph("", _("Optional property.")) definition.append(para) if prop.get("AllowedPattern"): para = nodes.paragraph("", _("Value must match pattern: %s") % prop.get("AllowedPattern")) definition.append(para) if prop.get("AllowedValues"): allowed = [str(a) for a in prop.get("AllowedValues") if a is not None] para = nodes.paragraph("", _("Allowed values: %s") % ", ".join(allowed)) definition.append(para) sub_schema = None if prop.get("Schema") and prop_type == "Map": para = nodes.emphasis("", _("Map properties:")) definition.append(para) sub_schema = prop.get("Schema") elif prop_type == "List" and prop.get("Schema", {}).get("Schema"): para = nodes.emphasis("", _("List contains maps with the properties:")) definition.append(para) sub_schema = prop.get("Schema").get("Schema") if sub_schema: sub_prop_list = nodes.definition_list() definition.append(sub_prop_list) for sub_prop_key in sorted(sub_schema.keys()): sub_prop = sub_schema[sub_prop_key] self.contribute_property(sub_prop_list, sub_prop_key, sub_prop)