Ejemplo n.º 1
0
    def __init__(self, self_cfg, import_dest):
        tracer.info("called")
        self.useable = False
        self._cfg = dict(self.default_config)
        self._cfg.update(self_cfg)
        self._dest = dict()
        self._entries = None
        self._topics = None

        import_dest_cfg = Cfg(import_dest)
        try:
            req_dirs = import_dest_cfg.get_rvalue("requirements_dirs")
            if req_dirs[0] and os.path.isdir(req_dirs[0]):
                self.useable = True
                self._dest["requirements_dirs"] = req_dirs[0]
        except RMTException:
            self.useable = False
        try:
            topics_dirs = import_dest_cfg.get_rvalue("topics_dirs")
            if topics_dirs[0] and os.path.isdir(topics_dirs[0]):
                self.useable = True
                self._dest["topics_dirs"] = topics_dirs[0]
        except RMTException:
            self.useable = False
        self._wb = None
        tracer.debug("Finished.")
Ejemplo n.º 2
0
 def __init__(self, config):
     cfg = Cfg(config)
     Interface.__init__(self, cfg)
     tracer.info("called")
     self.__topic_root_node = cfg.get_rvalue("topic_root_node")
     self.__dirs = {}
     self.__setup_directories(cfg)
Ejemplo n.º 3
0
Archivo: Git.py Proyecto: florath/rmtoo
    def __init__(self, config):
        tracer.info("called")
        cfg = Cfg(config)
        FileInterface.__init__(self, cfg)
        self.__start_vers = cfg.get_rvalue("start_vers")
        self.__end_vers = cfg.get_rvalue("end_vers")
        self.__topic_root_node = cfg.get_rvalue("topic_root_node")
        tracer.debug("start version [%s] end version [%s] "
                     "topic root node [%s]",
                     self.__start_vers, self.__end_vers,
                     self.__topic_root_node)

        # When the directory is not absolute, convert it to an
        # absolute path that it can be compared to the outcome of the
        # git.Repo.
        self.__dirs = {}
        self.__repo_base_dir = None
        self.__repo = None
        self.__dirs = self._setup_directories(cfg)
Ejemplo n.º 4
0
    def __init__(self, config):
        tracer.info("called")
        cfg = Cfg(config)
        Interface.__init__(self, cfg)
        self.__start_vers = cfg.get_rvalue("start_vers")
        self.__end_vers = cfg.get_rvalue("end_vers")
        self.__topic_root_node = cfg.get_rvalue("topic_root_node")
        tracer.debug(
            "start version [%s] end version [%s] "
            "topic root node [%s]" %
            (self.__start_vers, self.__end_vers, self.__topic_root_node))

        # When the directory is not absolute, convert it to an
        # absolute path that it can be compared to the outcome of the
        # git.Repo.
        self.__dirs = {}
        self.__repo_base_dir = None
        self.__repo = None
        self.__setup_directories(cfg)
Ejemplo n.º 5
0
class html(ExecutorTopicContinuum, CreateMakeDependencies):
    def __init__(self, oconfig):
        '''Create a graph output object.'''
        tracer.debug("Called: html ouput module constructed.")
        self._config = Cfg(oconfig)
        CreateMakeDependencies.__init__(self)
        self.__fd_stack = []
        self.__topic_name_set = []
        # Take care about the openess of the ul.
        self.__ul_open_stack = []
        self.__output_directory = self._config.get_rvalue('output_directory')
        self.html_header_filename = self._config.get_rvalue('header')
        self.html_footer_filename = self._config.get_rvalue('footer')
        self.read_html_arts()

    def __ouput_html_topic_mkdirs(self):
        '''If not already there, create the directory.'''
        try:
            os.makedirs(self.__output_directory)
        except OSError, ose:
            # It's ok if already there
            pass
