def _directive_helper(self, obj, content=None, arguments=None, **options): if isinstance(obj, (types.FunctionType, types.MethodType)): obj.content = content obj.arguments = arguments or (0, 0, False) obj.options = options return convert_directive_function(obj) else: if content or arguments or options: raise ExtensionError("when adding directive classes, no " "additional arguments may be given") return obj
def run(self): """Dynamically create and register a custom interpreted text role.""" if self.content_offset > self.lineno or not self.content: raise self.error('"%s" directive requires arguments on the first ' 'line.' % self.name) args = self.content[0] match = self.argument_pattern.match(args) if not match: raise self.error('"%s" directive arguments not valid role names: ' '"%s".' % (self.name, args)) new_role_name = match.group(1) base_role_name = match.group(3) messages = [] if base_role_name: base_role, messages = roles.role(base_role_name, self.state_machine.language, self.lineno, self.state.reporter) if base_role is None: error = self.state.reporter.error( 'Unknown interpreted text role "%s".' % base_role_name, nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return messages + [error] else: base_role = roles.generic_custom_role assert not hasattr(base_role, 'arguments'), ( 'Supplemental directive arguments for "%s" directive not ' 'supported (specified by "%r" role).' % (self.name, base_role)) try: converted_role = convert_directive_function(base_role) (arguments, options, content, content_offset) = (self.state.parse_directive_block( self.content[1:], self.content_offset, converted_role, option_presets={})) except states.MarkupError as detail: error = self.state_machine.reporter.error( 'Error in "%s" directive:\n%s.' % (self.name, detail), nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return messages + [error] if 'class' not in options: try: options['class'] = directives.class_option(new_role_name) except ValueError as detail: error = self.state_machine.reporter.error( 'Invalid argument for "%s" directive:\n%s.' % (self.name, SafeString(detail)), nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return messages + [error] role = roles.CustomRole(new_role_name, base_role, options, content) roles.register_local_role(new_role_name, role) return messages
def _directive_helper(self, obj, content=None, arguments=None, **options): if isinstance(obj, (types.FunctionType, types.MethodType)): obj.content = content obj.arguments = arguments or (0, 0, False) obj.options = options return convert_directive_function(obj) else: if content or arguments or options: raise ExtensionError('when adding directive classes, no ' 'additional arguments may be given') return obj
def _directive_helper(self, obj, content=None, arguments=None, **options): # type: (Any, unicode, Any, Any) -> Any if isinstance(obj, (types.FunctionType, types.MethodType)): obj.content = content # type: ignore obj.arguments = arguments or (0, 0, False) # type: ignore obj.options = options # type: ignore return convert_directive_function(obj) else: if content or arguments or options: raise ExtensionError('when adding directive classes, no ' 'additional arguments may be given') return obj
def directive_helper(obj, has_content=None, argument_spec=None, **option_spec): # type: (Any, bool, Tuple[int, int, bool], Any) -> Any if isinstance(obj, (types.FunctionType, types.MethodType)): obj.content = has_content # type: ignore obj.arguments = argument_spec or (0, 0, False) # type: ignore obj.options = option_spec # type: ignore return convert_directive_function(obj) else: if has_content or argument_spec or option_spec: raise ExtensionError(__('when adding directive classes, no ' 'additional arguments may be given')) return obj
def run(self): """Dynamically create and register a custom interpreted text role.""" if self.content_offset > self.lineno or not self.content: raise self.error('"%s" directive requires arguments on the first ' 'line.' % self.name) args = self.content[0] match = self.argument_pattern.match(args) if not match: raise self.error('"%s" directive arguments not valid role names: ' '"%s".' % (self.name, args)) new_role_name = match.group(1) base_role_name = match.group(3) messages = [] if base_role_name: base_role, messages = roles.role( base_role_name, self.state_machine.language, self.lineno, self.state.reporter) if base_role is None: error = self.state.reporter.error( 'Unknown interpreted text role "%s".' % base_role_name, nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return messages + [error] else: base_role = roles.generic_custom_role assert not hasattr(base_role, 'arguments'), ( 'Supplemental directive arguments for "%s" directive not ' 'supported (specified by "%r" role).' % (self.name, base_role)) try: converted_role = convert_directive_function(base_role) (arguments, options, content, content_offset) = ( self.state.parse_directive_block( self.content[1:], self.content_offset, converted_role, option_presets={})) except states.MarkupError as detail: error = self.state_machine.reporter.error( 'Error in "%s" directive:\n%s.' % (self.name, detail), nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return messages + [error] if 'class' not in options: try: options['class'] = directives.class_option(new_role_name) except ValueError as detail: error = self.state_machine.reporter.error( 'Invalid argument for "%s" directive:\n%s.' % (self.name, SafeString(detail)), nodes.literal_block( self.block_text, self.block_text), line=self.lineno) return messages + [error] role = roles.CustomRole(new_role_name, base_role, options, content) roles.register_local_role(new_role_name, role) return messages
def run(self): """Dynamically create and register a custom interpreted text template.""" try: new_role_name = self.arguments[0] except ValueError: raise self.error('Missing template name for directive: "%s".' % (self.name)) messages = [] base_role = roles.raw_role converted_role = convert_directive_function(base_role) role = CustomTemplate(new_role_name, base_role, self.options) roles.register_local_role(new_role_name, role) return messages
def directive_helper(obj: Any, has_content: bool = None, argument_spec: Tuple[int, int, bool] = None, **option_spec) -> Any: # NOQA warnings.warn('function based directive support is now deprecated. ' 'Use class based directive instead.', RemovedInSphinx30Warning) if isinstance(obj, (types.FunctionType, types.MethodType)): obj.content = has_content # type: ignore obj.arguments = argument_spec or (0, 0, False) # type: ignore obj.options = option_spec # type: ignore return convert_directive_function(obj) else: if has_content or argument_spec or option_spec: raise ExtensionError(__('when adding directive classes, no ' 'additional arguments may be given')) return obj
def directive_helper(obj, has_content=None, argument_spec=None, **option_spec): # type: (Any, bool, Tuple[int, int, bool], Any) -> Any warnings.warn('function based directive support is now deprecated. ' 'Use class based directive instead.', RemovedInSphinx30Warning) if isinstance(obj, (types.FunctionType, types.MethodType)): obj.content = has_content # type: ignore obj.arguments = argument_spec or (0, 0, False) # type: ignore obj.options = option_spec # type: ignore return convert_directive_function(obj) else: if has_content or argument_spec or option_spec: raise ExtensionError(__('when adding directive classes, no ' 'additional arguments may be given')) return obj
def run_directive(self, directive, match, type_name, option_presets): """ Parse a directive then run its directive function. Parameters: - `directive`: The class implementing the directive. Must be a subclass of `rst.Directive`. - `match`: A regular expression match object which matched the first line of the directive. - `type_name`: The directive name, as used in the source text. - `option_presets`: A dictionary of preset options, defaults for the directive options. Currently, only an "alt" option is passed by substitution definitions (value: the substitution name), which may be used by an embedded image directive. Returns a 2-tuple: list of nodes, and a "blank finish" boolean. """ if isinstance(directive, (FunctionType, MethodType)): from docutils.parsers.rst import convert_directive_function directive = convert_directive_function(directive) lineno = self.state_machine.abs_line_number() initial_line_offset = self.state_machine.line_offset ( indented, indent, line_offset, blank_finish, ) = self.state_machine.get_first_known_indented(match.end(), strip_top=0) block_text = "\n".join( self.state_machine. input_lines[initial_line_offset:self.state_machine.line_offset + 1]) try: arguments, options, content, content_offset = self.parse_directive_block( indented, line_offset, directive, option_presets) except states.MarkupError as detail: error = self.reporter.error( 'Error in "%s" directive:\n%s.' % (type_name, " ".join(detail.args)), nodes.literal_block(block_text, block_text), line=lineno, ) return [error], blank_finish directive_instance = directive( type_name, arguments, options, content, lineno, content_offset, block_text, self, self.state_machine, ) try: result = directive_instance.run() except DirectiveError as error: msg_node = self.reporter.system_message(error.level, error.msg, line=lineno) msg_node += nodes.literal_block(block_text, block_text) result = [msg_node] assert isinstance( result, list), ('Directive "%s" must return a list of nodes.' % type_name) for i in range(len(result)): assert isinstance(result[i], nodes.Node), ( 'Directive "%s" returned non-Node object (index %s): %r' % (type_name, i, result[i])) # NOTE it would be ideal to also record the start and end characters on lines? # However, it appears that nested state machine are initalised with # pre de-dented input lines, and do not record the initial indentation position = LSPDirective( rawsource=block_text, line_start=line_offset, line_end=self.state_machine.abs_line_number() - 1, # the line at which content starts line_content=content_offset if content else None, content_indent=indent if content else None, # relative to initial indent of directive dtype=type_name, arguments=arguments, options=options, klass=f"{directive.__module__}.{directive.__name__}", children=result, ) return (position, blank_finish or self.state_machine.is_next_line_blank())