Append an execute external command entry to the journal.

        This instructs Revit to execute the provided command from the
        provided module, tab, and panel.

        Args:
            tab_name (str): name of ribbon tab that contains the command
            panel_name (str): name of ribbon panel that contains the command
            command_module (str): name of module that provides the command
            command_class (str): name of command class inside command module
            command_data (dict): dict of string data to be passed to command

        Examples:
            >>> jm = JournalMaker()
            >>> cmdata = {'key1':'value1', 'key2':'value2'}
            >>> jm.execute_command(tab_name='Add-Ins',
            ...                    panel_name='Panel Name',
            ...                    command_module='Addon App Namespace',
            ...                    command_class='Command Classname',
            ...                    command_data=cmdata)

def execute_command(self, tab_name, panel_name,
                        command_module, command_class, command_data=None):
        """Append an execute external command entry to the journal.

        This instructs Revit to execute the provided command from the
        provided module, tab, and panel.

        Args:
            tab_name (str): name of ribbon tab that contains the command
            panel_name (str): name of ribbon panel that contains the command
            command_module (str): name of module that provides the command
            command_class (str): name of command class inside command module
            command_data (dict): dict of string data to be passed to command

        Examples:
            >>> jm = JournalMaker()
            >>> cmdata = {'key1':'value1', 'key2':'value2'}
            >>> jm.execute_command(tab_name='Add-Ins',
            ...                    panel_name='Panel Name',
            ...                    command_module='Addon App Namespace',
            ...                    command_class='Command Classname',
            ...                    command_data=cmdata)
        """
        # make sure command_data is not empty
        command_data = {} if command_data is None else command_data
        # make the canonical name for the command
        cmdclassname = '{}.{}'.format(command_module, command_class)

        self._add_entry(templates.EXTERNAL_COMMAND
                                 .format(external_command_tab=tab_name,
                                         external_command_panel=panel_name,
                                         command_class_name=command_class,
                                         command_class=cmdclassname))

        # count the data
        data_count = len(command_data.keys())

        # create the entry for the command data
        if data_count > 0:
            data_str_list = []
            for k, v in command_data.items():
                data_str_list.append(' "{}" , "{}"'.format(k, v))

            data_str = '_\n    ,'.join(data_str_list)
            self._add_entry(templates.EXTERNAL_COMMANDDATA
                                     .format(data_count=data_count,
                                             data_string=data_str))