Example #1
0
def writeCode(class_name, code, inliner):
    '''write code of class to file.

    returns URI of written code.
    '''
    document = inliner.document.current_source

    reference = class_name

    # root of document tree
    srcdir = setup.srcdir

    # get the directory of the rst file
    rstdir, rstfile = os.path.split(document)

    (basedir, fname, basename, ext, outdir, codename,
     notebookname) = Utils.build_paths(reference)

    # path to root relative to rst
    rst2srcdir = os.path.join(os.path.relpath(srcdir, start=rstdir), outdir)

    # output code
    linked_codename = re.sub("\\\\", "/", os.path.join(rst2srcdir, codename))
    if code and basedir != outdir:
        outfile = open(os.path.join(outdir, codename), "w")
        for line in code:
            outfile.write(line)
        outfile.close()

    return linked_codename
Example #2
0
def cleanTrackers(rst_files, options, args):
    '''instantiate trackers and get code.'''
    trackers = set()
    for f in rst_files:
        for lineno, b in getBlocksFromRstFile(f):
            trackers.add(b.mArguments[0])

    ntested, ncleaned, nskipped = 0, 0, 0
    for reference in trackers:

        try:
            code, tracker, tracker_path = report_directive.makeTracker(
                reference)
        except AttributeError:
            # ignore missing trackers
            nskipped += 1
            continue

        new_codehash = hashlib.md5("".join(code)).hexdigest()
        (basedir, fname, basename, ext,
         outdir, codename, notebookname) = Utils.build_paths(
             reference)
        codefilename = os.path.join(outdir, codename)
        ntested += 1
        if not os.path.exists(codefilename):
            nskipped += 1
            continue
        old_codehash = hashlib.md5(
            "".join(open(codefilename, "r").readlines())).hexdigest()
        if new_codehash != old_codehash:
            removed = clean.removeTracker(reference)
            removed.extend(clean.removeText(reference))
            print("code has changed for %s: %i files removed" %
                  (reference, len(removed)))
            ncleaned += 1
    print("CGATReport: %i Trackers changed (%i tested, %i skipped)" %
          (ncleaned, ntested, nskipped))
Example #3
0
def writeCode(class_name, code, inliner):
    '''write code of class to file.

    returns URI of written code.
    '''
    document = inliner.document.current_source

    reference = class_name

    # root of document tree
    srcdir = setup.srcdir

    # get the directory of the rst file
    rstdir, rstfile = os.path.split(document)

    (basedir, fname, basename, ext, outdir, codename,
     notebookname) = Utils.build_paths(reference)

    # path to root relative to rst
    rst2srcdir = os.path.join(os.path.relpath(srcdir, start=rstdir), outdir)

    # output code
    linked_codename = re.sub("\\\\", "/", os.path.join(rst2srcdir, codename))
    if code and basedir != outdir:
        # patch, something is wrong with paths, files do not end up
        # in build directory, but in current directory because outdir
        # only has the last path components (_static/report_directive)
        if not os.path.exists(outdir):
            os.makedirs(outdir)

        outfile = open(os.path.join(outdir, codename), "w")
        for line in code:
            outfile.write(line)
        outfile.close()

    return linked_codename
