Example #1
0
def multi_choice (values, argument):
    """
    Checks a space-separated list of actual values against a list of approved values.
    Raises ValueError if it finds any value that is not in the list.
    Usage: option_spec = {'option' : functools.partial (multi_choice, list_of_values) }
    """
    entries = argument.split ()
    for e in entries:
        directives.choice (e, values)
    return entries
Example #2
0
def choice (values, argument):
    """
    Checks an actual value against a list of approved values.
    Raises ValueError if the value is not found in the list of values.
    Usage: option_spec = {'option' : functools.partial (choice, list_of_values) }
    """
    return directives.choice (argument, values)
Example #3
0
def lightbox_directive(name, arguments, options, content, lineno,
                       content_offset, block_text, state, state_machine):
    """
    lightbox image directive

    usage:

    .. lightbox:: thumb_url img_url

        Title
    """
    classes = ["lightbox-img"]
    if 'align' in options:
        directives.choice(options['align'], align_values)

        if isinstance(state, states.SubstitutionDef):
            # Check for align_v_values.
            if options['align'] not in align_v_values:
                raise DirectiveError(3,
                    'Error in "%s" directive: "%s" is not a valid value '
                    'for the "align" option within a substitution '
                    'definition.  Valid values for "align" are: "%s".'
                    % (name, options['align'],
                       '", "'.join(align_v_values)))
        elif options['align'] not in align_h_values:
            raise DirectiveError(3,
                'Error in "%s" directive: "%s" is not a valid value for '
                'the "align" option.  Valid values for "align" are: "%s".'
                % (name, options['align'],
                   '", "'.join(align_h_values)))

        classes.append('align-%s' % options['align'])

    thumb_href = arguments[0]
    img_href = arguments[1]
    title = u" ".join(content)
    alt = options.get('alt', '')

    html = '<a title="%(title)s" rel="lightbox" href="%(img_href)s"><img %(classes)s src="%(thumb_href)s" title="%(title)s" alt="%(alt)s"/></a>' % {
        "classes": 'class="%s"' % " ".join(classes) if classes else "",
        "title": title,
        "img_href": img_href,
        "thumb_href": thumb_href,
        "alt": alt,
    }
    return [nodes.raw("", html, format="html")]
Example #4
0
    def align(argument):
        """Convert and validate the :align: option.

        Args:
            argument: The argument passed to the :align: option.
        """
        # This is not callable as self.align.  We cannot make it a
        # staticmethod because we're saving an unbound method in
        # option_spec below.
        return directives.choice(argument, directives.images.Image.align_values)
Example #5
0
def check_samples_slot(value):
    """Validate the samples_slot option to the TypeDocumenter.

    Valid positions are 'before-docstring' and
    'after-docstring'. Using the explicit 'none' disables sample
    output. The default is after-docstring.
    """
    if not value:
        return 'after-docstring'
    val = directives.choice(
        value,
        ('none',              # do not include
         'before-docstring',  # show samples then docstring
         'after-docstring',   # show docstring then samples
         ))
    return val
Example #6
0
def metricunits(unitname):
    return directives.choice(
        unitname.lower(),
        (
            "ratio",
            "percent",
            "kbits",
            "mbits",
            "bytes",
            "kbytes",
            "mbytes",
            "nanoseconds",
            "microseconds",
            "milliseconds",
            "seconds",
        ),
    )