Ejemplo n.º 6
0
class html(ExecutorTopicContinuum, CreateMakeDependencies):

    def __init__(self, oconfig):
        '''Create a graph output object.'''
        tracer.debug("Called: html ouput module constructed.")
        self._config = Cfg(oconfig)
        CreateMakeDependencies.__init__(self)
        self.__fd_stack = []
        self.__topic_name_set = []
        # Take care about the openess of the ul.
        self.__ul_open_stack = []
        self.__output_directory = self._config.get_rvalue('output_directory')
        self.html_header_filename = self._config.get_rvalue('header')
        self.html_footer_filename = self._config.get_rvalue('footer')
        self.read_html_arts()

    def __ouput_html_topic_mkdirs(self):
        '''If not already there, create the directory.'''
        try:
            os.makedirs(self.__output_directory)
        except OSError, ose:
            # It's ok if already there
            pass
Ejemplo n.º 7
0
class StdOutputParams:
    '''Handles the standard output parameters and sets the values
       in the self object provided.'''

    def __init__(self, config):
        '''Constructs the standard output parameters based on the
           provided config.'''
        self._output_filename = None
        self._start_date = None
        self._end_date = None
        self._config = Cfg(config)
        self.__parse()

    def __parse_output_filename(self):
        '''Sets the output filename.'''
        self._output_filename = self._config.get_rvalue('output_filename')

    @staticmethod
    def __parse_date(cfg, name, default_value):
        '''If name is in params, the value is converted to a date
           and returned.  If name is not in params, the default_value
           is returned.'''
        pname = cfg.get_value_wo_throw(name)
        if pname == None:
            return default_value
        return parse_date(name, pname)

    def __parse_start_and_end_date(self):
        '''Extracts the start and the end date from the params.'''
        today = datetime.date.today()
        yesterday = today - datetime.timedelta(1)
        self._start_date = self.__parse_date(
                                self._config, 'start_date', yesterday)
        tracer.debug("Start date [%s]" % self._start_date)
        self._end_date = self.__parse_date(self._config, 'end_date', today)
        tracer.debug("End date [%s]" % self._end_date)

    def __parse(self):
        '''Parses the standard parameters.'''
        self.__parse_output_filename()
        self.__parse_start_and_end_date()
Ejemplo n.º 8
0
class StdOutputParams(object):
    '''Handles the standard output parameters and sets the values
       in the self object provided.'''
    def __init__(self, config):
        '''Constructs the standard output parameters based on the
           provided config.'''
        self._output_filename = None
        self._start_date = None
        self._end_date = None
        self._config = Cfg(config)
        self.__parse()

    def __parse_output_filename(self):
        '''Sets the output filename.'''
        self._output_filename = self._config.get_rvalue('output_filename')

    @staticmethod
    def __parse_date(cfg, name, default_value):
        '''If name is in params, the value is converted to a date
           and returned.  If name is not in params, the default_value
           is returned.'''
        pname = cfg.get_value_wo_throw(name)
        if pname is None:
            return default_value
        return parse_date(name, pname)

    def __parse_start_and_end_date(self):
        '''Extracts the start and the end date from the params.'''
        today = datetime.date.today()
        yesterday = today - datetime.timedelta(1)
        self._start_date = self.__parse_date(self._config, 'start_date',
                                             yesterday)
        tracer.debug("Start date [%s]", self._start_date)
        self._end_date = self.__parse_date(self._config, 'end_date', today)
        tracer.debug("End date [%s]", self._end_date)

    def __parse(self):
        '''Parses the standard parameters.'''
        self.__parse_output_filename()
        self.__parse_start_and_end_date()