def run(arguments,
        options,
        lineno,
        content,
        state_machine=None,
        document=None,
        srcdir=None,
        builddir=None,
        build_environment=None):
    """process:report: directive.

    *srdir* - top level directory of rst documents
    *builddir* - build directory
    """

    tag = "%s:%i" % (str(document), lineno)

    logger = Component.get_logger()

    logger.debug("report_directive.run: profile: started: rst: %s" % tag)

    # sort out the paths
    # reference is used for time-stamping
    tracker_name = directives.uri(arguments[0])

    (basedir, fname, basename, ext, outdir,
     codename, notebookname) = Utils.build_paths(tracker_name)

    # get the directory of the rst file
    # state_machine.document.attributes['source'])
    rstdir, rstfile = os.path.split(document)
    # root of document tree
    if srcdir is None:
        srcdir = setup.srcdir

    # build directory
    if builddir is None:
        builddir = setup.builddir

    # remove symbolic links
    srcdir, builddir, rstdir = [
        os.path.abspath(os.path.realpath(x)) for x in (srcdir, builddir, rstdir)]

    # there are three directories:
    # builddir = directory where document is built in
    #            (usually _build/html or similar)
    # rstdir   = directory where rst sources are located
    # srcdir   = directory from which the build process is started

    # path to root relative to rst
    rst2srcdir = os.path.join(os.path.relpath(srcdir, start=rstdir), outdir)

    # path to root relative to rst
    rst2builddir = os.path.join(
        os.path.relpath(builddir, start=rstdir), outdir)

    # path relative to source (for images)
    root2builddir = os.path.join(
        os.path.relpath(builddir, start=srcdir), outdir)

    logger.debug(
        "report_directive.run: arguments=%s, options=%s, lineno=%s, "
        "content=%s, document=%s" %
        (str(arguments),
         str(options),
         str(lineno),
         str(content),
         str(document)))
    logger.debug(
        "report_directive.run: plotdir=%s, basename=%s, ext=%s, "
        "fname=%s, rstdir=%s, srcdir=%s, builddir=%s" %
        (tracker_name, basename, ext, fname, rstdir, srcdir, builddir))
    logger.debug(
        "report_directive.run: tracker_name=%s, basedir=%s, "
        "rst2src=%s, root2build=%s, outdir=%s, codename=%s" %
        (tracker_name, basedir, rst2srcdir, rst2builddir, outdir, codename))

    # try to create. If several processes try to create it,
    # testing with `if` will not work.
    try:
        os.makedirs(outdir)
    except OSError as msg:
        pass

    if not os.path.exists(outdir):
        raise OSError("could not create directory %s: %s" % (outdir, msg))

    ########################################################
    # collect options
    # replace placedholders
    try:
        options = update_options(options)
    except ValueError as msg:
        logger.warn("failure while updating options: %s" % msg)

    logger.debug("report_directive.run: options=%s" % (str(options),))

    transformer_names = []
    renderer_name = None

    layout = options.get("layout", "column")
    long_titles = "long-titles" in options

    option_map = get_option_map()
    renderer_options = select_and_delete_options(
        options, option_map["render"])
    transformer_options = select_and_delete_options(
        options, option_map["transform"])
    dispatcher_options = select_and_delete_options(
        options, option_map["dispatch"])
    tracker_options = select_and_delete_options(
        options, option_map["tracker"], expand=["tracker"])
    display_options = get_default_display_options()
    display_options.update(select_and_delete_options(
        options, option_map["display"]))

    logger.debug("report_directive.run: renderer options: %s" %
                 str(renderer_options))
    logger.debug("report_directive.run: transformer options: %s" %
                 str(transformer_options))
    logger.debug("report_directive.run: dispatcher options: %s" %
                 str(dispatcher_options))
    logger.debug("report_directive.run: tracker options: %s" %
                 str(tracker_options))
    logger.debug("report_directive.run: display options: %s" %
                 str(display_options))

    if "transform" in display_options:
        transformer_names = display_options["transform"].split(",")
        del display_options["transform"]

    if "render" in display_options:
        renderer_name = display_options["render"]
        del display_options["render"]

    ########################################################
    # check for missing files
    if renderer_name is not None:

        options_key = str(renderer_options) +\
            str(transformer_options) +\
            str(dispatcher_options) +\
            str(tracker_options) +\
            str(transformer_names) +\
            re.sub("\s", "", "".join(content))

        options_hash = hashlib.md5(options_key.encode()).hexdigest()[:10]

        template_name = Utils.quote_filename(
            Config.SEPARATOR.join((tracker_name, renderer_name,
                                   options_hash)))
        filename_text = os.path.join(outdir, "%s.txt" % (template_name))
        rstname = os.path.basename(filename_text)
        notebookname += options_hash

        logger.debug("report_directive.run: options_hash=%s" % options_hash)

        ###########################################################
        # check for existing files
        # update strategy does not use file stamps, but checks
        # for presence/absence of text element and if all figures
        # mentioned in the text element are present
        ###########################################################
        queries = [re.compile("%s/(\S+.%s)" %
                              (root2builddir, suffix))
                   for suffix in ("png", "pdf", "svg")]

        logger.debug("report_directive.run: checking for changed files.")

        # check if text element exists
        if os.path.exists(filename_text):

            with open(filename_text, "r", encoding="utf-8") as inf:
                lines = [x[:-1] for x in inf]
            filenames = []
            
            # check if all figures are present
            for line in lines:
                for query in queries:
                    x = query.search(line)
                    if x:
                        filenames.extend(list(x.groups()))

            filenames = [os.path.join(outdir, x) for x in filenames]
            if len(filenames) == 0:
                logger.info("report_directive.run: %s: redo: no files found" % tag)
            else:
                logger.debug(
                    "report_directive.run: %s: checking for %s" %
                    (tag, str(filenames)))
                for filename in filenames:
                    if not os.path.exists(filename):
                        logger.info(
                            "report_directive.run: %s: redo: file %s is missing" %
                            (tag, filename))
                        break
                else:
                    logger.info(
                        "report_directive.run: %s: noredo: all files are present" %
                        tag)
                    # all is present - save text and return
                    if lines and state_machine:
                        state_machine.insert_input(
                            lines, state_machine.input_lines.source(0))
                    return []
        else:
            logger.debug(
                "report_directive.run: %s: no check performed: %s missing" %
                (tag, str(filename_text)))
    else:
        template_name = ""
        filename_text = None

    collect_here = False
    ##########################################################
    # instantiate tracker, dispatcher, renderer and transformers
    # and collect output
    ###########################################################
    try:
        ########################################################
        # find the tracker
        logger.debug(
            "report_directive.run: collecting tracker %s with options %s " %
            (tracker_name, tracker_options))
        code, tracker, tracker_path = make_tracker(
            tracker_name, (), tracker_options)
        if not tracker:
            logger.error(
                "report_directive.run: no tracker - no output from %s " %
                str(document))
            raise ValueError("tracker `%s` not found" % tracker_name)

        logger.debug(
            "report_directive.run: collected tracker %s" % tracker_name)

        tracker_id = Cache.tracker2key(tracker)

        ########################################################
        # determine the transformer
        logger.debug("report_directive.run: creating transformers")

        transformers = get_transformers(
            transformer_names, transformer_options)

        ########################################################
        # determine the renderer
        logger.debug("report_directive.run: creating renderer.")

        if renderer_name is None:
            logger.error(
                "report_directive.run: no renderer - no output from %s" %
                str(document))
            raise ValueError("the report directive requires a renderer")

        renderer = get_renderer(renderer_name, renderer_options)

        try:
            renderer.set_paths(rstdir, srcdir, builddir)
            renderer.set_display_options(display_options)
            renderer.set_build_environment(build_environment)
        except AttributeError:
            # User renderers will not have these methods
            pass

        ########################################################
        # write code output
        linked_codename = re.sub("\\\\", "/", os.path.join(rst2builddir, codename))
        if code and basedir != outdir:
            if six.PY2:
                with open(os.path.join(outdir, codename), "w") as outfile:
                    for line in code:
                        outfile.write(line)
            else:
                with open(os.path.join(outdir, codename), "w",
                          encoding=get_encoding()) as outfile:
                    for line in code:
                        outfile.write(line)

        ########################################################
        # write notebook snippet
        linked_notebookname = re.sub(
            "\\\\", "/", os.path.join(rst2builddir, notebookname))

        if basedir != outdir and tracker_id is not None:
            with open(os.path.join(outdir, notebookname), "w") as outfile:
                Utils.writeNoteBookEntry(outfile,
                                         renderer=renderer_name,
                                         tracker=tracker_name,
                                         transformers=transformer_names,
                                         tracker_path=tracker_path,
                                         options=list(renderer_options.items()) +
                                         list(tracker_options.items()) +
                                         list(transformer_options.items()))

        if filename_text is not None:
            linked_rstname = re.sub(
                "\\\\", "/", os.path.join(rst2builddir, rstname))
        else:
            linked_rstname = None

        ##########################################################
        # Initialize collectors
        links = {'code_url': linked_codename,
                 'rst_url': linked_rstname,
                 'notebook_url': linked_notebookname}

        collectors = []
        for name, collector in get_plugins("collect").items():
            collectors.append(collector(
                template_name=template_name,
                outdir=outdir,
                rstdir=rstdir,
                builddir=builddir,
                srcdir=srcdir,
                content=content,
                display_options=display_options,
                trackerd_id=tracker_id,
                links=links))

        # user renderers might not have a set_collectors method
        try:
            collect_here = not renderer.set_collectors(collectors)
        except AttributeError:
            collect_here = True

        ########################################################
        # create and call dispatcher
        logger.debug("report_directive.run: creating dispatcher")

        dispatcher = Dispatcher.Dispatcher(tracker,
                                           renderer,
                                           transformers)

        # add the tracker options
        dispatcher_options.update(tracker_options)
        blocks = dispatcher(**dispatcher_options)

        if blocks is None:
            blocks = ResultBlocks(
                Utils.buildWarning(
                    "NoData",
                    "tracker %s returned no Data" % str(tracker)))
            code = None
            tracker_id = None

    except:
        exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
        tb = "\n".join(traceback.format_tb(exceptionTraceback))

        logger.error(
            "report_directive.run: exception caught at %s:%i: %s %s\n%s\n" %
            (str(document), lineno,
             exceptionType,
             exceptionValue,
             tb))

        blocks = ResultBlocks(Utils.buildException("invocation"))
        code = None
        tracker_id = None
        links = {'code_url': "",
                 'rst_url': "",
                 'notebook_url': ""}

    logger.debug(
        "report_directive.run: profile: started: collecting: %s" % tag)

    ###########################################################
    # replace place holders or add text
    ###########################################################
    # add default for text-only output
    requested_urls = as_list(Utils.get_params()["report_urls"])

    urls = []
    if "code" in requested_urls:
        urls.append(":download:`code <%(code_url)s>`" % links)

    if "notebook" in requested_urls:
        urls.append(":download:`nb <%(notebook_url)s>`" % links)

    map_figure2text = {}

    if collect_here:
        for collector in collectors:
            map_figure2text.update(collector.collect(blocks))

    map_figure2text["default-prefix"] = ""
    map_figure2text["default-suffix"] = ""

    if urls and "no-links" not in display_options:
        url_template = "[{}]".format(" ".join(urls))
    else:
        url_template = ""

    map_figure2text["default-prefix"] = TEMPLATE_TEXT % locals()

    blocks.updatePlaceholders(map_figure2text)

    # render the output taking into account the layout
    lines = Utils.layoutBlocks(blocks, layout, long_titles=long_titles)
    lines.append("")

    # add caption
    if content and "no-caption" not in display_options:
        lines.extend(['::', ''])
        lines.extend(['    %s' % row.strip() for row in content])
        lines.append("")

    # encode lines
    if six.PY2:
        lines = [force_encode(x, encoding="ascii", errors="replace") for x in lines]

    # output rst text for this renderer
    if filename_text:
        if six.PY2:
            with open(filename_text, "w") as outf:
                outf.write("\n".join(lines))
        else:
            with open(filename_text, "w", encoding=get_encoding()) as outf:
                outf.write("\n".join(lines))

    if CGATREPORT_DEBUG:
        for x, l in enumerate(lines):
            try:
                print(("%5i %s" % (x, l)))
            except UnicodeEncodeError:
                print(("line skipped - unicode error"))
                pass

    if len(lines) and state_machine:
        state_machine.insert_input(
            lines, state_machine.input_lines.source(0))

    logger.debug(
        "report_directive.run: profile: finished: collecting: %s" % tag)
    logger.debug(
        "report_directive.run: profile: finished: rst: %s:%i" %
        (str(document), lineno))

    return []