Example #7
0
    def run(self):
        name = self.arguments[0]
        command = directives.choice(self.arguments[1], allowed_commands)

        if command == 'init':
            # Create a temporary file to hold the database
            db_fh = tempfile.NamedTemporaryFile(delete = False)
            ehive_db_urls[name] = 'sqlite:///' + db_fh.name
            command_array = ['init_pipeline.pl', self.arguments[2], '-pipeline_url', ehive_db_urls[name]]
            for tweak in self.options.get('tweaks', '').split():
                command_array.extend(['-tweak', tweak])
        else:
            db = ehive_db_urls[name]
            if command == 'run_job':
                command_array = ['runWorker.pl', '-url', db, '-job_id', self.arguments[2]]

            elif command == 'sync':
                command_array = ['beekeeper.pl', '-url', db, '-sync']
                if self.options.has_key('analyses_pattern'):
                    command_array.extend(['-analyses_pattern', self.options['analyses_pattern']])

            elif command == 'analysis_diagram':
                default_config_file = os.environ["EHIVE_ROOT_DIR"] + os.path.sep + "hive_config.json"
                command_array = ['generate_graph.pl', '-url', db, '-output', '/dev/stdout', '-format', 'dot', '-config_file', default_config_file]

            elif command == 'job_diagram':
                default_config_file = os.environ["EHIVE_ROOT_DIR"] + os.path.sep + "hive_config.json"
                command_array = ['visualize_jobs.pl', '-url', db, '-output', '/dev/stdout', '-format', 'dot', '-config_file', default_config_file]
                command_array.extend(self.options.get('vj_options', '').split())

        command_array[0] = os.path.join(os.environ["EHIVE_ROOT_DIR"], 'scripts', command_array[0])
        dotcontent = subprocess.check_output(command_array, stderr=sys.stderr)

        if command.endswith('diagram'):
            # We reuse the graphviz node (from the graphviz extension) as it deals better with image formats vs builders
            graphviz_node = graphviz()
            graphviz_node['code'] = dotcontent
            graphviz_node['options'] = {}

            return [graphviz_node]
        else:
            return []
Example #8
0
class BokehPlotDirective(Directive):
    """
    Sphinx directive.
    """

    has_content = True
    optional_arguments = 2

    option_spec = {
        'source-position': lambda x: choice(x, ('below', 'above', 'none')),
        'linenos': lambda x: True if flag(x) is None else False,
    }

    def run(self):

        env = self.state.document.settings.env
        app = env.app

        # filename *or* python code content, but not both
        if self.arguments and self.content:
            raise SphinxError(
                "bokeh-plot:: directive can't have both args and content")

        # process inline examples here
        if self.content:
            app.debug("[bokeh-plot] handling inline example in %r",
                      env.docname)
            source = '\n'.join(self.content)
            # need docname not to look like a path
            docname = env.docname.replace("/", "-")
            js_name = "bokeh-plot-%s-inline-%s.js" % (docname, uuid4().hex)
            # the code runner just needs a real path to cd to, this will do
            path = join(env.bokeh_plot_auxdir, js_name)

            (script, js, js_path,
             source) = _process_script(source, path, env.bokeh_plot_auxdir,
                                       js_name)
            env.bokeh_plot_files[js_name] = (script, js, js_path, source)

        # process example files here
        else:
            example_path = self.arguments[0][:-3]  # remove the ".py"

            # if it's an "internal" example, the python parser has already handled it
            if example_path in env.bokeh_plot_files:
                app.debug("[bokeh-plot] handling internal example in %r: %s",
                          env.docname, self.arguments[0])
                (script, js, js_path,
                 source) = env.bokeh_plot_files[example_path]

            # handle examples external to the docs source, e.g. gallery examples
            else:
                app.debug("[bokeh-plot] handling external example in %r: %s",
                          env.docname, self.arguments[0])
                source = open(self.arguments[0]).read()
                source = decode_utf8(source)
                docname = env.docname.replace("/", "-")
                js_name = "bokeh-plot-%s-external-%s.js" % (docname,
                                                            uuid4().hex)
                (script, js, js_path,
                 source) = _process_script(source, self.arguments[0],
                                           env.bokeh_plot_auxdir, js_name)
                env.bokeh_plot_files[js_name] = (script, js, js_path, source)

        # use the source file name to construct a friendly target_id
        target_id = "%s.%s" % (env.docname, basename(js_path))
        target = nodes.target('', '', ids=[target_id])
        result = [target]

        linenos = self.options.get('linenos', False)
        code = nodes.literal_block(source,
                                   source,
                                   language="python",
                                   linenos=linenos,
                                   classes=[])
        set_source_info(self, code)

        source_position = self.options.get('source-position', 'below')

        if source_position == "above":
            result += [code]

        result += [nodes.raw('', script, format="html")]

        if source_position == "below":
            result += [code]

        return result
