Beispiel #1
0
    def __init__(self) -> None:
        """Initialise main window
        """
        super().__init__()
        if which("pandoc") is None and sys.platform.startswith("win32"):
            os.environ.setdefault("PYPANDOC_PANDOC",
                                  get_resource("pandoc-2.13/pandoc.exe"))
        self.date_opened = date.today()
        self.refresh_stylesheet()

        # Load config
        config_file = get_resource("config.json")
        with open(config_file, "r") as file:
            config_dict = json.loads(file.read())

        self.no_journal_dialog = QtWidgets.QMessageBox()
        self.no_journal_dialog.setText("No journal directory configured")
        self.no_journal_dialog.setStandardButtons(QtWidgets.QMessageBox.Close
                                                  | QtWidgets.QMessageBox.Open)
        self.no_journal_dialog.setDefaultButton(QtWidgets.QMessageBox.Open)

        # Folder is not an absolute folder
        try:
            if not (config_dict['diary_directory'][0] == '/'
                    or config_dict['diary_directory'][1] == ':'
                    ) or not os.path.exists(config_dict['diary_directory']):
                answer = self.no_journal_dialog.exec()
                if answer == QtWidgets.QMessageBox.Open:
                    self.select_diary_directory()
                else:
                    exit(0)
        except IndexError:
            answer = self.no_journal_dialog.exec()
            if answer == QtWidgets.QMessageBox.Open:
                self.select_diary_directory()
            else:
                exit(0)

        # Layout
        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        # Edit pane
        self.edit_pane = EditPane()

        self.web_view = WebView(self.edit_pane)

        # Menu bar and adding panes underneath
        self.tool_bar = CustomToolbar(self, self.edit_pane, self.web_view)

        self.layout.addWidget(self.tool_bar)
        self.layout.addWidget(self.edit_pane)
        self.layout.addWidget(self.web_view)

        self.edit_pane.open_file_from_date(date.today())
Beispiel #2
0
    def open_file_from_date(self, file_date: date):
        """Open or create a markdown file corresponding to today"""
        formatted_date = file_date.strftime("%Y-%m-%d")

        # Add ordinal to end of number if it exists
        try:
            day_of_month = num2words(file_date.day,
                                     to="ordinal_num",
                                     lang=locale.getlocale()[0])
        except NotImplementedError:
            day_of_month = file_date.day

        long_date = file_date.strftime(f"%A {day_of_month} %B %Y")

        # Get folder for today's journal entry
        config_file = get_resource("config.json")
        with open(config_file, "r") as file:
            file_directory = os.path.join(
                json.loads(file.read())["diary_directory"],
                str(file_date.year), str(file_date.month), formatted_date)

        # Make folder for today's entry if not already exist
        print(get_resource("config.json"))
        if not os.path.exists(file_directory):
            pathlib.Path(file_directory).mkdir(parents=True, exist_ok=True)

        # Open markdown in r+ mode if it exists, else open in w+ mode
        try:
            with open(os.path.join(file_directory, f"{formatted_date}.md"),
                      "r+") as file:
                self.set_current_file(file)

        except FileNotFoundError:
            with open(os.path.join(file_directory, f"{formatted_date}.md"),
                      "w+") as file:
                self.set_current_file(file)
                self.setText('---\n'
                             f'title: {long_date}\n'
                             f'date: {formatted_date}\n'
                             'tags: []\n'
                             '---\n')
        self.save_current_file()
        self.file_changed.emit()
        self.window().setWindowTitle(long_date)
        self.set_margins()
Beispiel #3
0
    def refresh_page(self):
        """Convert markdown to html and set webView"""
        parsed_stylesheet = parse_stylesheet(get_resource('ViewPaneStyle.css'),
                                             CONSTANTS.theme)

        # Write parsed stylesheet to file so it can be passed to pandoc
        with open(get_resource("parsed_stylesheet.css"), "w") as file:
            file.write(parsed_stylesheet)

        # Convert markdown to html using pandoc
        html = pypandoc.convert_text(
            self.edit_pane.toPlainText(),
            "html",
            format="markdown",
            extra_args=[
                f"--highlight-style={get_resource('syntax.theme')}", "-s",
                "--css="
                f"{get_resource('parsed_stylesheet.css')}",
                f"--katex={get_resource('katex/')}"
            ])
        self.setHtml(html,
                     QtCore.QUrl().fromLocalFile(self.edit_pane.current_file))