Example #5
0
def run(arguments,
        options,
        lineno,
        content,
        state_machine=None,
        document=None,
        srcdir=None,
        builddir=None):
    """process:report: directive.

    *srdir* - top level directory of rst documents
    *builddir* - build directory
    """

    tag = "%s:%i" % (str(document), lineno)

    logging.debug("report_directive.run: profile: started: rst: %s" % tag)

    # sort out the paths
    # reference is used for time-stamping
    tracker_name = directives.uri(arguments[0])

    (basedir, fname, basename, ext, outdir,
     codename, notebookname) = Utils.build_paths(tracker_name)

    # get the directory of the rst file
    # state_machine.document.attributes['source'])
    rstdir, rstfile = os.path.split(document)
    # root of document tree
    if srcdir is None:
        srcdir = setup.srcdir

    # build directory
    if builddir is None:
        builddir = setup.builddir

    # remove symbolic links
    srcdir, builddir, rstdir = [
        os.path.realpath(x) for x in (srcdir, builddir, rstdir)]

    # there are three directories:
    # builddir = directory where document is built in
    #            (usually _build/html or similar)
    # rstdir   = directory where rst sources are located
    # srcdir   = directory from which the build process is started

    # path to root relative to rst
    rst2srcdir = os.path.join(os.path.relpath(srcdir, start=rstdir), outdir)

    # path to root relative to rst
    rst2builddir = os.path.join(
        os.path.relpath(builddir, start=rstdir), outdir)

    # path relative to source (for images)
    root2builddir = os.path.join(
        os.path.relpath(builddir, start=srcdir), outdir)

    logging.debug(
        "report_directive.run: arguments=%s, options=%s, lineno=%s, "
        "content=%s, document=%s" %
        (str(arguments),
         str(options),
         str(lineno),
         str(content),
         str(document)))
    logging.debug(
        "report_directive.run: plotdir=%s, basename=%s, ext=%s, "
        "fname=%s, rstdir=%s, srcdir=%s, builddir=%s" %
        (tracker_name, basename, ext, fname, rstdir, srcdir, builddir))
    logging.debug(
        "report_directive.run: tracker_name=%s, basedir=%s, "
        "rst2src=%s, root2build=%s, outdir=%s, codename=%s" %
        (tracker_name, basedir, rst2srcdir, rst2builddir, outdir, codename))

    # try to create. If several processes try to create it,
    # testing with `if` will not work.
    try:
        os.makedirs(outdir)
    except OSError as msg:
        pass

    if not os.path.exists(outdir):
        raise OSError("could not create directory %s: %s" % (outdir, msg))

    ########################################################
    # collect options
    # replace placedholders
    try:
        options = Utils.updateOptions(options)
    except ValueError as msg:
        logging.warn("failure while updating options: %s" % msg)

    logging.debug("report_directive.run: options=%s" % (str(options),))

    transformer_names = []
    renderer_name = None

    # get layout option
    layout = options.get("layout", "column")

    option_map = Component.getOptionMap()
    renderer_options = Utils.selectAndDeleteOptions(
        options, option_map["render"])
    transformer_options = Utils.selectAndDeleteOptions(
        options, option_map["transform"])
    dispatcher_options = Utils.selectAndDeleteOptions(
        options, option_map["dispatch"])
    tracker_options = Utils.selectAndDeleteOptions(
        options, option_map["tracker"])
    display_options = Utils.selectAndDeleteOptions(
        options, option_map["display"])

    logging.debug("report_directive.run: renderer options: %s" %
                  str(renderer_options))
    logging.debug("report_directive.run: transformer options: %s" %
                  str(transformer_options))
    logging.debug("report_directive.run: dispatcher options: %s" %
                  str(dispatcher_options))
    logging.debug("report_directive.run: tracker options: %s" %
                  str(tracker_options))
    logging.debug("report_directive.run: display options: %s" %
                  str(display_options))

    if "transform" in display_options:
        transformer_names = display_options["transform"].split(",")
        del display_options["transform"]

    if "render" in display_options:
        renderer_name = display_options["render"]
        del display_options["render"]

    ########################################################
    # check for missing files
    if renderer_name is not None:

        options_key = str(renderer_options) +\
            str(transformer_options) +\
            str(dispatcher_options) +\
            str(tracker_options) +\
            str(transformer_names)

        options_hash = hashlib.md5(options_key.encode()).hexdigest()

        template_name = Utils.quote_filename(
            Config.SEPARATOR.join((tracker_name, renderer_name,
                                   options_hash)))
        filename_text = os.path.join(outdir, "%s.txt" % (template_name))

        notebookname += options_hash

        logging.debug("report_directive.run: options_hash=%s" % options_hash)

        ###########################################################
        # check for existing files
        # update strategy does not use file stamps, but checks
        # for presence/absence of text element and if all figures
        # mentioned in the text element are present
        ###########################################################
        queries = [re.compile("%s(%s\S+.%s)" %
                              (root2builddir, outdir, suffix))
                   for suffix in ("png", "pdf", "svg")]

        logging.debug("report_directive.run: checking for changed files.")

        # check if text element exists
        if os.path.exists(filename_text):

            lines = [x[:-1] for x in open(filename_text, "r").readlines()]
            filenames = []

            # check if all figures are present
            for line in lines:
                for query in queries:
                    x = query.search(line)
                    if x:
                        filenames.extend(list(x.groups()))

            logging.debug(
                "report_directive.run: %s: checking for %s" %
                (tag, str(filenames)))
            for filename in filenames:
                if not os.path.exists(filename):
                    logging.info(
                        "report_directive.run: %s: redo: %s missing" %
                        (tag, filename))
                    break
            else:
                logging.info(
                    "report_directive.run: %s: noredo: all files are present" %
                    tag)
                # all is present - save text and return
                if lines and state_machine:
                    state_machine.insert_input(
                        lines, state_machine.input_lines.source(0))
                return []
        else:
            logging.debug(
                "report_directive.run: %s: no check performed: %s missing" %
                (tag, str(filename_text)))
    else:
        template_name = ""
        filename_text = None

    ##########################################################
    # Initialize collectors
    collectors = []
    for collector in list(Component.getPlugins("collect").values()):
        collectors.append(collector())

    ##########################################################
    # instantiate tracker, dispatcher, renderer and transformers
    # and collect output
    ###########################################################
    try:
        ########################################################
        # find the tracker
        logging.debug(
            "report_directive.run: collecting tracker %s with options %s " %
            (tracker_name, tracker_options))
        code, tracker, tracker_path = Utils.makeTracker(
            tracker_name, (), tracker_options)
        if not tracker:
            logging.error(
                "report_directive.run: no tracker - no output from %s " %
                str(document))
            raise ValueError("tracker `%s` not found" % tracker_name)

        logging.debug(
            "report_directive.run: collected tracker %s" % tracker_name)

        tracker_id = Cache.tracker2key(tracker)

        ########################################################
        # determine the transformer
        logging.debug("report_directive.run: creating transformers")

        transformers = Utils.getTransformers(
            transformer_names, transformer_options)

        ########################################################
        # determine the renderer
        logging.debug("report_directive.run: creating renderer.")

        if renderer_name is None:
            logging.error(
                "report_directive.run: no renderer - no output from %s" %
                str(document))
            raise ValueError("the report directive requires a renderer")

        renderer = Utils.getRenderer(renderer_name, renderer_options)

        try:
            renderer.set_paths(rstdir, srcdir, builddir)
            renderer.set_display_options(display_options)
        except AttributeError:
            # User renderers will not have these methods
            pass

        ########################################################
        # create and call dispatcher
        logging.debug("report_directive.run: creating dispatcher")

        dispatcher = Dispatcher.Dispatcher(tracker,
                                           renderer,
                                           transformers)

        # add the tracker options
        dispatcher_options.update(tracker_options)

        blocks = dispatcher(**dispatcher_options)

        if blocks is None:
            blocks = ResultBlocks(ResultBlocks(
                Utils.buildWarning(
                    "NoData",
                    "tracker %s returned no Data" % str(tracker))))
            code = None
            tracker_id = None

    except:

        logging.warn(
            "report_directive.run: exception caught at %s:%i - see document" %
            (str(document), lineno))

        blocks = ResultBlocks(ResultBlocks(
            Utils.buildException("invocation")))
        code = None
        tracker_id = None

    logging.debug(
        "report_directive.run: profile: started: collecting: %s" % tag)

    ########################################################
    # write code output
    linked_codename = re.sub("\\\\", "/", os.path.join(rst2srcdir, codename))
    if code and basedir != outdir:
        with open(os.path.join(outdir, codename), "w") as outfile:
            for line in code:
                outfile.write(line)

    ########################################################
    # write notebook snippet
    linked_notebookname = re.sub(
        "\\\\", "/", os.path.join(rst2srcdir, notebookname))
    if basedir != outdir and tracker_id is not None:
        with open(os.path.join(outdir, notebookname), "w") as outfile:
            Utils.writeNoteBookEntry(outfile,
                                     renderer=renderer_name,
                                     tracker=tracker_name,
                                     transformers=transformer_names,
                                     tracker_path=tracker_path,
                                     options=renderer_options.items() +
                                     tracker_options.items() +
                                     transformer_options.items())

    ###########################################################
    # collect images
    ###########################################################
    map_figure2text = {}
    links = {'code_url': linked_codename,
             'notebook_url': linked_notebookname}
    try:
        for collector in collectors:
            map_figure2text.update(collector.collect(
                blocks,
                template_name,
                outdir,
                rstdir,
                builddir,
                srcdir,
                content,
                display_options,
                tracker_id,
                links=links))
    except:

        logging.warn("report_directive.run: exception caught while "
                     "collecting with %s at %s:%i - see document" %
                     (collector, str(document), lineno))
        blocks = ResultBlocks(ResultBlocks(
            Utils.buildException("collection")))
        code = None
        tracker_id = None

    ###########################################################
    # replace place holders or add text
    ###########################################################
    # add default for text-only output
    urls = Utils.asList(Utils.PARAMS["report_urls"])
    code_url, nb_url = "", ""
    if "code" in urls:
        code_url = "`code <%(code_url)s>`__" % links

    if "notebook" in urls:
        nb_url = '`nb <%(notebook_url)s>`__' % links

    map_figure2text["default-prefix"] = TEMPLATE_TEXT % locals()
    map_figure2text["default-suffix"] = ""
    blocks.updatePlaceholders(map_figure2text)

    # render the output taking into account the layout
    lines = Utils.layoutBlocks(blocks, layout)
    lines.append("")

    # add caption
    lines.extend(['::', ''])
    if content:
        lines.extend(['    %s' % row.strip() for row in content])
        lines.append("")

    lines.append("")

    # output rst text for this renderer
    if filename_text:
        outfile = open(filename_text, "w")
        outfile.write("\n".join(lines))
        outfile.close()

    if CGATREPORT_DEBUG:
        for x, l in enumerate(lines):
            print("%5i %s" % (x, l))

    if len(lines) and state_machine:
        state_machine.insert_input(
            lines, state_machine.input_lines.source(0))

    logging.debug(
        "report_directive.run: profile: finished: collecting: %s" % tag)
    logging.debug(
        "report_directive.run: profile: finished: rst: %s:%i" %
        (str(document), lineno))

    return []