Example #9
0
def wmode(argument):
    """Conversion function for the "wmode" option."""
    return directives.choice(argument, ('window', 'opaque', 'transparent'))
Example #10
0
def choose_builders(arguments):
    return [directives.choice(argument, AVAILABLE_BUILDERS)
            for argument in arguments]
Example #11
0
 def align(argument):
     return directives.choice(argument, Figure.align_h_values)
def lhs_litstyle(argument):
    return directives.choice(argument, ('bird', 'latex'))
def yes_no_zero_one(argument):
    return directives.choice(argument, ('yes', 'no', '0', '1'))
Example #14
0
class ManimDirective(Directive):
    r"""The manim directive, rendering videos while building
    the documentation.

    See the module docstring for documentation.
    """
    has_content = True
    required_arguments = 1
    optional_arguments = 0
    option_spec = {
        "hide_source": bool,
        "quality": lambda arg: directives.choice(
            arg,
            ("low", "medium", "high", "fourk"),
        ),
        "save_as_gif": bool,
        "save_last_frame": bool,
        "ref_modules": lambda arg: process_name_list(arg, "mod"),
        "ref_classes": lambda arg: process_name_list(arg, "class"),
        "ref_functions": lambda arg: process_name_list(arg, "func"),
        "ref_methods": lambda arg: process_name_list(arg, "meth"),
    }
    final_argument_whitespace = True

    def run(self):
        # Rendering is skipped if the tag skip-manim is present,
        # or if we are making the pot-files
        should_skip = (
            "skip-manim" in self.state.document.settings.env.app.builder.tags.tags
            or self.state.document.settings.env.app.builder.name == "gettext"
        )
        if should_skip:
            node = SkipManimNode()
            self.state.nested_parse(
                StringList(
                    [
                        f"Placeholder block for ``{self.arguments[0]}``.",
                        "",
                        ".. code-block:: python",
                        "",
                    ]
                    + ["    " + line for line in self.content]
                ),
                self.content_offset,
                node,
            )
            return [node]

        from manim import config, tempconfig

        global classnamedict

        clsname = self.arguments[0]
        if clsname not in classnamedict:
            classnamedict[clsname] = 1
        else:
            classnamedict[clsname] += 1

        hide_source = "hide_source" in self.options
        save_as_gif = "save_as_gif" in self.options
        save_last_frame = "save_last_frame" in self.options
        assert not (save_as_gif and save_last_frame)

        ref_content = (
            self.options.get("ref_modules", [])
            + self.options.get("ref_classes", [])
            + self.options.get("ref_functions", [])
            + self.options.get("ref_methods", [])
        )
        if ref_content:
            ref_block = "References: " + " ".join(ref_content)

        else:
            ref_block = ""

        if "quality" in self.options:
            quality = f'{self.options["quality"]}_quality'
        else:
            quality = "example_quality"
        frame_rate = QUALITIES[quality]["frame_rate"]
        pixel_height = QUALITIES[quality]["pixel_height"]
        pixel_width = QUALITIES[quality]["pixel_width"]

        state_machine = self.state_machine
        document = state_machine.document

        source_file_name = Path(document.attributes["source"])
        source_rel_name = source_file_name.relative_to(setup.confdir)
        source_rel_dir = source_rel_name.parents[0]
        dest_dir = Path(setup.app.builder.outdir, source_rel_dir).absolute()
        if not dest_dir.exists():
            dest_dir.mkdir(parents=True, exist_ok=True)

        source_block = [
            ".. code-block:: python",
            "",
            "    from manim import *\n",
            *("    " + line for line in self.content),
        ]
        source_block = "\n".join(source_block)

        config.media_dir = (Path(setup.confdir) / "media").absolute()
        config.images_dir = "{media_dir}/images"
        config.video_dir = "{media_dir}/videos/{quality}"
        output_file = f"{clsname}-{classnamedict[clsname]}"
        config.assets_dir = Path("_static")
        config.progress_bar = "none"
        config.verbosity = "WARNING"

        example_config = {
            "frame_rate": frame_rate,
            "pixel_height": pixel_height,
            "pixel_width": pixel_width,
            "save_last_frame": save_last_frame,
            "write_to_movie": not save_last_frame,
            "output_file": output_file,
        }
        if save_last_frame:
            example_config["format"] = None
        if save_as_gif:
            example_config["format"] = "gif"

        user_code = self.content
        if user_code[0].startswith(">>> "):  # check whether block comes from doctest
            user_code = [
                line[4:] for line in user_code if line.startswith((">>> ", "... "))
            ]

        code = [
            "from manim import *",
            *user_code,
            f"{clsname}().render()",
        ]

        with tempconfig(example_config):
            run_time = timeit(lambda: exec("\n".join(code), globals()), number=1)
            video_dir = config.get_dir("video_dir")
            images_dir = config.get_dir("images_dir")

        _write_rendering_stats(
            clsname,
            run_time,
            self.state.document.settings.env.docname,
        )

        # copy video file to output directory
        if not (save_as_gif or save_last_frame):
            filename = f"{output_file}.mp4"
            filesrc = video_dir / filename
            destfile = Path(dest_dir, filename)
            shutil.copyfile(filesrc, destfile)
        elif save_as_gif:
            filename = f"{output_file}.gif"
            filesrc = video_dir / filename
        elif save_last_frame:
            filename = f"{output_file}.png"
            filesrc = images_dir / filename
        else:
            raise ValueError("Invalid combination of render flags received.")
        rendered_template = jinja2.Template(TEMPLATE).render(
            clsname=clsname,
            clsname_lowercase=clsname.lower(),
            hide_source=hide_source,
            filesrc_rel=Path(filesrc).relative_to(setup.confdir).as_posix(),
            output_file=output_file,
            save_last_frame=save_last_frame,
            save_as_gif=save_as_gif,
            source_block=source_block,
            ref_block=ref_block,
        )
        state_machine.insert_input(
            rendered_template.split("\n"),
            source=document.attributes["source"],
        )

        return []
