diff --git a/nw/convert/htmlfile.py b/nw/convert/file/html.py
similarity index 91%
rename from nw/convert/htmlfile.py
rename to nw/convert/file/html.py
index 0b175e77..b5acaf2e 100644
--- a/nw/convert/htmlfile.py
+++ b/nw/convert/file/html.py
@@ -13,9 +13,9 @@
import logging
import nw
-from nw.convert.textfile import TextFile
-from nw.convert.tohtml import ToHtml
-from nw.enum import nwAlert
+from nw.convert.file.text import TextFile
+from nw.convert.text.tohtml import ToHtml
+from nw.enum import nwAlert
logger = logging.getLogger(__name__)
diff --git a/nw/convert/latexfile.py b/nw/convert/file/latex.py
similarity index 90%
rename from nw/convert/latexfile.py
rename to nw/convert/file/latex.py
index 448236ff..cdaeb66e 100644
--- a/nw/convert/latexfile.py
+++ b/nw/convert/file/latex.py
@@ -13,9 +13,9 @@
import logging
import nw
-from nw.convert.textfile import TextFile
-from nw.convert.tolatex import ToLaTeX
-from nw.enum import nwAlert
+from nw.convert.file.text import TextFile
+from nw.convert.text.tolatex import ToLaTeX
+from nw.enum import nwAlert
logger = logging.getLogger(__name__)
diff --git a/nw/convert/markdownfile.py b/nw/convert/file/markdown.py
similarity index 86%
rename from nw/convert/markdownfile.py
rename to nw/convert/file/markdown.py
index 0f490d1e..b5d2c32c 100644
--- a/nw/convert/markdownfile.py
+++ b/nw/convert/file/markdown.py
@@ -13,9 +13,9 @@
import logging
import nw
-from nw.convert.textfile import TextFile
-from nw.convert.tomarkdown import ToMarkdown
-from nw.enum import nwAlert
+from nw.convert.file.text import TextFile
+from nw.convert.text.tomarkdown import ToMarkdown
+from nw.enum import nwAlert
logger = logging.getLogger(__name__)
diff --git a/nw/convert/textfile.py b/nw/convert/file/text.py
similarity index 96%
rename from nw/convert/textfile.py
rename to nw/convert/file/text.py
index 3ffeb7ff..b4adee27 100644
--- a/nw/convert/textfile.py
+++ b/nw/convert/file/text.py
@@ -16,8 +16,8 @@ import nw
from os import path
from PyQt5.QtWidgets import QMessageBox
-from nw.convert.tokenizer import Tokenizer
-from nw.enum import nwAlert, nwItemLayout
+from nw.convert.text.totext import ToText
+from nw.enum import nwAlert, nwItemLayout
logger = logging.getLogger(__name__)
@@ -36,7 +36,7 @@ class TextFile():
self.expNotes = False
self.winEnding = False
- self.theConv = Tokenizer(self.theProject, self.theParent)
+ self.theConv = ToText(self.theProject, self.theParent)
self.makeAlert = self.theParent.makeAlert
self.setComments(False)
diff --git a/nw/convert/tohtml.py b/nw/convert/text/tohtml.py
similarity index 100%
rename from nw/convert/tohtml.py
rename to nw/convert/text/tohtml.py
diff --git a/nw/convert/tolatex.py b/nw/convert/text/tolatex.py
similarity index 100%
rename from nw/convert/tolatex.py
rename to nw/convert/text/tolatex.py
diff --git a/nw/convert/tomarkdown.py b/nw/convert/text/tomarkdown.py
similarity index 100%
rename from nw/convert/tomarkdown.py
rename to nw/convert/text/tomarkdown.py
diff --git a/nw/convert/text/totext.py b/nw/convert/text/totext.py
new file mode 100644
index 00000000..abb42e7c
--- /dev/null
+++ b/nw/convert/text/totext.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+"""novelWriter Plain Text Converter
+
+ novelWriter – Plain Text Converter
+====================================
+ Extends the Tokenizer class to convert to plain text
+
+ File History:
+ Created: 2019-10-26 [0.3.1]
+
+"""
+
+import textwrap
+import logging
+import re
+import nw
+
+from nw.convert.tokenizer import Tokenizer
+
+logger = logging.getLogger(__name__)
+
+class ToText(Tokenizer):
+
+ def __init__(self, theProject, theParent):
+ Tokenizer.__init__(self, theProject, theParent)
+ return
+
+ def doConvert(self):
+ """Converts the tokenized text into plain text.
+ """
+
+ if self.wordWrap > 0:
+ tWrap = textwrap.TextWrapper(
+ width = self.wordWrap,
+ initial_indent = "",
+ subsequent_indent = "",
+ expand_tabs = True,
+ replace_whitespace = True,
+ fix_sentence_endings = False,
+ break_long_words = True,
+ drop_whitespace = True,
+ break_on_hyphens = True,
+ tabsize = 8,
+ max_lines = None
+ )
+
+ self.theResult = ""
+ thisPar = []
+ for tType, tText, tFormat, tAlign in self.theTokens:
+
+ # First check if we have a comment or plain text, as they need some
+ # extra replacing before we proceed to wrapping and final formatting.
+ if tType == self.T_COMMENT:
+ tText = "[%s]" % tText
+
+ elif tType == self.T_TEXT:
+ tTemp = tText
+ for xPos, xLen, xFmt in reversed(tFormat):
+ tTemp = tTemp[:xPos]+tTemp[xPos+xLen:]
+ tText = tTemp
+
+ tLen = len(tText)
+
+ # The text can now be word wrapped, if we have requested this and it's needed.
+ if tAlign == self.A_CENTRE:
+ if self.wordWrap > 0:
+ if tLen > self.wordWrap:
+ aText = tWrap.wrap(tText)
+ for n in range(len(aText)):
+ aText[n] = self._centreText(aText[n],self.wordWrap)
+ tText = "\n".join(aText)
+ else:
+ tText = self._centreText(tText,self.wordWrap)
+ else:
+ if self.wordWrap > 0 and tLen > self.wordWrap:
+ tText = tWrap.fill(tText)
+
+ # Then the text can receive final formatting before we append it to the results.
+ # We also store text lines in a buffer and merge them only when we find an empty line,
+ # indicating a new paragraph.
+ if tType == self.T_EMPTY:
+ if len(thisPar) > 0:
+ self.theResult += "%s\n\n" % " ".join(thisPar)
+ thisPar = []
+
+ elif tType == self.T_HEAD1:
+ uLine = "="*min(tLen,self.wordWrap)
+ if tAlign == self.A_CENTRE:
+ uLine = self._centreText(uLine,self.wordWrap)
+ self.theResult += "%s\n%s\n\n" % (tText,uLine)
+
+ elif tType == self.T_HEAD2:
+ uLine = "~"*min(tLen,self.wordWrap)
+ self.theResult += "%s\n%s\n\n" % (tText,uLine)
+
+ elif tType == self.T_HEAD3:
+ uLine = "-"*min(tLen,self.wordWrap)
+ self.theResult += "%s\n%s\n\n" % (tText,uLine)
+
+ elif tType == self.T_HEAD4:
+ self.theResult += "%s\n\n" % tText
+
+ elif tType == self.T_SEP:
+ if self.wordWrap > 0 and tLen < self.wordWrap:
+ tText = self._centreText(tText,self.wordWrap)
+ self.theResult += "%s\n\n" % tText
+
+ elif tType == self.T_TEXT:
+ thisPar.append(tText)
+
+ elif tType == self.T_COMMENT and self.doComments:
+ self.theResult += "%s\n\n" % tText
+
+ elif tType == self.T_COMMAND and self.doCommands:
+ self.theResult += "%s\n\n" % tText
+
+ return
+
+# END Class ToText
diff --git a/nw/convert/tokenizer.py b/nw/convert/tokenizer.py
index e4fb34ac..a59b4f13 100644
--- a/nw/convert/tokenizer.py
+++ b/nw/convert/tokenizer.py
@@ -276,97 +276,6 @@ class Tokenizer():
return
- def doConvert(self):
- """Converts the tokenized text into plain text.
- """
-
- if self.wordWrap > 0:
- tWrap = textwrap.TextWrapper(
- width = self.wordWrap,
- initial_indent = "",
- subsequent_indent = "",
- expand_tabs = True,
- replace_whitespace = True,
- fix_sentence_endings = False,
- break_long_words = True,
- drop_whitespace = True,
- break_on_hyphens = True,
- tabsize = 8,
- max_lines = None
- )
-
- self.theResult = ""
- thisPar = []
- for tType, tText, tFormat, tAlign in self.theTokens:
-
- # First check if we have a comment or plain text, as they need some
- # extra replacing before we proceed to wrapping and final formatting.
- if tType == self.T_COMMENT:
- tText = "[%s]" % tText
-
- elif tType == self.T_TEXT:
- tTemp = tText
- for xPos, xLen, xFmt in reversed(tFormat):
- tTemp = tTemp[:xPos]+tTemp[xPos+xLen:]
- tText = tTemp
-
- tLen = len(tText)
-
- # The text can now be word wrapped, if we have requested this and it's needed.
- if tAlign == self.A_CENTRE:
- if self.wordWrap > 0:
- if tLen > self.wordWrap:
- aText = tWrap.wrap(tText)
- for n in range(len(aText)):
- aText[n] = self._centreText(aText[n],self.wordWrap)
- tText = "\n".join(aText)
- else:
- tText = self._centreText(tText,self.wordWrap)
- else:
- if self.wordWrap > 0 and tLen > self.wordWrap:
- tText = tWrap.fill(tText)
-
- # Then the text can receive final formatting before we append it to the results.
- # We also store text lines in a buffer and merge them only when we find an empty line,
- # indicating a new paragraph.
- if tType == self.T_EMPTY:
- if len(thisPar) > 0:
- self.theResult += "%s\n\n" % " ".join(thisPar)
- thisPar = []
-
- elif tType == self.T_HEAD1:
- uLine = "="*min(tLen,self.wordWrap)
- if tAlign == self.A_CENTRE:
- uLine = self._centreText(uLine,self.wordWrap)
- self.theResult += "%s\n%s\n\n" % (tText,uLine)
-
- elif tType == self.T_HEAD2:
- uLine = "~"*min(tLen,self.wordWrap)
- self.theResult += "%s\n%s\n\n" % (tText,uLine)
-
- elif tType == self.T_HEAD3:
- uLine = "-"*min(tLen,self.wordWrap)
- self.theResult += "%s\n%s\n\n" % (tText,uLine)
-
- elif tType == self.T_HEAD4:
- self.theResult += "%s\n\n" % tText
-
- elif tType == self.T_SEP:
- if self.wordWrap > 0 and tLen < self.wordWrap:
- tText = self._centreText(tText,self.wordWrap)
- self.theResult += "%s\n\n" % tText
-
- elif tType == self.T_TEXT:
- thisPar.append(tText)
-
- elif tType == self.T_COMMENT and self.doComments:
- self.theResult += "%s\n\n" % tText
-
- elif tType == self.T_COMMAND and self.doCommands:
- self.theResult += "%s\n\n" % tText
-
- return
-
def windowsEndings(self):
self.theResult = self.theResult.replace("\n","\r\n")
return
diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py
index 68cba7ec..72c85ee4 100644
--- a/nw/gui/docviewer.py
+++ b/nw/gui/docviewer.py
@@ -17,9 +17,9 @@ from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTextBrowser
from PyQt5.QtGui import QTextOption, QFont, QPalette, QColor
-from nw.convert.tokenizer import Tokenizer
-from nw.convert.tohtml import ToHtml
-from nw.enum import nwItemType
+from nw.convert.tokenizer import Tokenizer
+from nw.convert.text.tohtml import ToHtml
+from nw.enum import nwItemType
logger = logging.getLogger(__name__)
diff --git a/nw/gui/export.py b/nw/gui/export.py
index 0fc82e6b..efcbca80 100644
--- a/nw/gui/export.py
+++ b/nw/gui/export.py
@@ -23,15 +23,15 @@ from PyQt5.QtWidgets import (
QLabel, QComboBox, QLineEdit, QPushButton, QFileDialog, QProgressBar, QSpinBox
)
-from nw.project.document import NWDoc
-from nw.tools.translate import numberToWord
-from nw.tools.optlaststate import OptLastState
-from nw.convert.textfile import TextFile
-from nw.convert.htmlfile import HtmlFile
-from nw.convert.markdownfile import MarkdownFile
-from nw.convert.latexfile import LaTeXFile
-from nw.constants import nwFiles
-from nw.enum import nwItemType
+from nw.project.document import NWDoc
+from nw.tools.translate import numberToWord
+from nw.tools.optlaststate import OptLastState
+from nw.convert.file.text import TextFile
+from nw.convert.file.html import HtmlFile
+from nw.convert.file.markdown import MarkdownFile
+from nw.convert.file.latex import LaTeXFile
+from nw.constants import nwFiles
+from nw.enum import nwItemType
logger = logging.getLogger(__name__)