Beispiel #4
0
    def paintCell(self, painter: QtGui.QPainter, rect: QtCore.QRect,
                  date: typing.Union[QtCore.QDate, datetime.date]) -> None:
        painter.save()
        with open(get_resource("config.json")) as file:
            if date.toPyDate().strftime("%Y-%m-%d") in json.loads(
                    file.read())["favorites"]:
                painter.fillRect(rect, QtGui.QColor.fromRgb(255, 255, 0))
        if (date.month() != self.monthShown()):
            painter.setPen(QtGui.QColor("#888888"))
        elif date.dayOfWeek() == 6 or date.dayOfWeek() == 7:
            painter.setPen(QtGui.QColor("red"))

        tags = self.get_tags_from_date_file(date.toPyDate())
        rect.adjust(0, 0, -1, -1)
        pen = painter.pen()
        pen.setColor(
            QtGui.QColor.fromHsl(pen.color().hue(),
                                 pen.color().saturation(),
                                 pen.color().lightness(), 150))
        painter.setPen(pen)
        painter.drawRect(rect)
        pen.setColor(
            QtGui.QColor.fromHsl(pen.color().hue(),
                                 pen.color().saturation(),
                                 pen.color().lightness(), 255))
        painter.setPen(pen)

        painter.drawText(rect, QtCore.Qt.AlignTop, str(date.day()))
        text = ""
        try:
            for tag in tags[:5]:
                if len(tag) > 12:
                    tag = str(tag[:12]) + "..."
                text += f" {tag} \n"
        except TypeError:
            text = ""
        font = QtGui.QFont()
        font.setPixelSize(10)
        painter.setFont(font)
        brush = painter.background()
        random.seed(date)
        brush.setColor(QtGui.QColor().fromHsl(randint(0, 255), randint(0, 255),
                                              randint(200, 255)))
        painter.setPen(QtGui.QColor("black"))
        painter.setBackground(brush)
        painter.setBackgroundMode(QtCore.Qt.OpaqueMode)
        painter.drawText(rect, QtCore.Qt.AlignBottom | QtCore.Qt.AlignHCenter,
                         text)
        painter.restore()
Beispiel #5
0
    def createCustomContextMenu(self, pos) -> QtWidgets.QMenu:
        menu = self.createStandardContextMenu()
        menu.addSeparator()
        add_icon = QtGui.QIcon(
            get_resource(CONSTANTS.icons["plus"][CONSTANTS.theme]))
        if sys.platform != "win32":  # Don't add plus icon on windows (looks ugly)
            menu.addAction(add_icon, "Insert Image", self.insert_image)
        else:
            menu.addAction("Insert Image", self.insert_image)
        menu.addSeparator()
        self.word_cursor = self.cursorForPosition(pos)
        self.word_cursor.select(QtGui.QTextCursor.WordUnderCursor)
        # Find misspelled word in highlighted text
        misspelled = [
            token[0]
            for token in self.spell_tknzr(self.word_cursor.selectedText())
            if token[0][0].islower() and not spell_dict.check(token[0])
        ]

        # If there is a misspelled word and the word matches the whole of the highlighted text
        if len(misspelled
               ) > 0 and misspelled[0] == self.word_cursor.selectedText():
            # Add 'Add to Dictionary option'
            self.add_to_dict_action_handler = ActionHandler(
                menu.addAction("Add to dictionary"), self.add_to_word_list)
            menu.addSeparator()

            spell_suggestion_handlers = []
            # Get spelling suggestions
            spell_suggestions = spell_dict.suggest(misspelled[0])
            # Add suggestions to menu until there is no more left or a maximum of 10
            while len(spell_suggestion_handlers) < 10 and len(
                    spell_suggestion_handlers) < len(spell_suggestions):
                for suggestion in spell_suggestions:
                    new_action = menu.addAction(suggestion)
                    spell_suggestion_handlers.append(
                        ActionHandler(new_action, self.replace_selection))

            # Save suggestion handlers to object so they persist
            self.spell_suggestion_handlers = spell_suggestion_handlers

            if len(self.spell_suggestion_handlers) == 0:
                no_suggestions = menu.addAction("No Suggestions")
                no_suggestions.setEnabled(False)

        return menu