Example #15
0
def showhide(argument):
  """Conversion function for the "showhide" option."""
  return directives.choice(argument, ('show', 'hide', 'none'))
Example #16
0
 def backlinks(arg):
     value = directives.choice(arg, Contents.backlinks_values)
     if value == 'none':
         return None
     else:
         return value
Example #17
0
def directive_truefalse(argument):
    return directives.choice(argument, ('true', 'false'))
Example #18
0
def metricunits(unitname):
    return directives.choice(
        unitname.lower(),
        ('ratio', 'percent', 'kbits', 'mbits', 'bytes', 'kbytes', 'mbytes',
         'nanoseconds', 'microseconds', 'milliseconds', 'seconds'))
Example #19
0
def metrictypes(typename):
    return directives.choice(
        typename.lower(), ('counter', 'gauge', 'derivative', 'flag', 'text'))
Example #20
0
def _option_graph2use(arg):
    return directives.choice(
        arg, ('hierarchical', 'colored', 'flat', 'orig', 'exec'))
Example #21
0
def align(argument):
    return directives.choice(argument, ('left', 'center', 'right'))
def _source_position(argument):
    return choice(argument, ('below', 'above', 'none'))
Example #23
0
def align(argument):
    """Conversion function for the "align" option."""
    return directives.choice(argument, ('left', 'center', 'right'))
Example #24
0
 def align(argument):
     return directives.choice(argument, ("left", "center", "right"))