Ejemplo n.º 9
0
class Html(ExecutorTopicContinuum, CreateMakeDependencies):
    """HTML output module"""
    def __init__(self, oconfig):
        '''Create a graph output object.'''
        tracer.debug("Called: html ouput module constructed.")
        self._config = Cfg(oconfig)
        CreateMakeDependencies.__init__(self)
        self.__fd_stack = []
        self.__topic_name_set = []
        # Take care about the openess of the ul.
        self.__ul_open_stack = []
        self.__output_directory = self._config.get_rvalue('output_directory')
        self.__markup = Markup("html")
        self.__tc_name = None
        self.__topic_set = None
        self.html_header_filename = self._config.get_rvalue('header')
        self.html_footer_filename = self._config.get_rvalue('footer')
        self.read_html_arts()

    def __ouput_html_topic_mkdirs(self):
        '''If not already there, create the directory.'''
        try:
            os.makedirs(self.__output_directory)
        except OSError:
            # It's ok if already there
            pass

    def topic_continuum_sort(self, vcs_commit_ids, topic_sets):
        '''Because graph2 can only one topic continuum,
           the latest (newest) is used.'''
        return [topic_sets[vcs_commit_ids[-1].get_commit()]]

    def topic_set_pre(self, _topics_set):
        '''Do all the file and directory preparation.'''
        self.__ouput_html_topic_mkdirs()

    def __output_html_topic_write_header(self, out_fd):
        '''Write the html header.'''
        out_fd.write(self.html_header)

    def topic_pre(self, topic):
        '''Output one topic.
           This method is called once for each topic and subtopic.'''
        tracer.debug("Called: topic name [%s]", topic.name)
        filename = os.path.join(self.__output_directory, topic.name + ".html")
        out_fd = io.open(filename, "w", encoding="utf-8")
        self.__output_html_topic_write_header(out_fd)
        self.__fd_stack.append(out_fd)
        self.__ul_open_stack.append(False)
        # self.output_html_topic_output_content(fd, topic)

    def topic_post(self, topic):
        '''Write out the footer and do clean ups.'''
        out_fd = self.__fd_stack.pop()
        self.__ul_open_stack.pop()
        self.output_html_topic_write_footer(out_fd)
        out_fd.close()
        tracer.debug("Finished: topic name [%s]", topic.name)

    def topic_name(self, name):
        '''Set the name.'''
        out_fd = self.__fd_stack[-1]
        level = len(self.__fd_stack)
        out_fd.write(u"<h%d>%s</h%d>\n" % (level, name, level))

    def topic_text(self, text):
        '''Called when there is text to be outputted.'''
        out_fd = self.__fd_stack[-1]
        out_fd.write(u'<p><span class="fltext">%s</span></p>\n' %
                     self.__markup.replace(text))

    def topic_sub_pre(self, subtopic):
        '''Prepares a new subtopic output.'''
        out_fd = self.__fd_stack[-1]
        if not self.__ul_open_stack[-1]:
            out_fd.write(u'<span class="subtopiclist"><ul>')
            self.__ul_open_stack[-1] = True
        out_fd.write(u'<li><a href="%s.html">%s</a></li>\n' %
                     (subtopic.get_id(), subtopic.get_topic_name()))

    def topic_sub_post(self, _subtopic):
        '''Write the header for subtopic.'''
        if self.__ul_open_stack[-1]:
            out_fd = self.__fd_stack[-1]
            out_fd.write(u"</ul></span>")
            self.__ul_open_stack[-1] = False

    def requirement_set_sort(self, list_to_sort):
        '''Sort by id.'''
        return sorted(list_to_sort, key=lambda r: r.get_id())

    def requirement(self, req):
        '''Output one requirement.'''
        out_fd = self.__fd_stack[-1]
        level = len(self.__fd_stack)

        out_fd.write(u"\n<!-- REQ '%s' -->\n" % req.get_id())
        out_fd.write(u'<h%d><a id="%s">%s</a></h%d>\n' %
                     (level + 1, req.get_id(),
                      req.get_value("Name").get_content(), level + 1))
        out_fd.write(u"<dl>")

        out_fd.write(
            u'<dt><span class="dlt_description">Description</span>'
            '</dt><dd><span class="dlv_description">%s</span></dd>' %
            self.__markup.replace(req.get_value("Description").get_content()))

        if req.is_value_available("Rationale") \
                and req.get_value("Rationale") is not None:
            out_fd.write(
                u'<dt><span class="dlt_rationale">Rationale</span>'
                '</dt><dd><span class="dlv_rationale">%s</span></dd>' %
                self.__markup.replace_par(
                    req.get_value("Rationale").get_content()))

        if req.is_value_available("Note") \
           and req.get_value("Note") is not None:
            out_fd.write(u'<dt><span class="dlt_note">Note</span></dt>'
                         '<dd><span class="dlv_note">%s</span></dd>' %
                         req.get_value("Note").get_content())

        # Only output the depends on when there are fields for output.
        if req.incoming:
            # Create links to the corresponding labels.
            out_fd.write(u'<dt><span class="dlt_depends_on">Depends on:'
                         '</span></dt><dd><span class="dlv_depends_on">')
            is_first = True
            for iid in sorted(req.incoming, key=lambda r: r.get_id()):
                if not is_first:
                    out_fd.write(u", ")
                is_first = False
                out_fd.write(
                    u'<a href="%s.html#%s">%s</a>' %
                    (iid.get_value("Topic"), iid.get_id(), iid.get_id()))
            out_fd.write(u"</span></dd>")

        if req.outgoing:
            # Create links to the corresponding dependency nodes.
            out_fd.write(u'<dt><span class="dlt_dependent">Dependent'
                         '</span></dt><dd><span class="dlv_dependent">')
            is_first = True
            for iid in sorted(req.outgoing, key=lambda r: r.get_id()):
                if not is_first:
                    out_fd.write(u", ")
                is_first = False
                out_fd.write(
                    u'<a href="%s.html#%s">%s</a>' %
                    (iid.get_value("Topic"), iid.get_id(), iid.get_id()))
            out_fd.write(u"</span></dd>")

        status = req.get_value("Status").get_output_string()
        clstr = req.get_value("Class").get_output_string()

        out_fd.write(
            u'<dt><span class="dlt_id">Id</span></dt>'
            '<dd><span class="dlv_id">%s</span></dd>'
            '<dt><span class="dlt_priority">Priority</span></dt>'
            '<dd><span class="dlv_priority">%4.2f</span></dd>'
            '<dt><span class="dlt_owner">Owner</span></dt>'
            '<dd><span class="dlv_owner">%s</span></dd>'
            '<dt><span class="dlt_invented_on">Invented on</span></dt>'
            '<dd><span class="dlv_invented_on">%s</span></dd>'
            '<dt><span class="dlt_invented_by">Invented by</span></dt>'
            '<dd><span class="dlv_invented_by">%s</span></dd>'
            '<dt><span class="dlt_status">Status</span></dt>'
            '<dd><span class="dlv_status">%s</span></dd>'
            '<dt><span class="dlt_class">Class</span></dt>'
            '<dd><span class="dlv_class">%s</span></dd>' %
            (req.get_id(), req.get_value("Priority") * 10,
             req.get_value("Owner"),
             req.get_value("Invented on").strftime("%Y-%m-%d"),
             req.get_value("Invented by"), status, clstr))
        out_fd.write(u"</dl>")

        # Mark the end of the requirment - then it is possible to add
        # some ruler here
        out_fd.write(u'<div class="requirment_end"> </div>')

    def cmad_topic_continuum_pre(self, topics_continuum):
        '''Save the name.'''
        self.__tc_name = topics_continuum.get_name()

    def cmad_topic_set_pre(self, topic_set):
        '''Save the name.'''
        self.__topic_set = topic_set

    def cmad_topic_set_post(self, _topic_set):
        '''Output symbol with all the HTMLs artifacts inside.'''
        self._cmad_file.write(u"OUTPUT_HTML=")
        for topic_name in self.__topic_name_set:
            self._cmad_file.write(
                u"%s.html " %
                os.path.join(self.__output_directory, topic_name))
        self._cmad_file.write(u"\n")

    def cmad_topic_pre(self, topic):
        '''Create makefile dependencies for given topic.'''
        self.__topic_name_set.append(topic.name)
        self._cmad_file.write(
            u"%s.html: %s %s ${%s}\n%s" %
            (os.path.join(self.__output_directory, topic.name),
             self.html_header_filename, self.html_footer_filename,
             self.__topic_set.create_makefile_name(
                 self.__tc_name, topic.name), self._get_call_rmtoo_line()))

    def cmad_requirement(self, requirement):
        '''Called on requirement level.'''
        self._cmad_file.write(u"REQS+=%s\n" % requirement.get_file_path())

    def cmad(self, reqscont, ofile):
        """Create Makefile Dependencies

        Basic idea: each HTML file is dependend of the approriate topic
        file plus the header and the footer.
        Each html file depends on it's topic file
        """
        # Dependencies of every single topic html page
        for topic in self.topic_set.nodes:
            ofile.write(u"%s.html: %s %s ${%s}\n\t${CALL_RMTOO}\n" %
                        (os.path.join(self.output_dir, topic.name),
                         self.html_header_filename, self.html_footer_filename,
                         self.topic_set.create_makefile_name(topic.name)))

        # All HTML files
        ofile.write("OUTPUT_HTML=")
        for topic in self.topic_set.nodes:
            ofile.write(u"%s.html " %
                        os.path.join(self.output_dir, topic.name))
        ofile.write(u"\n")

    def read_html_arts(self):
        if self.html_header_filename is not None:
            with io.open(self.html_header_filename, "r",
                         encoding="utf-8") as fd:
                self.html_header = fd.read()
        if self.html_footer_filename is not None:
            with io.open(self.html_footer_filename, "r",
                         encoding="utf-8") as fd:
                self.html_footer = fd.read()

    # The real output
    # Note that currently the 'reqscont' is not used in case of topics
    # based output.
    def output(self, reqscont):
        # Currently just pass this to the RequirementSet
        self.output_reqset(reqscont.continuum_latest())

    def output_reqset(self, reqset):
        # Call the topic to write out everything
        self.output_html_topic(self.topic_set.get_master())

    def output_html_topic_output_content(self, fd, topic):
        # Subtopics go in a ul
        ul_open = False
        for t in topic.get_tags():
            tag = t.get_tag()
            val = t.get_content()

            if tag != "SubTopic" and ul_open:
                fd.write(u"</ul></span>")
                ul_open = False

            if tag == "Name":
                # The Name itself depends on the level.
                fd.write(u"<h%d>%s</h%d>\n" %
                         (topic.level + 1, val, topic.level + 1))
                continue

            if tag == "SubTopic":
                if not ul_open:
                    fd.write(u'<span class="subtopiclist"><ul>')
                    ul_open = True

                rtopic = topic.find_outgoing(val)
                # A link to the other file.
                fd.write(u'<li><a href="%s.html">%s</a></li>\n' %
                         (val, rtopic.get_name()))
                self.output_html_topic(rtopic)
                continue

            if tag == "Text":
                fd.write(u'<p><span class="fltext">%s</span></p>\n' %
                         self.__markup.replace(val))
                continue

            if tag == "IncludeRequirements":
                self.output_requirements(fd, topic)
                continue

        if ul_open:
            fd.write(u"</ul></span>")

    def output_html_topic_write_footer(self, fd):
        fd.write(self.html_footer)

    def output_requirements(self, fd, topic):
        # Output must be sorted - to be comparable
        for req in sorted(topic.reqs, key=lambda r: r.get_id()):
            self.output_requirement(fd, req, topic.level + 1)
