From 282477bcfaeda180477878b18034bace8fd419bb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 31 Aug 2021 20:56:44 +0530 Subject: [PATCH] When adding markdown (.md) or textile (.textile) files that contain references to images, automatically add them as txtz with the images --- src/calibre/customize/builtins.py | 10 +++---- .../ebooks/conversion/plugins/txt_input.py | 13 +++++++-- src/calibre/ebooks/txt/processor.py | 28 ++++++++++--------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index d152107f83..0bf4038596 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -54,21 +54,19 @@ class TXT2TXTZ(FileTypePlugin): 'containing Markdown or Textile references to images. The referenced ' 'images as well as the TXT file are added to the archive.') version = numeric_version - file_types = {'txt', 'text'} + file_types = {'txt', 'text', 'md', 'markdown', 'textile'} supported_platforms = ['windows', 'osx', 'linux'] on_import = True - def _get_image_references(self, txt, base_dir): - from calibre.ebooks.txt.processor import get_images_from_polyglot_text - return get_images_from_polyglot_text(txt, base_dir) - def run(self, path_to_ebook): from calibre.ebooks.metadata.opf2 import metadata_to_opf + from calibre.ebooks.txt.processor import get_images_from_polyglot_text with open(path_to_ebook, 'rb') as ebf: txt = ebf.read().decode('utf-8', 'replace') base_dir = os.path.dirname(path_to_ebook) - images = self._get_image_references(txt, base_dir) + ext = path_to_ebook.rpartition('.')[-1].lower() + images = get_images_from_polyglot_text(txt, base_dir, ext) if images: # Create TXTZ and put file plus images inside of it. diff --git a/src/calibre/ebooks/conversion/plugins/txt_input.py b/src/calibre/ebooks/conversion/plugins/txt_input.py index 682364d7c0..2a1f0c0759 100644 --- a/src/calibre/ebooks/conversion/plugins/txt_input.py +++ b/src/calibre/ebooks/conversion/plugins/txt_input.py @@ -152,7 +152,9 @@ class TXTInput(InputFormatPlugin): zf.extractall('.') for x in walk('.'): - if os.path.splitext(x)[1].lower() in ('.txt', '.text'): + ext = os.path.splitext(x)[1].lower() + if ext in ('.txt', '.text', '.textile', '.md', '.markdown'): + file_ext = ext with open(x, 'rb') as tf: txt += tf.read() + b'\n\n' if os.path.exists('metadata.opf'): @@ -168,10 +170,17 @@ class TXTInput(InputFormatPlugin): if txt_formatting is not None and txt_formatting.text: txt_formatting = txt_formatting.text.strip() if txt_formatting in ('plain', 'textile', 'markdown') and options.formatting_type == 'auto': - log.info(f'Using metadata from TXTZ archive to set text formmating type to: {txt_formatting}') + log.info(f'Using metadata from TXTZ archive to set text formating type to: {txt_formatting}') options.formatting_type = txt_formatting if txt_formatting != 'plain': options.paragraph_type = 'off' + if options.formatting_type == 'auto': + if file_ext == 'textile': + options.formatting_type = txt_formatting + options.paragraph_type = 'off' + elif file_ext in ('md', 'markdown'): + options.formatting_type = txt_formatting + options.paragraph_type = 'off' else: if getattr(stream, 'name', None): base_dir = os.path.dirname(stream.name) diff --git a/src/calibre/ebooks/txt/processor.py b/src/calibre/ebooks/txt/processor.py index 5a84cbc965..fe46e39b1d 100644 --- a/src/calibre/ebooks/txt/processor.py +++ b/src/calibre/ebooks/txt/processor.py @@ -343,7 +343,7 @@ def detect_formatting_type(txt): return 'heuristic' -def get_images_from_polyglot_text(txt: str, base_dir: str = '') -> set: +def get_images_from_polyglot_text(txt: str, base_dir: str = '', file_ext: str = 'txt') -> set: from calibre.ebooks.oeb.base import OEB_IMAGES from calibre import guess_type if not base_dir: @@ -354,17 +354,19 @@ def get_images_from_polyglot_text(txt: str, base_dir: str = '') -> set: if path and not os.path.isabs(path) and guess_type(path)[0] in OEB_IMAGES and os.path.exists(os.path.join(base_dir, path)): images.add(path) - # Textile - for m in re.finditer(r'(?mu)(?:[\[{])?\!(?:\. )?(?P[^\s(!]+)\s?(?:\(([^\)]+)\))?\!(?::(\S+))?(?:[\]}]|(?=\s|$))', txt): - path = m.group('path') - check_path(path) + if file_ext in ('txt', 'text', 'textile'): + # Textile + for m in re.finditer(r'(?mu)(?:[\[{])?\!(?:\. )?(?P[^\s(!]+)\s?(?:\(([^\)]+)\))?\!(?::(\S+))?(?:[\]}]|(?=\s|$))', txt): + path = m.group('path') + check_path(path) - # Markdown - from markdown import Markdown - html = HTML_TEMPLATE % ('', Markdown().convert(txt)) - from html5_parser import parse - root = parse(html) - for img in root.iterdescendants('img'): - path = img.get('src') - check_path(path) + if file_ext in ('txt', 'text', 'md', 'markdown'): + # Markdown + from markdown import Markdown + html = HTML_TEMPLATE % ('', Markdown().convert(txt)) + from html5_parser import parse + root = parse(html) + for img in root.iterdescendants('img'): + path = img.get('src') + check_path(path) return images