Example #25
0
class PyReverse(Directive):
    """Runs pyreverse to generate UML for specified module name and options.

    The directive accepts the same arguments as pyreverse, except you should not specify
    ``--project`` or ``-o`` (output format). These are automatically specified.

    If you pass ``-c`` to this, the figure generated is forced to be the className.png
    like ``BurnMatrix.png``. For .gitignore purposes, this is a pain. Thus, we
    auto-prefix ALL images generated by this directive with ``pyrev_``.
    """

    has_content = True
    required_arguments = 1
    optional_arguments = 50
    option_spec = {
        "alt": directives.unchanged,
        "height": directives.length_or_percentage_or_unitless,
        "width": directives.length_or_percentage_or_unitless,
        "align": lambda arg: directives.choice(arg,
                                               ("left", "right", "center")),
        "filename": directives.unchanged,
    }

    def run(self):
        try:
            args = list(self.arguments)
            args.append("--project")
            args.append(f"{args[0]}")
            args.append("-opng")

            # cannot use "pylint.pyreverse.main.Run" because it calls `sys.exit`. why?
            fig_name = self.options.get("filename",
                                        "classes_{}.png".format(args[0]))
            command = [sys.executable, "-m", "pylint.pyreverse.main"]
            print("Running {}".format(command + args))
            env = dict(os.environ)
            # apply any runtime path mods to the pythonpath env variable (e.g. sys.path
            # mods made during doc confs)
            env["PYTHONPATH"] = os.pathsep.join(sys.path)
            subprocess.check_call(command + args, env=env)

            try:
                os.remove(os.path.join(APIDOC_DIR, fig_name))
            except:
                pass

            shutil.move(fig_name, APIDOC_DIR)
            # add .gitignore helper prefix
            shutil.move(
                os.path.join(APIDOC_DIR, fig_name),
                os.path.join(APIDOC_DIR, f"pyr_{fig_name}"),
            )
            new_content = [f".. figure:: /{APIDOC_DIR}/pyr_{fig_name}"]

            # assume we don't need the packages_, and delete.
            try:
                os.remove("packages_{}.png".format(args[0]))
            except:
                pass

            # pass the other args through (figure args like align)
            for opt, val in self.options.items():
                if opt in ("filename", ):
                    continue
                new_content.append("    :{}: {}\n".format(opt, val))

            new_content.append("\n")

            for line in self.content:
                new_content.append("    " + line)

            para = nodes.container()
            # tab_width = self.options.get('tab-width', self.state.document.settings.tab_width)
            lines = statemachine.StringList(new_content)
            self.state.nested_parse(lines, self.content_offset, para)
            return [para]
        except Exception as e:
            docname = self.state.document.settings.env.docname
            # add the error message directly to the built documentation and also tell the
            # builder
            raise self.error(
                "Unable to execute embedded doc code at {}:{} ... {}\n{}".
                format(docname, self.lineno, datetime.datetime.now(), str(e)))
Example #26
0
 def align(argument):
     return directives.choice(argument,
                              directives.images.Image.align_h_values)
Example #27
0
 def align(argument):
     return directives.choice(argument, Figure.align_h_values)
Example #28
0
def hide_title(argument):
    return directives.choice(argument, ("true", "false"))
def _option_align(arg):
    return directives.choice(arg, ("top", "middle", "bottom", "left", "center",
                                   "right"))
Example #30
0
def figure_align(argument):
    return directives.choice(argument, align_h_values)
Example #31
0
 def capalign(argument):
     # This is not callable as self.align.  We cannot make it a
     # staticmethod because we're saving an unbound method in
     # option_spec below.
     return directives.choice(
         argument, ['left', 'right', 'center', 'justify', 'inherit'])
Example #32
0
def bottom_right(argument):
    return directives.choice(argument, ('bottom', 'right'))
Example #33
0
def _option_language(arg):
    """
    Check language option.
    """
    return directives.choice(arg, ("bash", "python"))
Example #34
0
def nice_bool(arg):
    tvalues = ('true', 't', 'yes', 'y')
    fvalues = ('false', 'f', 'no', 'n')
    arg = directives.choice(arg, tvalues + fvalues)
    return arg in tvalues
def _option_context(arg):
    if arg in [None, 'reset']:
        return arg
    else:
        raise ValueError("argument should be None or 'reset'")
    return directives.choice(arg, ('None', 'reset'))
