def process_only_nodes(doctree, tags): # type: (nodes.Node, Tags) -> None # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... warnings.warn( 'process_only_nodes() is deprecated. ' 'Use sphinx.environment.apply_post_transforms() instead.', RemovedInSphinx17Warning) for node in doctree.traverse(addnodes.only): try: ret = tags.eval_condition(node['expr']) except Exception as err: logger.warning( 'exception while evaluating only directive expression: %s', err, location=node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: node.replace_self(nodes.comment())
def process_only_nodes(config, document, tags): # type: (nodes.Node, Tags) -> None """Filter ``only`` nodes which does not match *tags* or html (through config)""" ret_html_cell = config['jupyter_allow_html_only'] for node in document.traverse(addnodes.only): try: ret = tags.eval_condition(node['expr']) #check for jupyter only if ret_html_cell and node[ 'expr'] == 'html': #allow html only cells if option is specified ret = True except Exception as err: logger.warning( __('exception while evaluating only directive expression: %s'), err, location=node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... node.replace_self(nodes.comment())
def html2Docutils(app, doctree): #find all raw nodes if not app.env.config.sphinx_md_processRaw: return filepath = doctree['source'] htmlCounter = 0 for node in doctree.traverse(nodes.raw): soup = BeautifulSoup(node.astext(), features="html.parser") if soup.find(): if soup.find().name in known_start_tags: #send it to converter div = nodes.container() div['id'] = 'html-content-' + str(htmlCounter) htmlCounter += 1 convertHTML(soup, div, app, filepath) parent = node.parent parent.replace(node, div.children) #replace raw node with output of converter #child = nodes.Text("poof") #node[0]=child elif soup.find().name == hidden_tag: hidden_comment = nodes.comment() comment_text = nodes.Text("hidden") hidden_comment.append(comment_text) parent = node.parent parent.replace(node, hidden_comment)
def run(self): env = self.state.document.settings.env # Default language language = self.options.get('language') # Build the file text cwd = self.options.get('cwd', self.default_cwd) # Get the filename, possibly from first line of contents fname_raw, content = self.get_filename() file_content = u'\n'.join(content) + '\n' # Write the file if not fname_raw.startswith('/'): if cwd == '/': fname_sphinx = cwd + fname_raw else: fname_sphinx = cwd + '/' + fname_raw else: fname_sphinx = fname_raw _, fname = env.relfn2path(fname_sphinx) with open(fname, 'wt') as fobj: fobj.write(file_content) if 'hide' in self.options: return [nodes.comment(file_content, file_content)] literal = nodes.literal_block(file_content, file_content) literal['language'] = (self.options['highlighter'] if 'highlighter' in self.options else 'none' if language is None else language) literal['linenos'] = 'linenos' in self.options para = FileContents() para += nodes.emphasis(text='Contents of ') para += nodes.literal(text=fname_raw) para += literal return [para]
def run(self): name = self.arguments.pop(0) params = self.run_prepare() value = params.out.strip() self.add_var(name, value) self.add_links({name: value}) code = u'\n'.join(self.content) return [nodes.comment(code, code)]
def process_only_nodes(document: Node, tags: "Tags") -> None: """Filter ``only`` nodes which do not match *tags*.""" for node in document.findall(addnodes.only): try: ret = tags.eval_condition(node['expr']) except Exception as err: logger.warning(__('exception while evaluating only directive expression: %s'), err, location=node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... node.replace_self(nodes.comment())
def apply(self): # type: () -> None # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... for node in self.document.traverse(addnodes.only): try: ret = self.app.builder.tags.eval_condition(node['expr']) except Exception as err: logger.warning('exception while evaluating only directive expression: %s', err, location=node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: node.replace_self(nodes.comment())
def run(self): env = self.state.document.settings.env config = AutoRun.config try: language = self.arguments[0] except IndexError: language = 'bash' print 'opts', self.options if language not in config: raise RunBlockError('Unknown language %s' % language) # Get configuration values for the language args = config[language].split() input_encoding = config.get(language + '_input_encoding', 'ascii') output_encoding = config.get(language + '_output_encoding', 'ascii') prefix_chars = config.get(language + '_prefix_chars', 0) show_source = config.get(language + '_show_source', True) prompt_prefix = config.get(language + '_prompt_prefix', '') # Build the code text _, cwd = env.relfn2path(self.options.get('cwd', '/')) proc = Popen(args, bufsize=1, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd) codelines = (line[prefix_chars:] for line in self.content) code = u'\n'.join(codelines).encode(input_encoding) # Run the code stdout, stderr = proc.communicate(code) # Process output if stdout: out = ''.join(stdout).decode(output_encoding) elif stderr: out = ''.join(stderr).decode(output_encoding) else: out = '' # Get the original code with prefixes if show_source: code = prompt_prefix + (u'\n' + prompt_prefix).join(self.content) else: code = '' code_out = u'\n'.join((code, out)) if 'hide' in self.options: return [nodes.comment(code_out, code_out)] literal = nodes.literal_block(code_out, code_out) literal['language'] = language literal['linenos'] = 'linenos' in self.options return [literal]
def setUp(self): source = join(dirname(__file__), 'doc', 'doctree.rst') with open(source, 'r', encoding='utf-8') as rst: self.doctree = publish_doctree(rst.read()) self.node = self.doctree.next_node(self._matches_node_i) self.node_addresses = [ (nodes.section(), ()), (nodes.paragraph(), ()), (nodes.comment(), ()), (nodes.Text('text'), ())]
def crawl_toc(node): crawled[node] = True for j, subnode in enumerate(node): try: if 'remove-node' in subnode['classes']: subnode.replace_self(nodes.comment()) except Exception: continue if subnode not in crawled: crawl_toc(subnode)
def process_only_nodes(document, tags): # type: (nodes.Node, Tags) -> None """Filter ``only`` nodes which does not match *tags*.""" for node in document.traverse(addnodes.only): try: ret = tags.eval_condition(node['expr']) except Exception as err: logger.warning(__('exception while evaluating only directive expression: %s'), err, location=node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... node.replace_self(nodes.comment())
def process_only_nodes(doctree, tags, warn_node=None): # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... for node in doctree.traverse(addnodes.only): try: ret = tags.eval_condition(node['expr']) except Exception as err: if warn_node is None: raise err warn_node('exception while evaluating only ' 'directive expression: %s' % err, node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: node.replace_self(nodes.comment())
def run(self): self.bridge = DocumenterBridge(self.env, self.state.document.reporter, Options(), self.lineno, self.state) names = [ x.strip().split()[0] for x in self.content if x.strip() and re.search(r'^[~a-zA-Z_]', x.strip()[0]) ] items = self.get_items(names) tablenodes = self.get_table(items) if 'toctree' in self.options: dirname = posixpath.dirname(self.env.docname) tree_prefix = self.options['toctree'].strip() docnames = [] excluded = Matcher(self.config.exclude_patterns) filename_map = self.config.autosummary_filename_map for name, sig, summary, real_name in items: real_name = filename_map.get(real_name, real_name.replace('::', '.')) docname = posixpath.join(tree_prefix, real_name) docname = posixpath.normpath(posixpath.join(dirname, docname)) if docname not in self.env.found_docs: if excluded(self.env.doc2path(docname, None)): msg = __( 'autosummary references excluded document %r. Ignored.' ) else: msg = __('autosummary: stub file not found %r. ' 'Check your autosummary_generate setting.') logger.warning(msg, real_name) continue docnames.append(docname) if docnames: tocnode = addnodes.toctree() tocnode['includefiles'] = docnames tocnode['entries'] = [(None, docn) for docn in docnames] tocnode['maxdepth'] = -1 tocnode['glob'] = None tocnode['caption'] = self.options.get('caption') tablenodes.append(nodes.comment('', '', tocnode)) if 'toctree' not in self.options and 'caption' in self.options: logger.warning(__( 'A captioned autosummary requires :toctree: option. ignored.'), location=tablenodes[-1]) return tablenodes
def run(self): name = self.arguments.pop(0) self.run_prepare() value = self.params.out.strip() var_type = self.options.get('var_type', 'common') self.add_typed_var(name, value, var_type) literal = not 'not-literal' in self.options if 'omit_link' not in self.options: self.add_links({name: value}, literal=literal) code = u'\n'.join(self.content) return [nodes.comment(code, code)]
def process_only_nodes(doctree, tags, warn_node=None): # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... for node in doctree.traverse(addnodes.only): try: ret = tags.eval_condition(node['expr']) except Exception as err: if warn_node is None: raise err warn_node( 'exception while evaluating only ' 'directive expression: %s' % err, node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: node.replace_self(nodes.comment())
def run(self): env = self.state.document.settings.env config = AutoRun.config try: language = self.arguments[0] except IndexError: language = 'bash' print 'opts', self.options if language not in config: raise RunBlockError('Unknown language %s' % language) # Get configuration values for the language args = config[language].split() input_encoding = config.get(language+'_input_encoding','ascii') output_encoding = config.get(language+'_output_encoding','ascii') prefix_chars = config.get(language+'_prefix_chars', 0) show_source = config.get(language+'_show_source', True) prompt_prefix = config.get(language+'_prompt_prefix', '') # Build the code text _, cwd = env.relfn2path(self.options.get('cwd', '/')) proc = Popen(args,bufsize=1,stdin=PIPE,stdout=PIPE,stderr=PIPE, cwd=cwd) codelines = (line[prefix_chars:] for line in self.content) code = u'\n'.join(codelines).encode(input_encoding) # Run the code stdout, stderr = proc.communicate(code) # Process output if stdout: out = ''.join(stdout).decode(output_encoding) elif stderr: out = ''.join(stderr).decode(output_encoding) else: out = '' # Get the original code with prefixes if show_source: code = prompt_prefix + (u'\n' + prompt_prefix).join(self.content) else: code = '' code_out = u'\n'.join((code,out)) if 'hide' in self.options: return [nodes.comment(code_out, code_out)] literal = nodes.literal_block(code_out, code_out) literal['language'] = language literal['linenos'] = 'linenos' in self.options return [literal]
def process_only_nodes(doctree, tags): # type: (nodes.Node, Tags) -> None # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to # something, even if it's just a comment and will lose the id anyway... warnings.warn('process_only_nodes() is deprecated. ' 'Use sphinx.environment.apply_post_transforms() instead.', RemovedInSphinx17Warning) for node in doctree.traverse(addnodes.only): try: ret = tags.eval_condition(node['expr']) except Exception as err: logger.warning('exception while evaluating only directive expression: %s', err, location=node) node.replace_self(node.children or nodes.comment()) else: if ret: node.replace_self(node.children or nodes.comment()) else: node.replace_self(nodes.comment())
def run(self): params = self.run_prepare() # Get the original code with prefixes if params.show_source: code = params.prompt_prefix + ( u'\n' + params.prompt_prefix).join(self.content) else: code = '' code_out = u'\n'.join((code, params.out)) # Do env substitution code_out = subst_vars(code_out, self._get_env_vars()) # Make nodes if 'hide' in self.options: return [nodes.comment(code_out, code_out)] literal = nodes.literal_block(code_out, code_out) literal['language'] = params.language literal['linenos'] = 'linenos' in self.options return [literal]
def run(self): # Set default options self.set_opt_defaults() self._prepare() # Run code, collect output if not 'dont-run' in self.options: self._run_prepared() if ('allow-fail' not in self.options and self.params.returncode != 0): raise RuntimeError( 'Command {} failed with {} in doc {}'.format( self.params.exe_code, self.params.out, self.state.document['source'])) params = self.params # Get the original code with prefixes if params.show_source: code = params.prompt_prefix + ( u'\n' + params.prompt_prefix).join(self.content) else: code = '' # Do post-run env substitution on code code = subst_vars(code, self.get_typed_vars('render')) # Do output post-processing out = self.process_out() # String for rendering code_out = u'\n'.join((code, out)) if 'hide-code' in self.options: contents = out elif 'hide-out' in self.options: contents = code else: contents = code_out # Make nodes if 'hide' in self.options: return [nodes.comment(code_out, code_out)] literal = nodes.literal_block(contents, contents) literal['language'] = (self.options['highlighter'] if 'highlighter' in self.options else params.language) literal['linenos'] = 'linenos' in self.options return [literal]
def run(self): table_code, test_code = CodeDiffParser().parse(list(self.content), **self.options) # Create a test node as a comment node so it won't show up in the docs. # We add attribute "testnodetype" so it is be picked up by the doctest # builder. This functionality is not officially documented but can be found # in the source code: # https://github.com/sphinx-doc/sphinx/blob/3.x/sphinx/ext/doctest.py # (search for 'testnodetype'). test_code = '\n'.join(test_code) test_node = nodes.comment(test_code, test_code, testnodetype='testcode') # Set the source info so the error message is correct when testing. self.set_source_info(test_node) test_node['options'] = {} test_node['language'] = 'python3' # The table node is the side-by-side diff view that will be shown on RTD. table_node = nodes.paragraph() self.content = ViewList(table_code, self.content.parent) self.state.nested_parse(self.content, self.content_offset, table_node) return [table_node, test_node]
def apply(self): pending = self.startnode parent = pending.parent child = pending # Check for appropriate following siblings: for index in range(parent.index(child) + 1, len(parent)): element = parent[index] if isinstance(element, nodes.Invisible) or isinstance(element, nodes.system_message): continue parent.remove(pending) # the directive itself parent.remove(element) # next element if len(parent.children) == 0: parent.append(nodes.comment(text="hidden")) return error = self.document.reporter.error( 'No suitable element following "%s" directive' % pending.details["directive"], nodes.literal_block(pending.rawsource, pending.rawsource), line=pending.line, ) pending.parent.replace(pending, error)
def run(self): env = self.state.document.settings.env # Build the file text cwd = self.options.get('cwd', self.default_cwd) # Get the filename file_prefix = self.options.get('file_prefix', self.default_file_prefix) line0 = self.content[0] if not line0.startswith(file_prefix): raise WriteFileError('First line should begin with ' + file_prefix) fname_sphinx = line0[len(file_prefix):].strip() page_content = u'\n'.join(self.content) + '\n' file_content = u'\n'.join(self.content[1:]) + '\n' # Write the file if not fname_sphinx.startswith('/'): fname_sphinx = cwd + '/' + fname_sphinx _, fname = env.relfn2path(fname_sphinx) with open(fname, 'wt') as fobj: fobj.write(file_content) if 'hide' in self.options: return [nodes.comment(page_content, page_content)] literal = nodes.literal_block(page_content, page_content) literal['linenos'] = 'linenos' in self.options return [literal]
def run(self): self.assert_has_content() # On error, you can ``raise self.error('Error message.')`` # You have access to all arguments and options # self.arguments # self.options print(self.arguments) # the content following directive print(self.options) print( self.content ) # List with each line of the content (text on lines after initial directive call) # You can return one or more nodes that will be inserted at the # location where the directive was called. The output format # will depend on the translator/writer that is used after # the parser is done reading and calling all directives to generate # the node tree. comment_node = nodes.comment(text="Section generated by " + __file__) warning_node = nodes.warning() text_node = nodes.Text("Who dares call my custom directive!?") line_node = nodes.transition() # You could simply return the nodes as a list # return [comment_node, line_node, text_node] # But, if you want to wrap multiple nodes up in a section with # a special class name, create a section and put the nodes in it. # This will wrap them with a <div class="section"> w/ html5 writer section_node = nodes.section() section_node['classes'] = ['my-custom-css-class', 'another-style'] section_node.append(comment_node) section_node.append(warning_node) section_node.append(text_node) section_node.append(line_node) return [section_node]
def render_myst_block_break(self, token): block_break = nodes.comment(token.content, token.content) block_break["classes"] += ["block_break"] self.add_line_and_source_path(block_break, token) self.current_node.append(block_break)
def plugin_links_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): return [nodes.comment('', 'PLUGIN_LINKS')]
def render_myst_line_comment(self, token: SyntaxTreeNode) -> None: self.current_node.append( nodes.comment(token.content, token.content.strip()))
def render_myst_line_comment(self, token): self.current_node.append(nodes.comment(token.content, token.content))
def roundOffTableDefinition(self): u"""Round off the table definition. This method rounds off the table definition in :py:member:`rows`. * This method inserts the needed ``None`` values for the missing cells arising from spanning cells over rows and/or columns. * recount the :py:member:`max_cols` * Autospan or fill (option ``fill-cells``) missing cells on the right side of the table-row """ y = 0 while y < len(self.rows): x = 0 while x < len(self.rows[y]): cell = self.rows[y][x] if cell is None: x += 1 continue cspan, rspan = cell[:2] # handle colspan in current row for c in range(cspan): try: self.rows[y].insert(x+c+1, None) except: # pylint: disable=W0702 # the user sets ambiguous rowspans pass # SDK.CONSOLE() # handle colspan in spanned rows for r in range(rspan): for c in range(cspan + 1): try: self.rows[y+r+1].insert(x+c, None) except: # pylint: disable=W0702 # the user sets ambiguous rowspans pass # SDK.CONSOLE() x += 1 y += 1 # Insert the missing cells on the right side. For this, first # re-calculate the max columns. for row in self.rows: if self.max_cols < len(row): self.max_cols = len(row) # fill with empty cells or cellspan? fill_cells = False if 'fill-cells' in self.directive.options: fill_cells = True for row in self.rows: x = self.max_cols - len(row) if x and not fill_cells: if row[-1] is None: row.append( ( x - 1, 0, []) ) else: cspan, rspan, content = row[-1] row[-1] = (cspan + x, rspan, content) elif x and fill_cells: for i in range(x): row.append( (0, 0, nodes.comment()) )