Beispiel #6
0
    def select_diary_directory(self):
        """Request user to select a directory and set it to diary_directory in config
        """
        # TODO: Maybe change so only create folder on first save
        config_file = get_resource("config.json")
        with open(config_file, "r") as file:
            config_dict = json.loads(file.read())
            file_dialog = QtWidgets.QFileDialog()
            old_dir = config_dict["diary_directory"]

            # Need non-native file in flatpak to get correct directory
            if sys.platform.startswith("linux"):
                config_dict[
                    "diary_directory"] = file_dialog.getExistingDirectory(
                        self,
                        "Please select a directory to store your journal files",
                        "", QtWidgets.QFileDialog.ShowDirsOnly
                        | QtWidgets.QFileDialog.DontUseNativeDialog)
            else:
                config_dict[
                    "diary_directory"] = file_dialog.getExistingDirectory(
                        self,
                        "Please select a directory to store your journal files",
                        "")
            print(config_dict["diary_directory"])

        # Cancel has been clicked
        if config_dict["diary_directory"] == "":
            if os.path.exists(old_dir):
                config_dict["diary_directory"] = old_dir
            else:
                exit(0)
        with open(config_file, "w") as file:
            file.write(json.dumps(config_dict, sort_keys=True, indent=4))
        try:
            self.edit_pane.open_file_from_date(
                date.fromisoformat(self.edit_pane.current_file_date))
        except AttributeError:
            print("First time boot")
Beispiel #7
0
    def get_tags_from_date_file(self, date: datetime.date):
        """Open or create a markdown file corresponding to today"""
        formatted_date = date.strftime("%Y-%m-%d")

        # Get folder for today's journal entry
        config_file = get_resource("config.json")
        with open(config_file, "r") as file:
            file_directory = os.path.join(
                json.loads(file.read())["diary_directory"], str(date.year),
                str(date.month), formatted_date)

        try:
            with open(os.path.join(file_directory, f"{formatted_date}.md"),
                      "r") as file:
                pattern = regex.compile(r"(?<=(^-{3,}\n)).+?(?=-{3,})",
                                        regex.DOTALL)
                contents = file.read()
                metadata = regex.search(pattern, contents)
            if metadata is not None:
                meta_dict = yaml.safe_load(metadata.group())
                if "tags" in meta_dict.keys():
                    return meta_dict["tags"]
        except Exception:
            return {}
Beispiel #8
0
    def __init__(self, edit_pane: EditPane, web_view: WebView):
        """Constructor
        :param edit_pane: EditPane to open the new file in
        """
        super().__init__()
        self.edit_pane = edit_pane
        self.web_view = web_view
        self.setWindowFlag(QtCore.Qt.Dialog)

        date = self.edit_pane.current_file_date.split("-")
        self.setSelectedDate(
            QtCore.QDate(int(date[0]), int(date[1]), int(date[2])))

        self.selectionChanged.connect(self.selection_changed_handler)

        self.layout = QtWidgets.QVBoxLayout()
        self.setVerticalHeaderFormat(self.NoVerticalHeader)
        self.setMinimumSize(640, 640)
        self.setMaximumSize(640, 640)
        self.setWindowTitle("Calendar")

        self.setStyleSheet("""
        QMenu { 
            font-size:16px; 
            width: 150px; 
            left: 20px; 
            background-color: palette(base);
        }
        QWidget{
            background-color: palette(base);
        }
        QToolButton {
            icon-size: 24px, 24px;
            background-color: palette(base);
            color: palette(text);
        }
        QAbstractItemView {
            selection-background-color: rgb(255, 174, 0);
        }
        QToolButton::menu-arrow {
        }
        QToolButton::menu-button {
        }
        QToolButton::menu-indicator{
            width: 50px;
        }
        QToolButton::menu-indicator:pressed, QToolButton::menu-indicator:open{
            top:10px; 
            left: 10px;
        }
        QListView {
            background-color:white;
        }
        QSpinBox {
            width:200px; 
            border-width: 2px;
        }
        QSpinBox::up-button { 
            subcontrol-origin: border;
            subcontrol-position: top right; 
            width:50px; border-image: url(icons:arrow_up_n.png);
        }
        QSpinBox::down-button {
            subcontrol-origin: border; 
            subcontrol-position: bottom right;
            border-width: 1px; 
            width:10px;
            }
        QSpinBox::down-arrow { 
            width:6px; 
            height:6px;
        image: url(icons:arrow_down_n.png); 
        }
        QMenu::item:selected{
            background-color: palette(highlight);
        }
""")

        # Set format of how favorites appear in calendar
        favorite_format = QtGui.QTextCharFormat()
        favorite_brush = QtGui.QBrush()
        favorite_brush.setColor(QtGui.QColor.fromRgb(255, 228, 0))
        favorite_format.setBackground(favorite_brush)
        favorite_brush.setColor(QtGui.QColor.fromRgb(33, 33, 33))
        favorite_format.setForeground(favorite_brush)

        prev_month_button = self.findChild(QtWidgets.QToolButton,
                                           "qt_calendar_prevmonth")
        next_month_button = self.findChild(QtWidgets.QToolButton,
                                           "qt_calendar_nextmonth")
        prev_month_button.setIcon(
            QtGui.QIcon(
                get_resource(CONSTANTS.icons["left_arrow"][CONSTANTS.theme])))
        next_month_button.setIcon(
            QtGui.QIcon(
                get_resource(CONSTANTS.icons["right_arrow"][CONSTANTS.theme])))

        with open(get_resource("config.json")) as file:
            for day in json.loads(file.read())["favorites"]:
                formatted_date = [int(x) for x in day.split("-")]
                self.setDateTextFormat(
                    QtCore.QDate(formatted_date[0], formatted_date[1],
                                 formatted_date[2]), favorite_format)