Example #36
0
def align_spec(argument):
    # type: (Any) -> bool
    return directives.choice(argument, ('left', 'center', 'right'))
Example #37
0
def align(argument):
    return directives.choice(argument, align_values)
Example #38
0
def rendered_block_choice(argument):
    return directives.choice(argument, RENDERED_BLOCK_CHOICES)
Example #39
0
def metrictypes(typename):
    return directives.choice(typename.lower(), ("counter", "gauge", "derivative", "flag", "text"))
Example #40
0
def output(argument):
    """Conversion function for the "output" option."""
    return directives.choice(argument, ('show', 'hide'))
def heading(argument):
    """ directives choices for heading tag """
    return directives.choice(argument, ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))
Example #42
0
def align(argument):
    """Conversion function for the "align" option."""
    return directives.choice(argument, ("left", "center", "right"))
Example #43
0
def _option_format(arg):
    return directives.choice(arg, ("python", "lisp"))
Example #44
0
def httpOption(argument):
    """Conversion function for the "http" option."""
    return directives.choice(argument, ("http", "https"))
Example #45
0
def boolean(argument):
    return directives.choice(argument, ('true', 'false'))
Example #46
0
def align(argument):
    """Conversion function for the "align" option."""
    return directives.choice(argument, ('left', 'center', 'right'))
Example #47
0
def align_spec(argument):
    # type: (Any) -> bool
    return directives.choice(argument, ('left', 'center', 'right'))
Example #48
0
def _option_format(arg):
    return directives.choice(arg, ('python', 'lisp'))
Example #49
0
def fontset_choice(arg):
    return directives.choice(arg, ['cm', 'stix', 'stixsans'])
Example #50
0
 def align(argument):
     # This is not callable as self.align.  We cannot make it a
     # staticmethod because we're saving an unbound method in
     # option_spec below.
     return directives.choice(argument, Image.align_values)
def csharp_unicodelevel(argument):
    return directives.choice(argument, ('none', 'basic', 'full'))
Example #52
0
 def align(argument):
     """Return thumbnail alignment."""
     return directives.choice(argument, Image.align_values)
def raw_compress(argument):
    return directives.choice(argument, ('gz', 'bz2'))
Example #54
0
def _option_format(arg):
    return directives.choice(arg, ('python', 'doctest'))
Example #55
0
 def align(argument):
     # This is not callable as self.align.  We cannot make it a
     # staticmethod because we're saving an unbound method in
     # option_spec below.
     return directives.choice(argument, Image.align_values)
Example #56
0
def _option_align(arg):
    return directives.choice(
        arg, ("top", "middle", "bottom", "left", "center", "right"))
def _option_format(arg):
    return directives.choice(arg, ('python', 'doctest'))
Example #58
0
def align_spec(argument):
    return directives.choice(argument, ('left', 'center', 'right'))
Example #59
0
def backlinks(arg):
    value = directives.choice(arg, backlinks_values)
    if value == 'none':
        return None
    else:
        return value