Ejemplo n.º 10
0
class Html(ExecutorTopicContinuum, CreateMakeDependencies):
    """HTML output module"""

    def __init__(self, oconfig):
        '''Create a graph output object.'''
        tracer.debug("Called: html ouput module constructed.")
        self._config = Cfg(oconfig)
        CreateMakeDependencies.__init__(self)
        self.__fd_stack = []
        self.__topic_name_set = []
        # Take care about the openess of the ul.
        self.__ul_open_stack = []
        self.__output_directory = self._config.get_rvalue('output_directory')
        self.__markup = Markup("html")
        self.__tc_name = None
        self.__topic_set = None
        self.html_header_filename = self._config.get_rvalue('header')
        self.html_footer_filename = self._config.get_rvalue('footer')
        self.read_html_arts()

    def __ouput_html_topic_mkdirs(self):
        '''If not already there, create the directory.'''
        try:
            os.makedirs(self.__output_directory)
        except OSError:
            # It's ok if already there
            pass

    def topic_continuum_sort(self, vcs_commit_ids, topic_sets):
        '''Because graph2 can only one topic continuum,
           the latest (newest) is used.'''
        return [topic_sets[vcs_commit_ids[-1].get_commit()]]

    def topic_set_pre(self, _topics_set):
        '''Do all the file and directory preparation.'''
        self.__ouput_html_topic_mkdirs()

    def __output_html_topic_write_header(self, out_fd):
        '''Write the html header.'''
        out_fd.write(self.html_header)

    def topic_pre(self, topic):
        '''Output one topic.
           This method is called once for each topic and subtopic.'''
        tracer.debug("Called: topic name [%s]", topic.name)
        filename = os.path.join(self.__output_directory, topic.name + ".html")
        out_fd = io.open(filename, "w", encoding="utf-8")
        self.__output_html_topic_write_header(out_fd)
        self.__fd_stack.append(out_fd)
        self.__ul_open_stack.append(False)
        # self.output_html_topic_output_content(fd, topic)

    def topic_post(self, topic):
        '''Write out the footer and do clean ups.'''
        out_fd = self.__fd_stack.pop()
        self.__ul_open_stack.pop()
        self.output_html_topic_write_footer(out_fd)
        out_fd.close()
        tracer.debug("Finished: topic name [%s]", topic.name)

    def topic_name(self, name):
        '''Set the name.'''
        out_fd = self.__fd_stack[-1]
        level = len(self.__fd_stack)
        out_fd.write(u"<h%d>%s</h%d>\n" % (level, name, level))

    def topic_text(self, text):
        '''Called when there is text to be outputted.'''
        out_fd = self.__fd_stack[-1]
        out_fd.write(u'<p><span class="fltext">%s</span></p>\n'
                     % self.__markup.replace(text))

    def topic_sub_pre(self, subtopic):
        '''Prepares a new subtopic output.'''
        out_fd = self.__fd_stack[-1]
        if not self.__ul_open_stack[-1]:
            out_fd.write(u'<span class="subtopiclist"><ul>')
            self.__ul_open_stack[-1] = True
        out_fd.write(u'<li><a href="%s.html">%s</a></li>\n' %
                     (subtopic.get_id(), subtopic.get_topic_name()))

    def topic_sub_post(self, _subtopic):
        '''Write the header for subtopic.'''
        if self.__ul_open_stack[-1]:
            out_fd = self.__fd_stack[-1]
            out_fd.write(u"</ul></span>")
            self.__ul_open_stack[-1] = False

    def requirement_set_sort(self, list_to_sort):
        '''Sort by id.'''
        return sorted(list_to_sort, key=lambda r: r.get_id())

    def requirement(self, req):
        '''Output one requirement.'''
        out_fd = self.__fd_stack[-1]
        level = len(self.__fd_stack)

        out_fd.write(u"\n<!-- REQ '%s' -->\n" % req.get_id())
        out_fd.write(u'<h%d><a id="%s">%s</a></h%d>\n' %
                     (level + 1, req.get_id(),
                      req.get_value("Name").get_content(),
                      level + 1))
        out_fd.write(u"<dl>")

        out_fd.write(u'<dt><span class="dlt_description">Description</span>'
                     '</dt><dd><span class="dlv_description">%s</span></dd>' %
                     self.__markup.replace(req.get_value("Description")
                                           .get_content()))

        if req.is_value_available("Rationale") \
                and req.get_value("Rationale") is not None:
            out_fd.write(
                u'<dt><span class="dlt_rationale">Rationale</span>'
                '</dt><dd><span class="dlv_rationale">%s</span></dd>'
                % self.__markup.replace_par(req.get_value("Rationale").
                                            get_content()))

        if req.is_value_available("Note") \
           and req.get_value("Note") is not None:
            out_fd.write(u'<dt><span class="dlt_note">Note</span></dt>'
                         '<dd><span class="dlv_note">%s</span></dd>'
                         % req.get_value("Note").get_content())

        # Only output the depends on when there are fields for output.
        if req.incoming:
            # Create links to the corresponding labels.
            out_fd.write(u'<dt><span class="dlt_depends_on">Depends on:'
                         '</span></dt><dd><span class="dlv_depends_on">')
            is_first = True
            for iid in sorted(req.incoming, key=lambda r: r.get_id()):
                if not is_first:
                    out_fd.write(u", ")
                is_first = False
                out_fd.write(
                    u'<a href="%s.html#%s">%s</a>' %
                    (iid.get_value("Topic"), iid.get_id(), iid.get_id()))
            out_fd.write(u"</span></dd>")

        if req.outgoing:
            # Create links to the corresponding dependency nodes.
            out_fd.write(u'<dt><span class="dlt_dependent">Dependent'
                         '</span></dt><dd><span class="dlv_dependent">')
            is_first = True
            for iid in sorted(req.outgoing, key=lambda r: r.get_id()):
                if not is_first:
                    out_fd.write(u", ")
                is_first = False
                out_fd.write(
                    u'<a href="%s.html#%s">%s</a>' %
                    (iid.get_value("Topic"), iid.get_id(), iid.get_id()))
            out_fd.write(u"</span></dd>")

        status = req.get_value("Status").get_output_string()
        clstr = req.get_value("Class").get_output_string()

        out_fd.write(
            u'<dt><span class="dlt_id">Id</span></dt>'
            '<dd><span class="dlv_id">%s</span></dd>'
            '<dt><span class="dlt_priority">Priority</span></dt>'
            '<dd><span class="dlv_priority">%4.2f</span></dd>'
            '<dt><span class="dlt_owner">Owner</span></dt>'
            '<dd><span class="dlv_owner">%s</span></dd>'
            '<dt><span class="dlt_invented_on">Invented on</span></dt>'
            '<dd><span class="dlv_invented_on">%s</span></dd>'
            '<dt><span class="dlt_invented_by">Invented by</span></dt>'
            '<dd><span class="dlv_invented_by">%s</span></dd>'
            '<dt><span class="dlt_status">Status</span></dt>'
            '<dd><span class="dlv_status">%s</span></dd>'
            '<dt><span class="dlt_class">Class</span></dt>'
            '<dd><span class="dlv_class">%s</span></dd>'
            % (req.get_id(), req.get_value("Priority") * 10,
               req.get_value("Owner"),
               req.get_value("Invented on").strftime("%Y-%m-%d"),
               req.get_value("Invented by"), status, clstr))
        out_fd.write(u"</dl>")

        # Mark the end of the requirment - then it is possible to add
        # some ruler here
        out_fd.write(u'<div class="requirment_end"> </div>')

    def cmad_topic_continuum_pre(self, topics_continuum):
        '''Save the name.'''
        self.__tc_name = topics_continuum.get_name()

    def cmad_topic_set_pre(self, topic_set):
        '''Save the name.'''
        self.__topic_set = topic_set

    def cmad_topic_set_post(self, _topic_set):
        '''Output symbol with all the HTMLs artifacts inside.'''
        self._cmad_file.write(u"OUTPUT_HTML=")
        for topic_name in self.__topic_name_set:
            self._cmad_file.write(u"%s.html " % os.path.join(
                self.__output_directory, topic_name))
        self._cmad_file.write(u"\n")

    def cmad_topic_pre(self, topic):
        '''Create makefile dependencies for given topic.'''
        self.__topic_name_set.append(topic.name)
        self._cmad_file.write(
            u"%s.html: %s %s ${%s}\n%s" %
            (os.path.join(self.__output_directory, topic.name),
             self.html_header_filename,
             self.html_footer_filename,
             self.__topic_set.create_makefile_name(self.__tc_name, topic.name),
             self._get_call_rmtoo_line()))

    def cmad_requirement(self, requirement):
        '''Called on requirement level.'''
        self._cmad_file.write(u"REQS+=%s\n" % requirement.get_file_path())

    def cmad(self, reqscont, ofile):
        """Create Makefile Dependencies

        Basic idea: each HTML file is dependend of the approriate topic
        file plus the header and the footer.
        Each html file depends on it's topic file
        """
        # Dependencies of every single topic html page
        for topic in self.topic_set.nodes:
            ofile.write(u"%s.html: %s %s ${%s}\n\t${CALL_RMTOO}\n" %
                        (os.path.join(self.output_dir, topic.name),
                         self.html_header_filename,
                         self.html_footer_filename,
                         self.topic_set.create_makefile_name(topic.name)))

        # All HTML files
        ofile.write("OUTPUT_HTML=")
        for topic in self.topic_set.nodes:
            ofile.write(u"%s.html " % os.path.join(
                self.output_dir, topic.name))
        ofile.write(u"\n")

    def read_html_arts(self):
        if self.html_header_filename is not None:
            with io.open(self.html_header_filename, "r",
                         encoding="utf-8") as fd:
                self.html_header = fd.read()
        if self.html_footer_filename is not None:
            with io.open(self.html_footer_filename, "r",
                         encoding="utf-8") as fd:
                self.html_footer = fd.read()

    # The real output
    # Note that currently the 'reqscont' is not used in case of topics
    # based output.
    def output(self, reqscont):
        # Currently just pass this to the RequirementSet
        self.output_reqset(reqscont.continuum_latest())

    def output_reqset(self, reqset):
        # Call the topic to write out everything
        self.output_html_topic(self.topic_set.get_master())

    def output_html_topic_output_content(self, fd, topic):
        # Subtopics go in a ul
        ul_open = False
        for t in topic.get_tags():
            tag = t.get_tag()
            val = t.get_content()

            if tag != "SubTopic" and ul_open:
                fd.write(u"</ul></span>")
                ul_open = False

            if tag == "Name":
                # The Name itself depends on the level.
                fd.write(u"<h%d>%s</h%d>\n" % (topic.level + 1, val,
                                               topic.level + 1))
                continue

            if tag == "SubTopic":
                if not ul_open:
                    fd.write(u'<span class="subtopiclist"><ul>')
                    ul_open = True

                rtopic = topic.find_outgoing(val)
                # A link to the other file.
                fd.write(u'<li><a href="%s.html">%s</a></li>\n' %
                         (val, rtopic.get_name()))
                self.output_html_topic(rtopic)
                continue

            if tag == "Text":
                fd.write(u'<p><span class="fltext">%s</span></p>\n'
                         % self.__markup.replace(val))
                continue

            if tag == "IncludeRequirements":
                self.output_requirements(fd, topic)
                continue

        if ul_open:
            fd.write(u"</ul></span>")

    def output_html_topic_write_footer(self, fd):
        fd.write(self.html_footer)

    def output_requirements(self, fd, topic):
        # Output must be sorted - to be comparable
        for req in sorted(topic.reqs, key=lambda r: r.get_id()):
            self.output_requirement(fd, req, topic.level + 1)