mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Enhancement #2017403: Add a preview tab to Markdown "long text" editor (https://bugs.launchpad.net/calibre/+bug/2017403)
This commit is contained in:
parent
6c9bd54cb6
commit
b990609ac1
@ -18,6 +18,7 @@ from qt.core import (
|
||||
from calibre.ebooks.metadata import title_sort
|
||||
from calibre.gui2 import UNDEFINED_QDATETIME, elided_text, error_dialog, gprefs
|
||||
from calibre.gui2.comments_editor import Editor as CommentsEditor
|
||||
from calibre.gui2.markdown_editor import Editor as MarkdownEditor
|
||||
from calibre.gui2.complete2 import EditWithComplete as EWC
|
||||
from calibre.gui2.dialogs.tag_editor import TagEditor
|
||||
from calibre.gui2.library.delegates import ClearingDoubleSpinBox, ClearingSpinBox
|
||||
@ -467,6 +468,41 @@ class Comments(Base):
|
||||
self.signals_to_disconnect.append(self._tb.data_changed)
|
||||
|
||||
|
||||
class Markdown(Base):
|
||||
|
||||
def setup_ui(self, parent):
|
||||
self._box = QGroupBox(parent)
|
||||
self._box.setTitle(label_string(self.col_metadata['name']))
|
||||
self._layout = QVBoxLayout()
|
||||
self._tb = MarkdownEditor(self._box)
|
||||
self._tb.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
# self._tb.setTabChangesFocus(True)
|
||||
self._layout.addWidget(self._tb)
|
||||
self._box.setLayout(self._layout)
|
||||
self.widgets = [self._box]
|
||||
|
||||
def setter(self, val):
|
||||
self._tb.markdown = str(val or '').strip()
|
||||
|
||||
def getter(self):
|
||||
val = self._tb.markdown.strip()
|
||||
if not val:
|
||||
val = None
|
||||
return val
|
||||
|
||||
@property
|
||||
def tab(self):
|
||||
return self._tb.tab
|
||||
|
||||
@tab.setter
|
||||
def tab(self, val):
|
||||
self._tb.tab = val
|
||||
|
||||
def connect_data_changed(self, slot):
|
||||
self._tb.editor.textChanged.connect(slot)
|
||||
self.signals_to_disconnect.append(self._tb.editor.textChanged)
|
||||
|
||||
|
||||
class MultipleWidget(QWidget):
|
||||
|
||||
def __init__(self, parent, only_manage_items=False, widget=EditWithComplete, name=None):
|
||||
@ -780,8 +816,10 @@ def comments_factory(db, key, parent):
|
||||
ctype = fm.get('display', {}).get('interpret_as', 'html')
|
||||
if ctype == 'short-text':
|
||||
return SimpleText(db, key, parent)
|
||||
if ctype in ('long-text', 'markdown'):
|
||||
if ctype == 'long-text':
|
||||
return LongText(db, key, parent)
|
||||
if ctype == 'markdown':
|
||||
return Markdown(db, key, parent)
|
||||
return Comments(db, key, parent)
|
||||
|
||||
|
||||
|
122
src/calibre/gui2/markdown_editor.py
Normal file
122
src/calibre/gui2/markdown_editor.py
Normal file
@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2023, un_pogaz <un.pogaz@gmail.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from qt.core import (
|
||||
QPlainTextEdit, Qt, QTabWidget, QVBoxLayout, QWidget,
|
||||
)
|
||||
|
||||
from calibre.gui2.book_details import css
|
||||
from calibre.gui2.widgets2 import HTMLDisplay
|
||||
from calibre.library.comments import markdown
|
||||
|
||||
|
||||
class Editor(QWidget): # {{{
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
self._layout = QVBoxLayout(self)
|
||||
self.setLayout(self._layout)
|
||||
self.tabs = QTabWidget(self)
|
||||
self.tabs.setTabPosition(QTabWidget.TabPosition.South)
|
||||
self._layout.addWidget(self.tabs)
|
||||
|
||||
self.editor = QPlainTextEdit(self.tabs)
|
||||
|
||||
self.preview = HTMLDisplay(self.tabs)
|
||||
self.preview.setDefaultStyleSheet(css())
|
||||
self.preview.setTabChangesFocus(True)
|
||||
|
||||
self.tabs.addTab(self.editor, _('&Markdown source'))
|
||||
self.tabs.addTab(self.preview, _('&Preview'))
|
||||
|
||||
self.tabs.currentChanged[int].connect(self.change_tab)
|
||||
self.layout().setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
def set_minimum_height_for_editor(self, val):
|
||||
self.editor.setMinimumHeight(val)
|
||||
|
||||
@property
|
||||
def markdown(self):
|
||||
self.tabs.setCurrentIndex(0)
|
||||
return self.editor.toPlainText().strip()
|
||||
|
||||
@markdown.setter
|
||||
def markdown(self, v):
|
||||
self.editor.setPlainText(str(v or ''))
|
||||
|
||||
def change_tab(self, index):
|
||||
if index == 0: # changing to source
|
||||
pass
|
||||
if index == 1: # changing to preview
|
||||
html = markdown(self.editor.toPlainText().strip())
|
||||
val = f'''\
|
||||
<html>
|
||||
<head></head>
|
||||
<body class="vertical">
|
||||
<div>{html}</div>
|
||||
</body>
|
||||
<html>'''
|
||||
self.preview.setHtml(val)
|
||||
|
||||
@property
|
||||
def tab(self):
|
||||
return 'code' if self.tabs.currentWidget() is self.editor else 'preview'
|
||||
|
||||
@tab.setter
|
||||
def tab(self, val):
|
||||
self.tabs.setCurrentWidget(self.preview if val == 'preview' else self.editor)
|
||||
|
||||
def set_readonly(self, val):
|
||||
self.editor.setReadOnly(bool(val))
|
||||
|
||||
def hide_tabs(self):
|
||||
self.tabs.tabBar().setVisible(False)
|
||||
|
||||
def smarten_punctuation(self):
|
||||
from calibre.ebooks.conversion.preprocess import smarten_punctuation
|
||||
markdown = self.markdown
|
||||
newmarkdown = smarten_punctuation(markdown)
|
||||
if markdown != newmarkdown:
|
||||
self.markdown = newmarkdown
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from calibre.gui2 import Application
|
||||
app = Application([])
|
||||
w = Editor()
|
||||
w.resize(800, 600)
|
||||
w.setWindowFlag(Qt.WindowType.Dialog)
|
||||
w.show()
|
||||
w.markdown = '''\
|
||||
test *italic* **bold** ***bold-italic*** `code` [link](https://calibre-ebook.com) <span style="font-weight: bold; color:red">span</span>
|
||||
|
||||
> Blockquotes
|
||||
|
||||
if '>'+' '*4 in string:
|
||||
pre_block()
|
||||
|
||||
1. list 1
|
||||
1. list 1.1
|
||||
2. list 1.2
|
||||
2. list 2
|
||||
|
||||
***
|
||||
|
||||
* list
|
||||
- list
|
||||
|
||||
# Headers 1
|
||||
## Headers 2
|
||||
### Headers 3
|
||||
#### Headers 4
|
||||
##### Headers 5
|
||||
###### Headers 6
|
||||
'''
|
||||
app.exec()
|
||||
# print(w.markdown)
|
Loading…
x
Reference in New Issue
Block a user