Ejemplo n.º 1
0
def parse_commands(body_text):
    ast = gfm.parse(body_text)
    for para in ast.children:
        # This makes us ignore commands inside blockquotes, lists, code
        # blocks, etc.
        if not isinstance(para, marko.block.Paragraph):
            continue

        # Within a paragraph, we want to find RawText chunks that cover an
        # entire line. So they should start/end with the edge of the paragraph
        # *or* a LineBreak. In commonmark, there's a distinction between
        # "soft" and "hard" line breaks, but in practice github seems to
        # render both of them as hard line breaks, so we don't bother
        # distinguishing.
        def is_line_boundary(i):
            if i < 0:
                return True
            if i >= len(para.children):
                return True
            if isinstance(para.children[i], marko.inline.LineBreak):
                return True
            return False

        for i, child in enumerate(para.children):
            if (
                is_line_boundary(i - 1)
                and is_line_boundary(i + 1)
                and isinstance(child, marko.inline.RawText)
            ):
                line = child.children.strip()
                if line.startswith("/"):
                    yield line.split()
Ejemplo n.º 2
0
 def collect(self):
     examples = lisp_examples(gfm.parse(slurp(self.fspath)))
     for index, example in enumerate(examples):
         yield ReadmeItem.from_parent(
             self,
             name=str(index + 1),
             code=example['code'],  # mandatory
             output=example.get('output'),  # might not be present
         )
Ejemplo n.º 3
0
def get_spec(file_name: Path, preset: Dict[str, str],
             config: Dict[str, str]) -> SpecObject:
    functions: Dict[str, str] = {}
    protocols: Dict[str, ProtocolDefinition] = {}
    constant_vars: Dict[str, VariableDefinition] = {}
    preset_vars: Dict[str, VariableDefinition] = {}
    config_vars: Dict[str, VariableDefinition] = {}
    ssz_dep_constants: Dict[str, str] = {}
    ssz_objects: Dict[str, str] = {}
    dataclasses: Dict[str, str] = {}
    custom_types: Dict[str, str] = {}

    with open(file_name) as source_file:
        document = gfm.parse(source_file.read())

    current_name = None
    should_skip = False
    for child in document.children:
        if isinstance(child, BlankLine):
            continue
        if should_skip:
            should_skip = False
            continue
        if isinstance(child, Heading):
            current_name = _get_name_from_heading(child)
        elif isinstance(child, FencedCode):
            if child.lang != "python":
                continue
            source = _get_source_from_code_block(child)
            if source.startswith("def"):
                current_name = _get_function_name_from_source(source)
                self_type_name = _get_self_type_from_source(source)
                function_def = "\n".join(line.rstrip()
                                         for line in source.splitlines())
                if self_type_name is None:
                    functions[current_name] = function_def
                else:
                    if self_type_name not in protocols:
                        protocols[self_type_name] = ProtocolDefinition(
                            functions={})
                    protocols[self_type_name].functions[
                        current_name] = function_def
            elif source.startswith("@dataclass"):
                dataclasses[current_name] = "\n".join(
                    line.rstrip() for line in source.splitlines())
            elif source.startswith("class"):
                class_name, parent_class = _get_class_info_from_source(source)
                # check consistency with spec
                assert class_name == current_name
                if parent_class:
                    assert parent_class == "Container"
                # NOTE: trim whitespace from spec
                ssz_objects[current_name] = "\n".join(
                    line.rstrip() for line in source.splitlines())
            else:
                raise Exception("unrecognized python code element")
        elif isinstance(child, Table):
            for row in child.children:
                cells = row.children
                if len(cells) >= 2:
                    name_cell = cells[0]
                    name = name_cell.children[0].children

                    value_cell = cells[1]
                    value = value_cell.children[0].children
                    if isinstance(value, list):
                        # marko parses `**X**` as a list containing a X
                        value = value[0].children

                    if not _is_constant_id(name):
                        # Check for short type declarations
                        if value.startswith("uint") or value.startswith(
                                "Bytes") or value.startswith("ByteList"):
                            custom_types[name] = value
                        continue

                    if value.startswith("get_generalized_index"):
                        ssz_dep_constants[name] = value
                        continue

                    value_def = _parse_value(name, value)
                    if name in preset:
                        preset_vars[name] = VariableDefinition(
                            value_def.type_name, preset[name],
                            value_def.comment)
                    elif name in config:
                        config_vars[name] = VariableDefinition(
                            value_def.type_name, config[name],
                            value_def.comment)
                    else:
                        constant_vars[name] = value_def

        elif isinstance(child, LinkRefDef):
            comment = _get_eth2_spec_comment(child)
            if comment == "skip":
                should_skip = True

    return SpecObject(
        functions=functions,
        protocols=protocols,
        custom_types=custom_types,
        constant_vars=constant_vars,
        preset_vars=preset_vars,
        config_vars=config_vars,
        ssz_dep_constants=ssz_dep_constants,
        ssz_objects=ssz_objects,
        dataclasses=dataclasses,
    )