diff --git a/src/calibre/ebooks/txt/input.py b/src/calibre/ebooks/txt/input.py
index 7be1a3449a..a0570c07ae 100644
--- a/src/calibre/ebooks/txt/input.py
+++ b/src/calibre/ebooks/txt/input.py
@@ -8,7 +8,8 @@ import os
from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
from calibre.ebooks.txt.processor import convert_basic, convert_markdown, \
- separate_paragraphs_single_line, separate_paragraphs_print_formatted
+ separate_paragraphs_single_line, separate_paragraphs_print_formatted, \
+ preserve_spaces
class TXTInput(InputFormatPlugin):
@@ -28,6 +29,9 @@ class TXTInput(InputFormatPlugin):
'an indent (either a tab or 2+ spaces) represents a paragraph. '
'Paragraphs end when the next line that starts with an indent '
'is reached.')),
+ OptionRecommendation(name='preserve_spaces', recommended_value=False,
+ help=_('Normally extra spaces are condensed into a single space. '
+ 'With this option all spaces will be displayed.')),
OptionRecommendation(name='markdown', recommended_value=False,
help=_('Run the text input through the markdown pre-processor. To '
'learn more about markdown see')+' http://daringfireball.net/projects/markdown/'),
@@ -48,6 +52,8 @@ class TXTInput(InputFormatPlugin):
txt = separate_paragraphs_single_line(txt)
if options.print_formatted_paras:
txt = separate_paragraphs_print_formatted(txt)
+ if options.preserve_spaces:
+ txt = preserve_spaces(txt)
if options.markdown:
log.debug('Running text though markdown conversion...')
diff --git a/src/calibre/ebooks/txt/processor.py b/src/calibre/ebooks/txt/processor.py
index 06276a4bbc..baebf2f298 100644
--- a/src/calibre/ebooks/txt/processor.py
+++ b/src/calibre/ebooks/txt/processor.py
@@ -24,6 +24,9 @@ def convert_basic(txt, title=''):
for line in txt.splitlines():
lines.append(line.strip())
txt = '\n'.join(lines)
+
+ # Condense redundant spaces
+ txt = re.sub('[ ]{2,}', ' ', txt)
# Remove blank lines from the beginning and end of the document.
txt = re.sub('^\s+(?=.)', '', txt)
@@ -56,6 +59,11 @@ def separate_paragraphs_print_formatted(txt):
txt = re.sub('(?miu)^(\t+|[ ]{2,})(?=.)', '\n\t', txt)
return txt
+def preserve_spaces(txt):
+ txt = txt.replace(' ', ' ')
+ txt = txt.replace('\t', ' ')
+ return txt
+
def opf_writer(path, opf_name, manifest, spine, mi):
opf = OPFCreator(path, mi)
opf.create_manifest(manifest)
diff --git a/src/calibre/gui2/convert/txt_input.py b/src/calibre/gui2/convert/txt_input.py
index 7fe6f6274c..f108bdd7d5 100644
--- a/src/calibre/gui2/convert/txt_input.py
+++ b/src/calibre/gui2/convert/txt_input.py
@@ -14,6 +14,7 @@ class PluginWidget(Widget, Ui_Form):
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
Widget.__init__(self, parent, 'txt_input',
- ['single_line_paras', 'print_formatted_paras', 'markdown', 'markdown_disable_toc'])
+ ['single_line_paras', 'print_formatted_paras', 'markdown',
+ 'markdown_disable_toc', 'preserve_spaces'])
self.db, self.book_id = db, book_id
self.initialize_options(get_option, get_help, db, book_id)
diff --git a/src/calibre/gui2/convert/txt_input.ui b/src/calibre/gui2/convert/txt_input.ui
index 9fde157d33..5a9527ebc5 100644
--- a/src/calibre/gui2/convert/txt_input.ui
+++ b/src/calibre/gui2/convert/txt_input.ui
@@ -6,7 +6,7 @@
0
0
- 400
+ 470
300
@@ -52,7 +52,7 @@
- -
+
-
Qt::Vertical
@@ -65,10 +65,17 @@
+ -
+
+
+ Preserve &spaces
+
+
+
-
+
opt_markdown
toggled(bool)