Example #60
0
class ManimDirective(Directive):
    r"""The manim directive, rendering videos while building
    the documentation.

    See the module docstring for documentation.
    """
    has_content = True
    required_arguments = 1
    optional_arguments = 0
    option_spec = {
        "hide_source":
        bool,
        "quality":
        lambda arg: directives.choice(arg, ("low", "medium", "high", "fourk")),
        "save_as_gif":
        bool,
        "save_last_frame":
        bool,
        "ref_modules":
        lambda arg: process_name_list(arg, "mod"),
        "ref_classes":
        lambda arg: process_name_list(arg, "class"),
        "ref_functions":
        lambda arg: process_name_list(arg, "func"),
        "ref_methods":
        lambda arg: process_name_list(arg, "meth"),
    }
    final_argument_whitespace = True

    def run(self):
        if "skip-manim" in self.state.document.settings.env.app.builder.tags.tags:
            node = skip_manim_node()
            self.state.nested_parse(StringList(self.content[0]),
                                    self.content_offset, node)
            return [node]

        from manim import config

        global classnamedict

        clsname = self.arguments[0]
        if clsname not in classnamedict:
            classnamedict[clsname] = 1
        else:
            classnamedict[clsname] += 1

        hide_source = "hide_source" in self.options
        save_as_gif = "save_as_gif" in self.options
        save_last_frame = "save_last_frame" in self.options
        assert not (save_as_gif and save_last_frame)

        ref_content = (self.options.get("ref_modules", []) +
                       self.options.get("ref_classes", []) +
                       self.options.get("ref_functions", []) +
                       self.options.get("ref_methods", []))
        if ref_content:
            ref_block = f"""
.. admonition:: Example References
    :class: example-reference

    {' '.join(ref_content)}"""
        else:
            ref_block = ""

        if "quality" in self.options:
            quality = f'{self.options["quality"]}_quality'
        else:
            quality = "example_quality"
        frame_rate = QUALITIES[quality]["frame_rate"]
        pixel_height = QUALITIES[quality]["pixel_height"]
        pixel_width = QUALITIES[quality]["pixel_width"]
        qualitydir = f"{pixel_height}p{frame_rate}"

        state_machine = self.state_machine
        document = state_machine.document

        source_file_name = document.attributes["source"]
        source_rel_name = relpath(source_file_name, setup.confdir)
        source_rel_dir = os.path.dirname(source_rel_name)
        while source_rel_dir.startswith(os.path.sep):
            source_rel_dir = source_rel_dir[1:]

        dest_dir = os.path.abspath(
            os.path.join(setup.app.builder.outdir, source_rel_dir))
        if not os.path.exists(dest_dir):
            os.makedirs(dest_dir)

        source_block = [
            ".. code-block:: python",
            "",
            *["    " + line for line in self.content],
        ]
        source_block = "\n".join(source_block)

        config.media_dir = Path(setup.confdir) / "media"
        config.images_dir = "{media_dir}/images"
        config.video_dir = "{media_dir}/videos/{quality}"
        output_file = f"{clsname}-{classnamedict[clsname]}"
        config.assets_dir = Path("_static")

        config_code = [
            f'config["frame_rate"] = {frame_rate}',
            f'config["pixel_height"] = {pixel_height}',
            f'config["pixel_width"] = {pixel_width}',
            f'config["save_last_frame"] = {save_last_frame}',
            f'config["save_as_gif"] = {save_as_gif}',
            f'config["write_to_movie"] = {not save_last_frame}',
            f'config["output_file"] = r"{output_file}"',
        ]

        user_code = self.content
        if user_code[0].startswith(
                ">>> "):  # check whether block comes from doctest
            user_code = [
                line[4:] for line in user_code
                if line.startswith((">>> ", "... "))
            ]

        code = [
            "from manim import *",
            *config_code,
            *user_code,
            f"{clsname}().render()",
        ]
        exec("\n".join(code), globals())

        # copy video file to output directory
        if not (save_as_gif or save_last_frame):
            filename = f"{output_file}.mp4"
            filesrc = config.get_dir("video_dir") / filename
            destfile = os.path.join(dest_dir, filename)
            shutil.copyfile(filesrc, destfile)
        elif save_as_gif:
            filename = f"{output_file}.gif"
            filesrc = config.get_dir("video_dir") / filename
        elif save_last_frame:
            filename = f"{output_file}.png"
            filesrc = config.get_dir("images_dir") / filename
        else:
            raise ValueError("Invalid combination of render flags received.")

        rendered_template = jinja2.Template(TEMPLATE).render(
            clsname=clsname,
            clsname_lowercase=clsname.lower(),
            hide_source=hide_source,
            filesrc_rel=os.path.relpath(filesrc, setup.confdir),
            output_file=output_file,
            save_last_frame=save_last_frame,
            save_as_gif=save_as_gif,
            source_block=source_block,
            ref_block=ref_block,
        )
        state_machine.insert_input(rendered_template.split("\n"),
                                   source=document.attributes["source"])

        return []