Beispiel #9
0
    def license_clicked(self):
        self.license_window = QtWidgets.QTextBrowser()
        self.license_window.setFixedSize(600, 600)
        self.license_window.setFont(
            QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont))
        self.license_window.setStyleSheet(
            "background-color: palette(base); border: 0px solid white;")

        license_text = """
All of the source code to this product is available under licenses which are both free and open source. 
Most of the code is available under the GNU General Public License 3.0, the licenses of included software, as well as 
that of the main software is listed below.
            """

        with open(get_resource("licenses/gpl-3.0.txt")) as file:
            license_text += '\n\nLicense used by main source available at <https://github.com/LukeBriggsDev/Pepys>' \
                            'as well as PyQt5 <https://www.riverbankcomputing.com/static/Docs/PyQt5/>\n\n'
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/num2words_license.txt")) as file:
            license_text += "License used by python library num2words <https://github.com/savoirfairelinux/num2words>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/pandoc_license.txt")) as file:
            license_text += "License used by pandoc binary <https://github.com/jgm/pandoc>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/pyenchant_license.txt")) as file:
            license_text += "License used by python library pyenchant <https://github.com/pyenchant/pyenchant>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/pypandoc_LICENSE.txt")) as file:
            license_text += "License used by python library pypandoc <https://github.com/bebraw/pypandoc>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/pypdf4_license.txt")) as file:
            license_text += "License used by python library PyPDF4 <https://github.com/claird/PyPDF4>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/pyyaml_license.txt")) as file:
            license_text += "License used by python library pyYAML <https://github.com/yaml/pyyaml>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/regex_license.txt")) as file:
            license_text += "License used by python library regex <https://bitbucket.org/mrabarnett/mrab-regex>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/setproctitle_license.txt")) as file:
            license_text += "License used by python library setproctitle <https://github.com/dvarrazzo/py-setproctitle>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        with open(get_resource("licenses/wkhtmltopdf_license.txt")) as file:
            license_text += "License used by wkhtmltopdf binary <https://github.com/wkhtmltopdf/wkhtmltopdf>\n\n"
            license_text += file.read(
            ) + "\n\n=============================================================================\n\n"

        self.license_window.setText(license_text)
        self.license_window.show()
Beispiel #10
0
from CONSTANTS import get_resource
import CONSTANTS
from pypandoc.pandoc_download import download_pandoc
import pypandoc

from MainWindow import MainWindow

