diff --git a/components/binary_sensor/index.rst b/components/binary_sensor/index.rst index 4683ad514..f0d99c21c 100644 --- a/components/binary_sensor/index.rst +++ b/components/binary_sensor/index.rst @@ -85,23 +85,40 @@ of these entries matters!) return {}; } -Supported filters: +``invert`` +********** -- **invert**: Simple filter that just inverts every value from the binary sensor. -- **delayed_on**: When a signal ON is received, wait for the specified time period until publishing - an ON state. If an OFF value is received while waiting, the ON action is discarded. Or in other words: - Only send an ON value if the binary sensor has stayed ON for at least the specified time period. - **Useful for debouncing push buttons**. -- **delayed_off**: When a signal OFF is received, wait for the specified time period until publishing - an OFF state. If an ON value is received while waiting, the OFF action is discarded. Or in other words: - Only send an OFF value if the binary sensor has stayed OFF for at least the specified time period. - **Useful for debouncing push buttons**. -- **delayed_on_off**: Only send an ON or OFF value if the binary sensor has stayed in the same state - for at least the specified time period. - **Useful for debouncing binary switches**. -- **lambda**: Specify any :ref:`lambda ` for more complex filters. The input value from - the binary sensor is ``x`` and you can return ``true`` for ON, ``false`` for OFF, and ``{}`` to stop - the filter chain. +Simple filter that just inverts every value from the binary sensor. + +``delayed_on`` +************** + +(**Required**, :ref:`config-time`): When a signal ON is received, wait for the specified time period until publishing +an ON state. If an OFF value is received while waiting, the ON action is discarded. Or in other words: +Only send an ON value if the binary sensor has stayed ON for at least the specified time period. +**Useful for debouncing push buttons**. + +``delayed_off`` +*************** + +(**Required**, :ref:`config-time`): When a signal OFF is received, wait for the specified time period until publishing +an OFF state. If an ON value is received while waiting, the OFF action is discarded. Or in other words: +Only send an OFF value if the binary sensor has stayed OFF for at least the specified time period. +**Useful for debouncing push buttons**. + +``delayed_on_off`` +****************** + +(**Required**, :ref:`config-time`): Only send an ON or OFF value if the binary sensor has stayed in the same state +for at least the specified time period. +**Useful for debouncing binary switches**. + +``lambda`` +********** + +Specify any :ref:`lambda ` for more complex filters. The input value from +the binary sensor is ``x`` and you can return ``true`` for ON, ``false`` for OFF, and ``{}`` to stop +the filter chain. Binary Sensor Automation ------------------------ diff --git a/components/display/st7735.rst b/components/display/st7735.rst index c01dc0e12..7bd7bb301 100644 --- a/components/display/st7735.rst +++ b/components/display/st7735.rst @@ -42,7 +42,7 @@ There are numerous board types out there. Some initialize differently as well. T update_interval: 5s Configuration variables: -~~~~~~~~~~~~~~~~~~~~~~~~ +************************ - **model** (**Required**, "See Models Below"): This the model to use. INITR_BLACKTAB is the default - **cs_pin** (**Required**, :ref:`Pin Schema `): The CS pin. @@ -55,7 +55,7 @@ Configuration variables: - **reset_pin** (*Optional*, :ref:`Pin Schema `): The RESET pin. Memory notes: -~~~~~~~~~~~~~ +************* - 8Bit color saves 50% of the buffer required. - eightbitcolor: True 160x128 = 20480 *Important for memory constrained devices* @@ -63,7 +63,7 @@ Memory notes: Models: -~~~~~~~ +******* - INITR_GREENTAB - INITR_REDTAB diff --git a/components/mcp230xx.rst b/components/mcp230xx.rst index 23e80cb21..6bff7d85c 100644 --- a/components/mcp230xx.rst +++ b/components/mcp230xx.rst @@ -52,7 +52,7 @@ The MCP23008 component (`datasheet ` @@ -173,7 +173,7 @@ binary sensor or GPIO switch. inverted: False Configuration variables: -~~~~~~~~~~~~~~~~~~~~~~~~ +************************ - **id** (**Required**, :ref:`config-id`): The id to use for this MCP23017 component. - **address** (*Optional*, int): The I²C address of the driver. @@ -183,7 +183,7 @@ Configuration variables: will require pull-up resistors (to 3.3 volts) when this mode is enabled. Pin configuration variables: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +**************************** - **mcp23xxx** (**Required**, :ref:`config-id`): The id of the MCP23017 component. - **interrupt** (*Optional*): Set this pin to trigger the port INT pin on the component. Can be one of ``CHANGE``, ``RISING``, ``FALLING``. diff --git a/components/mcp23Sxx.rst b/components/mcp23Sxx.rst index 861c78364..2b6f26a92 100644 --- a/components/mcp23Sxx.rst +++ b/components/mcp23Sxx.rst @@ -54,7 +54,7 @@ The MCP23S08 component (`datasheet `__ +over the last few values. This can be used to filter outliers from the received sensor data. A large +window size will make the filter slow to react to input changes. .. code-block:: yaml @@ -232,27 +237,25 @@ sensor data. A large window size will make the filter slow to react to input cha send_every: 4 send_first_at: 3 -- **median**: A `simple moving median - `__ - over the last few values. +Configuration variables: - - **window_size**: The number of values over which to calculate the median - when pushing out a value. This number should - be odd if you want an actual received value pushed out. - Defaults to ``5``. - - **send_every**: How often a sensor value should be pushed out. For - example, in above configuration the median is calculated after every 4th - received sensor value, over the last 7 received values. - Defaults to ``5``. - - **send_first_at**: By default, the very first raw value on boot is immediately - published. With this parameter you can specify when the very first value is to be sent. - Must be smaller than or equal to ``send_every`` - Defaults to ``1``. +- **window_size** (*Optional*, integer): The number of values over which to calculate the median + when pushing out a value. This number should + be odd if you want an actual received value pushed out. + Defaults to ``5``. +- **send_every** (*Optional*, integer): How often a sensor value should be pushed out. For + example, in above configuration the median is calculated after every 4th + received sensor value, over the last 7 received values. + Defaults to ``5``. +- **send_first_at** (*Optional*, integer): By default, the very first raw value on boot is immediately + published. With this parameter you can specify when the very first value is to be sent. + Must be smaller than or equal to ``send_every`` + Defaults to ``1``. -``min`` / ``max`` -***************** +``min`` +******* -Calculate min/max over the data. A large window size will make the filter slow to +A moving minimum over the last few values. A large window size will make the filter slow to react to input changes. .. code-block:: yaml @@ -266,29 +269,46 @@ react to input changes. send_every: 4 send_first_at: 3 -- **min**: A moving minimum over the last few values. +Configuration variables: -- **max**: A moving maximum over the last few values. +- **window_size** (*Optional*, integer): The number of values over which to calculate the min/max when pushing out a + value. Defaults to ``5``. +- **send_every** (*Optional*, integer): How often a sensor value should be pushed out. For + example, in above configuration the min is calculated after every 4th + received sensor value, over the last 7 received values. + Defaults to ``5``. +- **send_first_at** (*Optional*, integer): By default, the very first raw value on boot is immediately + published. With this parameter you can specify when the very first value is to be sent. + Must be smaller than or equal to ``send_every`` + Defaults to ``1``. -- Both accept the following parameters: +``max`` +******* - - **window_size**: The number of values over which to calculate the min/max - when pushing out a value. - Defaults to ``5``. - - **send_every**: How often a sensor value should be pushed out. For - example, in above configuration the min is calculated after every 4th - received sensor value, over the last 7 received values. - Defaults to ``5``. - - **send_first_at**: By default, the very first raw value on boot is immediately - published. With this parameter you can specify when the very first value is to be sent. - Must be smaller than or equal to ``send_every`` - Defaults to ``1``. +A moving maximum over the last few values. A large window size will make the filter slow to +react to input changes. -``sliding_window_moving_average`` / ``exponential_moving_average`` -****************************************************************** +Configuration variables: -Two simple moving averages over the data. These can be used to have a short update interval -on the sensor but only push out an average on a specific interval (thus increasing resolution). +- **window_size** (*Optional*, integer): The number of values over which to calculate the min/max + when pushing out a value. + Defaults to ``5``. +- **send_every** (*Optional*, integer): How often a sensor value should be pushed out. For + example, in above configuration the min is calculated after every 4th + received sensor value, over the last 7 received values. + Defaults to ``5``. +- **send_first_at** (*Optional*, integer): By default, the very first raw value on boot is immediately + published. With this parameter you can specify when the very first value is to be sent. + Must be smaller than or equal to ``send_every`` + Defaults to ``1``. + + +``sliding_window_moving_average`` +********************************* + +A `simple moving average `__ +over the last few values. It can be used to have a short update interval on the sensor but only push +out an average on a specific interval (thus increasing resolution). .. code-block:: yaml @@ -300,28 +320,36 @@ on the sensor but only push out an average on a specific interval (thus increasi window_size: 15 send_every: 15 -- **sliding_window_moving_average**: A `simple moving - average `__ - over the last few values. +Configuration variables: - - **window_size**: The number of values over which to perform an - average when pushing out a value. - - **send_every**: How often a sensor value should be pushed out. For - example, in above configuration the weighted average is only - pushed out on every 15th received sensor value. - - **send_first_at**: By default, the very first raw value on boot is immediately - published. With this parameter you can specify when the very first value is to be sent. - Defaults to ``1``. +- **window_size** (*Optional*, integer): The number of values over which to perform an + average when pushing out a value. +- **send_every** (*Optional*, integer): How often a sensor value should be pushed out. For + example, in above configuration the weighted average is only + pushed out on every 15th received sensor value. +- **send_first_at** (*Optional*, integer): By default, the very first raw value on boot is immediately + published. With this parameter you can specify when the very first value is to be sent. + Defaults to ``1``. -- **exponential_moving_average**: A simple `exponential moving - average `__ - over the last few values. +``exponential_moving_average`` +****************************** - - **alpha**: The forget factor/alpha value of the filter. - - **send_every**: How often a sensor value should be pushed out. +A simple `exponential moving average +`__ over the last few +values. It can be used to have a short update interval on the sensor but only push +out an average on a specific interval (thus increasing resolution). -``throttle`` / ``heartbeat`` / ``debounce`` / ``delta`` -******************************************************* +Configuration variables: + +- **alpha** (*Optional*, float): The forget factor/alpha value of the filter. Defaults to ``0.1``. +- **send_every** (*Optional*, integer): How often a sensor value should be pushed out. Defaults to ``15``. + +``throttle`` +************ + +Throttle the incoming values. When this filter gets an incoming value, +it checks if the last incoming value is at least ``specified time period`` old. +If it is not older than the configured value, the value is not passed forward. .. code-block:: yaml @@ -333,28 +361,38 @@ on the sensor but only push out an average on a specific interval (thus increasi - delta: 5.0 - lambda: return x * (9.0/5.0) + 32.0; -- **throttle**: Throttle the incoming values. When this filter gets an incoming value, - it checks if the last incoming value is at least ``specified time period`` old. - If it is not older than the configured value, the value is not passed forward. -- **heartbeat**: Send the last value that this sensor in the specified time interval. - So a value of ``10s`` will cause the filter to output values every 10s regardless - of the input values. - -- **debounce**: Only send values if the last incoming value is at least ``specified time period`` - old. For example if two values come in at almost the same time, this filter will only output - the last value and only after the specified time period has passed without any new incoming - values. - -- **delta**: This filter stores the last value passed through this filter and only - passes incoming values through if the absolute difference is greater than the configured - value. For example if a value of 1.0 first comes in, it's passed on. If the delta filter - is configured with a value of 5, it will now not pass on an incoming value of 2.0, only values - that are at least 6.0 big or -4.0. - -``or`` Filter +``heartbeat`` ************* +Send the last value that this sensor in the specified time interval. +So a value of ``10s`` will cause the filter to output values every 10s regardless +of the input values. + +``debounce`` +************ + +Only send values if the last incoming value is at least ``specified time period`` +old. For example if two values come in at almost the same time, this filter will only output +the last value and only after the specified time period has passed without any new incoming +values. + +``delta`` +********* + +This filter stores the last value passed through this filter and only +passes incoming values through if the absolute difference is greater than the configured +value. For example if a value of 1.0 first comes in, it's passed on. If the delta filter +is configured with a value of 5, it will now not pass on an incoming value of 2.0, only values +that are at least 6.0 big or -4.0. + +``or`` +****** + +Pass forward a value with the first child filter that returns. Above example +will only pass forward values that are *either* at least 1s old or are if the absolute +difference is at least 5.0. + .. code-block:: yaml # Example filters: @@ -363,22 +401,18 @@ on the sensor but only push out an average on a specific interval (thus increasi - throttle: 1s - delta: 5.0 -- **or**: Pass forward a value with the first child filter that returns. Above example - will only pass forward values that are *either* at least 1s old or are if the absolute - difference is at least 5.0. +``lambda`` +********** -``lambda`` Filter -***************** +Perform a simple mathematical operation over the sensor values. The input value is ``x`` and +the result of the lambda is used as the output (use ``return``). .. code-block:: yaml filters: - lambda: return x * (9.0/5.0) + 32.0; -**lambda**: Perform a simple mathematical operation over the sensor -values. The input value is ``x`` and the result of the lambda is used -as the output (use ``return``). Make sure to add ``.0`` to all values in the lambda, otherwise divisions of integers will result in integers (not floating point values). diff --git a/components/sn74hc595.rst b/components/sn74hc595.rst index 787c9aa5b..21ce5b213 100644 --- a/components/sn74hc595.rst +++ b/components/sn74hc595.rst @@ -43,7 +43,7 @@ Use of the OE pin is optional. If used, the pin should be pulled up externally. inverted: False Configuration variables: -~~~~~~~~~~~~~~~~~~~~~~~~ +************************ - **id** (**Required**, :ref:`config-id`): The id to use for this SN74HC595 component. - **data_pin** (**Required**, :ref:`Pin Schema `): Pin connected to SN74HC595 SER input. @@ -54,7 +54,7 @@ Configuration variables: Pin configuration variables: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +**************************** - **sn74hc595** (**Required**, :ref:`config-id`): The id of the SN74HC595 component of the pin. - **number** (**Required**, integer): The pin number. diff --git a/guides/contributing.rst b/guides/contributing.rst index 0e6fd2924..fd285671b 100644 --- a/guides/contributing.rst +++ b/guides/contributing.rst @@ -31,9 +31,10 @@ The ESPHome documentation is built using `sphinx `__ Syntax ****** -In my opinion, Markdown would have been the much better choice in hindsight, but at the time -I was setting up the documentation good Doxygen integration was key to me. Anyway, here's a quick -RST primer: +Here's a quick RST primer: + +Title hierarchy is based on order of occurence, not on type of character used to underline it. This +documents establish the following character order for better consistency. - **Headers**: You can write titles like this: @@ -547,8 +548,8 @@ loader. These are: has one of them in the config, a validation error will be generated. - ``ESP_PLATFORMS``: Provide a list of allowed ESP types this integration works with. -- ``CODEOWNERS``: GitHub usernames or team names of people that are responsible for this integration. - You should add at least your GitHub username here, as well as anyone who helped you to write code +- ``CODEOWNERS``: GitHub usernames or team names of people that are responsible for this integration. + You should add at least your GitHub username here, as well as anyone who helped you to write code that is being included. Codebase Standards diff --git a/schema_doc.py b/schema_doc.py index 2a1322e39..4eff4d99f 100644 --- a/schema_doc.py +++ b/schema_doc.py @@ -6,7 +6,7 @@ from typing import MutableMapping from sphinx.util import logging from docutils import nodes -SCHEMA_PATH = "../esphome_devices/schema.json" +SCHEMA_PATH = "schema.json" CONFIGURATION_VARIABLES = "Configuration variables:" PIN_CONFIGURATION_VARIABLES = "Pin configuration variables:" COMPONENT_HUB = "Component/Hub" @@ -75,7 +75,9 @@ PLATFORMS_TITLES = { } CUSTOM_DOCS = { - "guides/automations": {"Global Variables": "properties/globals"}, + "guides/automations": { + "Global Variables": "properties/globals", + }, "guides/configuration-types": { "Color": "properties/color", "Pin Schema": [ @@ -83,6 +85,9 @@ CUSTOM_DOCS = { "definitions/PIN.OUTPUT_INTERNAL", ], }, + "components/binary_sensor/index": { + "Binary Sensor Filters": "binary_sensor.FILTER_REGISTRY", + }, "components/climate/ir_climate": { "IR Remote Climate": [ "properties/climate/coolix", @@ -109,7 +114,8 @@ CUSTOM_DOCS = { "definitions/light.BINARY_LIGHT_SCHEMA", "definitions/light.BRIGHTNESS_ONLY_LIGHT_SCHEMA", "definitions/light.LIGHT_SCHEMA", - ] + ], + "Light Effects": "light.EFFECTS_REGISTRY", }, "components/light/fastled": { "Clockless": "properties/light/fastled_clockless", @@ -125,10 +131,13 @@ CUSTOM_DOCS = { "MQTT Component Base Configuration": "definitions/CONFIG.MQTT_COMMAND_COMPONENT_SCHEMA", }, "components/output/index": { - "Base Output Configuration": "definitions/output.FLOAT_OUTPUT_SCHEMA" + "Base Output Configuration": "definitions/output.FLOAT_OUTPUT_SCHEMA", }, "components/remote_transmitter": { - "Remote Transmitter Actions": "definitions/REMOTE_BASE.BASE_REMOTE_TRANSMITTER_SCHEMA" + "Remote Transmitter Actions": "definitions/REMOTE_BASE.BASE_REMOTE_TRANSMITTER_SCHEMA", + }, + "components/sensor/index": { + "Sensor Filters": "sensor.FILTER_REGISTRY", }, "components/time": { "Home Assistant Time Source": "properties/time/homeassistant", @@ -146,6 +155,10 @@ CUSTOM_DOCS = { } +def get_node_title(node): + return list(node.traverse(nodes.title))[0].astext() + + class SchemaGeneratorVisitor(nodes.NodeVisitor): def __init__(self, app, doctree, docname): nodes.NodeVisitor.__init__(self, doctree) @@ -160,6 +173,8 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): self.json_base_config = None self.title_id = None self.props_section_title = None + self.find_registry = None + self.section_level = 0 if self.path[0] == "components": if len(self.path) == 2: # root component, e.g. dfplayer, logger component = docname[11:] @@ -230,7 +245,7 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): # this is empty, not much to do raise nodes.SkipChildren - self.props_section_title = list(node.traverse(nodes.title))[0].astext() + self.props_section_title = get_node_title(node) # Document first paragraph is description of this thing description = self.getMarkdownParagraph(node) @@ -266,23 +281,23 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): def depart_document(self, node): pass - def visit_SEONode(self, node): - pass - - def depart_SEONode(self, node): - pass - - def visit_literal_block(self, node): - pass - - def depart_literal_block(self, node): - pass - def visit_section(self, node): - pass + self.section_level += 1 + section_title = get_node_title(node) + if self.custom_doc and section_title in self.custom_doc: + r = self.custom_doc[section_title] + if ( + isinstance(r, list) + or r.startswith("properties") + or r.startswith("definitions") + ): + return + self.find_registry = r def depart_section(self, node): - pass + self.section_level -= 1 + if self.section_level == 1: + self.find_registry = None def unknown_visit(self, node): pass @@ -303,7 +318,11 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): # TODO: add same markdown description to each? return + json_component = self.find_component(self.custom_doc[title_text]) + if not json_component: + return + json_component["markdownDescription"] = self.getMarkdownParagraph( node.parent ) @@ -450,22 +469,6 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): ) return - if title_text.endswith("Action") or title_text.endswith("Condition"): - # Document first paragraph is description of this thing - description = self.getMarkdownParagraph(node.parent) - split_text = title_text.split(" ") - if len(split_text) != 2: - return - key = split_text[0] - registry_name = f"automation.{split_text[1].upper()}_REGISTRY" - registry = self.app.jschema["definitions"][registry_name]["anyOf"] - for action in registry: - if key in action["properties"]: - action["properties"][key]["markdownDescription"] = description - self.props = self.find_props(action["properties"][key]) - break - self.props_section_title = title_text - if title_text.endswith("Trigger"): # Document first paragraph is description of this thing description = self.getMarkdownParagraph(node.parent) @@ -481,28 +484,50 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): self.props = self.find_props(trigger_schema) self.props_section_title = title_text - if self.docname == "components/light/index" and title_text.endswith("Effect"): - # Document first paragraph is description of this thing + if title_text == PIN_CONFIGURATION_VARIABLES: + self.multi_component = [] + if self.app.jschema["definitions"].get(f"PIN.INPUT_{self.path[-1]}"): + self.multi_component.append(f"definitions/PIN.INPUT_{self.path[-1]}") + if self.app.jschema["definitions"].get(f"PIN.OUTPUT_{self.path[-1]}"): + self.multi_component.append(f"definitions/PIN.OUTPUT_{self.path[-1]}") + self.accept_props = True + self.filled_props = False + self.props = None + if len(self.multi_component) == 0: + raise ValueError( + f'Found a "{PIN_CONFIGURATION_VARIABLES}" entry but could not find pin schema' + ) + if title_text.endswith("Action") or title_text.endswith("Condition"): + # Document first paragraph is description of this thing description = self.getMarkdownParagraph(node.parent) - name = title_text[: -len(" Effect")] - # accept Light Effect as ending (Automation Light Effect) + split_text = title_text.split(" ") + if len(split_text) != 2: + return + key = split_text[0] + + if self.props: + ref = self.props.get(key) + if ref: + ref = self.get_ref(ref) + if ref: + self.props = self.find_props(ref) + return + + registry_name = f"automation.{split_text[1].upper()}_REGISTRY" + self.find_registry_prop(registry_name, key, description) + + if self.section_level == 3 and self.find_registry: + name = title_text + if name.endswith(" Effect"): + name = title_text[: -len(" Effect")] if name.endswith(" Light"): name = name[: -len(" Light")] - key = name.replace(" ", "_").replace(".", "").lower() - registry = self.app.jschema["definitions"]["light.EFFECTS_REGISTRY"][ - "anyOf" - ] + description = self.getMarkdownParagraph(node.parent) + self.find_registry_prop(self.find_registry, key, description) self.props_section_title = title_text - for effect in registry: - if key in effect["properties"]: - effect["properties"][key]["markdownDescription"] = description - self.props = self.find_props(effect["properties"][key]) - return - raise ValueError("Cannot find Effect " + title_text) - if title_text == PIN_CONFIGURATION_VARIABLES: self.multi_component = [] if self.app.jschema["definitions"].get(f"PIN.INPUT_{self.path[-1]}"): @@ -517,6 +542,16 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): f'Found a "{PIN_CONFIGURATION_VARIABLES}" entry but could not find pin schema' ) + def find_registry_prop(self, registry_name, key, description): + registry = self.app.jschema["definitions"][registry_name]["anyOf"] + for item in registry: + if key in item["properties"]: + item["properties"][key]["markdownDescription"] = description + self.props = self.find_props(item["properties"][key]) + + return + raise ValueError(f"Cannot find {registry_name} {key}") + def depart_title(self, node): if self.filled_props: self.filled_props = False @@ -663,6 +698,25 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): paragraph = list(node.traverse(nodes.paragraph))[0] markdown = self.getMarkdown(paragraph) + param_type = None + # Check if there is type information for this item + try: + name_type = markdown[: markdown.index(": ") + 2] + ntr = re.search( + r"(\(((\*\*Required\*\*)|(\*Optional\*))(,\s(.*))*)\):\s", + name_type, + re.IGNORECASE, + ) + if ntr: + param_type = ntr.group(6) + if param_type: + markdown = ( + f"**{param_type}**: {markdown[markdown.index(': ') + 2 :]}" + ) + except ValueError: + # ': ' not found + pass + title = list(node.traverse(nodes.title))[0] if len(title) > 0: url = urllib.parse.urljoin( @@ -696,9 +750,6 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): # **name** (*Optional*, string): Long Description... Defaults to ``value``. # **name** (*Optional*): Long Description... Defaults to ``value``. - if "ads111" in self.docname: - self.docname = self.docname - ntr = re.search( r"\* \*\*(\w*)\*\*\s(\(((\*\*Required\*\*)|(\*Optional\*))(,\s(.*))*)\):\s", name_type, @@ -765,7 +816,7 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): desc = markdown[markdown.index(": ") + 2 :].strip() if param_type: - desc = param_type + ": " + desc + desc = "**" + param_type + "**: " + desc jprop["markdownDescription"] = desc global props_documented @@ -780,6 +831,8 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): def find_component(self, component_path): path = component_path.split("/") + if path[0] not in ("properties", "definitions"): + return None json_component = self.app.jschema[path[0]][path[1]] if len(path) > 2: @@ -897,32 +950,6 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor): self.current_prop = None return props - return - # find properties - if "then" in component: - component = component["then"] - props = component.get("properties") - ref = None - if not props: - arr = component.get("anyOf", component.get("allOf")) - if not arr: - if "$ref" in component: - return self.find_props(self.get_ref(component)) - return None - for x in arr: - props = x.get("properties") - if not ref: - ref = self.get_ref(x) - if props: - break - if not props and ref: - props = self.find_props(ref) - - if props: - self.filled_props = False - self.accept_props = False - self.current_prop = None - return props def handle_component(app, doctree, docname):