if __name__ == "__main__":
    if sys.platform.lower().startswith("linux"):
        os.putenv("QT_QPA_PLATFORM", "xcb")
    if sys.platform.startswith("win32"):
        import ctypes
        myappid = 'dev.lukebriggs.pepys'  # arbitrary string
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

    if not os.path.isfile(get_resource("wordlist.txt")):
        with open(get_resource("wordlist.txt"), "w+") as file:
            file.write("")
    app = QtWidgets.QApplication(sys.argv)
    app.setApplicationName("Pepys")
    app.setApplicationDisplayName("Pepys")
    app.setWindowIcon(QtGui.QIcon(get_resource("icons/appicons/icon.svg")))
    CONSTANTS.theme = "light" if QtWidgets.QApplication.palette().color(
        QtGui.QPalette.Active,
        QtGui.QPalette.Base).lightness() > 122 else "dark"
    CONSTANTS.light_palette = QtWidgets.QApplication.palette()
    setproctitle.setproctitle("Pepys")
    #Initialise and set size of main_window
    main_window = MainWindow()
    main_window.resize(800, 600)
    main_window.setMinimumSize(640, 480)
Beispiel #11
0
    def export_diary(self):

        # Load dialog
        self.load_dialog = QtWidgets.QDialog(self)
        self.load_dialog.setWindowModality(QtCore.Qt.WindowModal)
        self.load_dialog.setMinimumSize(400, 100)
        self.load_dialog.setMaximumSize(400, 100)
        self.load_dialog.setWindowTitle("Exporting...")
        progress_label = QtWidgets.QLabel()
        progress_label.setAlignment(QtCore.Qt.AlignCenter)
        progress_bar = QtWidgets.QProgressBar()
        progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.load_dialog.setLayout(QtWidgets.QVBoxLayout())
        self.load_dialog.layout().setAlignment(QtCore.Qt.AlignTop)
        self.load_dialog.layout().addWidget(progress_label)
        self.load_dialog.layout().addWidget(progress_bar)
        self.load_dialog.show()
        self.setDisabled(True)
        self.load_dialog.setEnabled(True)

        with open(get_resource("config.json"), "r") as file:
            directory = json.loads(file.read())["diary_directory"]

        if not os.path.exists(self.chosen_directory.text()):
            try:
                os.mkdir(os.path.join(Path(directory), "export"))
            except FileExistsError:
                shutil.rmtree(os.path.join(Path(directory), "export"), ignore_errors=True)
                os.mkdir(os.path.join(Path(directory), "export"))

            self.chosen_directory.setText(os.path.join(directory, "export"))

        diary_entries = list(Path(directory).rglob("*-*-*.[mM][dD]"))

        # Custom Range
        if self.date_options.currentText() == "Custom Range":
            diary_entries = [entry for entry in diary_entries
                             if self.start_date_widget.date().toString("yyyy-MM-dd") <= entry.name[:-3] <= self.end_date_widget.date().toString("yyyy-MM-dd")]

        # Current Date
        if self.date_options.currentText() == "Current Entry":
            diary_entries = list(Path(directory).rglob(f"{self.edit_pane.current_file_date}.[mM][dD]"))

        format = self.output_formats[self.export_options.currentText()]


        pdoc_args = ["--standalone",
                     f"--katex={get_resource('katex/')}"]

        if format["type"] == "pdf":
            # Convert to html before pdf to apply css
            pdoc_args.append("-thtml")
            if sys.platform.startswith("win32") and shutil.which("wkhtmltopdf") is None:
                pdoc_args.append(f"--pdf-engine={get_resource('wkhtmltopdf.exe')}")
            pass

        if format["type"] == "html" or format["type"] == "pdf":
            with open(get_resource("parsed_stylesheet.css"), "w+") as f:
                f.write(parse_stylesheet(get_resource("ViewPaneStyle.css"), "light"))
            pdoc_args.append("--css="+get_resource("HTMLExport.css"))
            pdoc_args.append("--self-contained")
            pdoc_args.append("--pdf-engine-opt=--enable-local-file-access")


        progress_label.setText("Converting to " + str(format["type"]))
        progress_bar.setMaximum(len(diary_entries))
        QtWidgets.QApplication.processEvents()
        finished = 0
        errors = []
        # Conversion
        for entry in diary_entries:
            if self.load_dialog.isVisible():
                os.chdir(entry.parent.as_posix())
                try:
                    pypandoc.convert_file(entry.as_posix(), format["type"],
                                          outputfile=(self.chosen_directory.text() + "/" + entry.name[:-3] + "." + format["ext"]),
                                          extra_args=pdoc_args)
                except RuntimeError as err:
                    progress_label.setText("ERROR IN FILE " + entry.name)
                    QtWidgets.QApplication.processEvents()
                    print(str(err))
                    errors.append(entry)
                    if str(err).startswith('Pandoc died with exitcode "47"'):
                        self.load_dialog.setMinimumSize(550, 150)
                        self.load_dialog.setMaximumSize(550, 150)
                        progress_bar.setVisible(False)
                        exit_button = QtWidgets.QPushButton("Close")
                        self.load_dialog.layout().addWidget(exit_button)
                        exit_button.clicked.connect(self.load_dialog.close)
                        progress_label.setText("No wkhtmltopdf installation found.\n"
                                               "Please install wkhtmltopdf.\n\n")
                        return 1
                    print(err)
                finished += 1
                progress_label.setText(str(finished) + "/" + str(len(diary_entries)))
                progress_bar.setValue(finished)
                QtWidgets.QApplication.processEvents()
            else:
                return 2
        progress_label.setText("Conversion finished")
        QtWidgets.QApplication.processEvents()

        if self.will_collate.isChecked():
            # Collate pdfs together into one pdf
            if format["type"] == "pdf":
                progress_label.setText("Starting pdf collation")
                QtWidgets.QApplication.processEvents()
                file_merger = PyPDF4.PdfFileMerger(strict=False)
                pdf_list = sorted([Path(os.path.join(self.chosen_directory.text(), entry.name[:-3] + ".pdf"))
                                   for entry in diary_entries
                                   if os.path.isfile(os.path.join(self.chosen_directory.text(), entry.name[:-3] + ".pdf"))],
                                   key=lambda x: x.name)

                for pdf in pdf_list:
                    progress_label.setText(pdf.name)
                    QtWidgets.QApplication.processEvents()
                    file_merger.append(pdf.as_posix(), pdf.name[:-4], import_bookmarks=False)
                    try:
                        os.remove(pdf.as_posix())
                    except PermissionError:
                        pass
                file_merger.write(self.chosen_directory.text() + "/diary.pdf")
                progress_label.setText("pdf collation finished")
                QtWidgets.QApplication.processEvents()

            # Collate html together into one pdf
            if format["type"] == "html":
                progress_label.setText("Starting html collation")
                QtWidgets.QApplication.processEvents()
                html_list = sorted([Path(os.path.join(self.chosen_directory.text(), entry.name[:-3] + ".html"))
                                    for entry in diary_entries
                                    if os.path.isfile(os.path.join(self.chosen_directory.text(), entry.name[:-3] + ".html"))],
                                    key=lambda x: x.name)
                html = ""
                try:
                    os.mkdir(os.path.join(Path(self.chosen_directory.text()), "html_export"))
                except FileExistsError:
                    shutil.rmtree(os.path.join(Path(self.chosen_directory.text()), "html_export"), ignore_errors=True)
                    os.mkdir(os.path.join(Path(self.chosen_directory.text()), "html_export"))

                for document in html_list:
                    shutil.move(document, os.path.join(Path(self.chosen_directory.text()), "html_export", document.name))

                with open(os.path.join(Path(self.chosen_directory.text()), "html_export", "_index.html"), "w") as f:
                    shutil.copyfile(get_resource("parsed_stylesheet.css"), os.path.join(Path(self.chosen_directory.text()), "html_export", "styles.css"))
                    f.write('<!DOCTYPE HTML>'
                            '<HTML>'
                            '<HEAD><LINK rel="stylesheet" href="styles.css" type="text/css">'
                            '</HEAD>')
                    for page in html_list:
                        f.write(f'<a href="{page.name}">{page.name[:-5]}</a><br>')
                    f.write('</HTMl>')

                progress_label.setText("HTML collation finished")
                QtWidgets.QApplication.processEvents()

        print(self.chosen_directory.text())
        if len(errors) > 0:
            self.error_dialog = QtWidgets.QMessageBox()
            self.error_dialog.setText("Errors occured in the following entries and they were not converted.\n\nPerhaps they link to files that do not exist")
            self.error_dialog.setInformativeText("\n".join([str(error) for error in errors]))
            self.error_dialog.show()
        CONSTANTS.openFolder(self.chosen_directory.text())
        self.load_dialog.close()