mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
25b4610a69
@ -15,6 +15,7 @@ from qt.core import QApplication, QCheckBox, QComboBox, QFrame, QGridLayout, QHB
|
|||||||
|
|
||||||
from calibre.constants import iswindows
|
from calibre.constants import iswindows
|
||||||
from calibre.gui2 import gprefs
|
from calibre.gui2 import gprefs
|
||||||
|
from calibre.gui2.dialogs.template_general_info import GeneralInformationDialog
|
||||||
from calibre.gui2.widgets2 import Dialog, HTMLDisplay
|
from calibre.gui2.widgets2 import Dialog, HTMLDisplay
|
||||||
from calibre.utils.ffml_processor import FFMLProcessor
|
from calibre.utils.ffml_processor import FFMLProcessor
|
||||||
from calibre.utils.formatter_functions import formatter_functions
|
from calibre.utils.formatter_functions import formatter_functions
|
||||||
@ -77,7 +78,7 @@ class FFDocEditor(Dialog):
|
|||||||
hl.addWidget(f)
|
hl.addWidget(f)
|
||||||
f.currentIndexChanged.connect(self.functions_box_index_changed)
|
f.currentIndexChanged.connect(self.functions_box_index_changed)
|
||||||
|
|
||||||
so = self.show_in_english_cb = QCheckBox(_('Show as &English'))
|
so = self.show_in_english_cb = QCheckBox(_('Show in &English'))
|
||||||
so.stateChanged.connect(self.first_row_checkbox_changed)
|
so.stateChanged.connect(self.first_row_checkbox_changed)
|
||||||
hl.addWidget(so)
|
hl.addWidget(so)
|
||||||
|
|
||||||
@ -120,6 +121,9 @@ class FFDocEditor(Dialog):
|
|||||||
b = QPushButton(_('&Copy text'))
|
b = QPushButton(_('&Copy text'))
|
||||||
b.clicked.connect(self.copy_text)
|
b.clicked.connect(self.copy_text)
|
||||||
l.addWidget(b)
|
l.addWidget(b)
|
||||||
|
b = QPushButton(_('&FFML documentation'))
|
||||||
|
b.clicked.connect(self.documentation_button_clicked)
|
||||||
|
l.addWidget(b)
|
||||||
l.addStretch()
|
l.addStretch()
|
||||||
gl.addLayout(l, 6, 0)
|
gl.addLayout(l, 6, 0)
|
||||||
gl.addWidget(self.bb, 6, 1)
|
gl.addWidget(self.bb, 6, 1)
|
||||||
@ -127,6 +131,9 @@ class FFDocEditor(Dialog):
|
|||||||
self.changed_timer = QTimer()
|
self.changed_timer = QTimer()
|
||||||
self.fill_in_top_row()
|
self.fill_in_top_row()
|
||||||
|
|
||||||
|
def documentation_button_clicked(self):
|
||||||
|
GeneralInformationDialog(include_ffml_doc=True, parent=self).exec()
|
||||||
|
|
||||||
def editable_box_changed(self):
|
def editable_box_changed(self):
|
||||||
self.changed_timer.stop()
|
self.changed_timer.stop()
|
||||||
t = self.changed_timer = QTimer()
|
t = self.changed_timer = QTimer()
|
||||||
|
@ -669,7 +669,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
self.doc_viewer = None
|
self.doc_viewer = None
|
||||||
|
|
||||||
def open_general_info_dialog(self):
|
def open_general_info_dialog(self):
|
||||||
GeneralInformationDialog().exec()
|
GeneralInformationDialog(include_general_doc=True, include_ffml_doc=True).exec()
|
||||||
|
|
||||||
def geometry_string(self, txt):
|
def geometry_string(self, txt):
|
||||||
if self.dialog_number is None or self.dialog_number == 0:
|
if self.dialog_number is None or self.dialog_number == 0:
|
||||||
|
@ -18,7 +18,9 @@ from calibre.utils.ffml_processor import FFMLProcessor
|
|||||||
|
|
||||||
class GeneralInformationDialog(Dialog):
|
class GeneralInformationDialog(Dialog):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, include_general_doc=False, include_ffml_doc=False, parent=None):
|
||||||
|
self.include_general_doc = include_general_doc
|
||||||
|
self.include_ffml_doc = include_ffml_doc
|
||||||
super().__init__(title=_('Template function general information'), name='template_editor_gen_info_dialog',
|
super().__init__(title=_('Template function general information'), name='template_editor_gen_info_dialog',
|
||||||
default_buttons=QDialogButtonBox.StandardButton.Close, parent=parent)
|
default_buttons=QDialogButtonBox.StandardButton.Close, parent=parent)
|
||||||
|
|
||||||
@ -29,10 +31,17 @@ class GeneralInformationDialog(Dialog):
|
|||||||
if iswindows:
|
if iswindows:
|
||||||
e.setDefaultStyleSheet('pre { font-family: "Segoe UI Mono", "Consolas", monospace; }')
|
e.setDefaultStyleSheet('pre { font-family: "Segoe UI Mono", "Consolas", monospace; }')
|
||||||
l.addWidget(self.bb)
|
l.addWidget(self.bb)
|
||||||
e.setHtml(FFMLProcessor().document_to_html(information, 'Template Information'))
|
html = ''
|
||||||
|
if self.include_general_doc:
|
||||||
|
html += '<h2>General Information</h2>'
|
||||||
|
html += FFMLProcessor().document_to_html(general_doc, 'Template General Information')
|
||||||
|
if self.include_ffml_doc:
|
||||||
|
html += '<h2>Format Function Markup Language Documentation</h2>'
|
||||||
|
html += FFMLProcessor().document_to_html(ffml_doc, 'FFML Documentation')
|
||||||
|
e.setHtml(html)
|
||||||
|
|
||||||
|
|
||||||
information = r'''
|
general_doc = r'''
|
||||||
[LIST]
|
[LIST]
|
||||||
[*]`Functions in Single Function Mode templates`
|
[*]`Functions in Single Function Mode templates`
|
||||||
[LIST]
|
[LIST]
|
||||||
@ -46,7 +55,7 @@ Instead, use Template Program Mode and General Program Mode.
|
|||||||
[*]Do not use subtemplates "(`{...}`)" or functions (see below) in the prefix or the suffix
|
[*]Do not use subtemplates "(`{...}`)" or functions (see below) in the prefix or the suffix
|
||||||
for the same reason as above; they will often not work.
|
for the same reason as above; they will often not work.
|
||||||
[/LIST]
|
[/LIST]
|
||||||
[*]`Editor for asssting with template function documentation`
|
[*]`Editor for assisting with template function documentation`
|
||||||
|
|
||||||
An editor is available for helping write template function documentation. Given a document
|
An editor is available for helping write template function documentation. Given a document
|
||||||
in the Formatter Function Markup Language, it show the resulting HTML. The HTML is updated as you edit.
|
in the Formatter Function Markup Language, it show the resulting HTML. The HTML is updated as you edit.
|
||||||
@ -60,23 +69,27 @@ all on one line.
|
|||||||
[*]By defining a keyboard shortcut in calibre for the action `Open the template
|
[*]By defining a keyboard shortcut in calibre for the action `Open the template
|
||||||
documenation editor` in the `Miscellaneous` section. There is no default shortcut.
|
documenation editor` in the `Miscellaneous` section. There is no default shortcut.
|
||||||
[/LIST]
|
[/LIST]
|
||||||
[*]The `Template Function Markup Language`
|
[/LIST]
|
||||||
|
'''
|
||||||
|
|
||||||
|
ffml_doc = r'''
|
||||||
Format Function Markup Language (FFML) is a basic markup language used to
|
Format Function Markup Language (FFML) is a basic markup language used to
|
||||||
document formatter functions. It is based on a combination of RST used by sphinx
|
document formatter functions. It is based on a combination of RST used by sphinx
|
||||||
and BBCODE used by many bulletin board systems such as MobileRead. It provides a
|
and BBCODE used by many bulletin board systems such as MobileRead. It provides a
|
||||||
way to specify:
|
way to specify:
|
||||||
[LIST]
|
[LIST]
|
||||||
[*]Inline program code text: surround this text with \`\` as in \`\`foo\`\`. Tags inside the text are ignored.
|
[*][B]Inline program code text[/B]: surround this text with \`\` as in \`\`foo\`\`.
|
||||||
[*]Italic text: surround this text with \`. Example: \`foo\` produces `foo`.
|
Tags inside the text are ignored. if the code text ends with a `\'` character, put
|
||||||
[*]Bold text: surround this text with \[B]text\[\B] tags. Example: \[B]foo\[/B] produces [B]foo[/B].
|
a space before the closing \`\` characters. Trailing blanks in the code text are removed.
|
||||||
[*]Text intended to reference a calibre GUI action. This uses RST syntax.\
|
[*][B]Italic text[/B]: surround this text with \`. Example: \`foo\` produces `foo`.
|
||||||
|
[*][B]Bold text[/B]: surround this text with \[B]text\[\B] tags. Example: \[B]foo\[/B] produces [B]foo[/B].
|
||||||
|
[*][B]Text intended to reference a calibre GUI action[/B]. This uses RST syntax.\
|
||||||
Example: \:guilabel\:\`Preferences->Advanced->Template functions\`. For HTML the produced text is in a different font, as in: :guilabel:`Some text`
|
Example: \:guilabel\:\`Preferences->Advanced->Template functions\`. For HTML the produced text is in a different font, as in: :guilabel:`Some text`
|
||||||
[*]Empty lines, indicated by two newlines in a row. A visible empty line in the FFML
|
[*][B]Empty lines[/B], indicated by two newlines in a row. A visible empty line in the FFML
|
||||||
will become an empty line in the output.
|
will become an empty line in the output.
|
||||||
[*]URLs. The syntax is similar to BBCODE: ``[URL href="http..."]Link text[/URL]``.\
|
[*][B]URLs.[/B] The syntax is similar to BBCODE: ``[URL href="http..."]Link text[/URL]``.\
|
||||||
Example: ``[URL href="https://en.wikipedia.org/wiki/ISO_8601"]ISO[/URL]`` produces [URL href="https://en.wikipedia.org/wiki/ISO_8601"]ISO[/URL]
|
Example: ``[URL href="https://en.wikipedia.org/wiki/ISO_8601"]ISO[/URL]`` produces [URL href="https://en.wikipedia.org/wiki/ISO_8601"]ISO[/URL]
|
||||||
[*]Internal function reference links. These are links to formatter function
|
[*][B]Internal function reference links[/B]. These are links to formatter function
|
||||||
documentation. The syntax is the same as guilabel. Example: ``:ref:\`get_note\```.
|
documentation. The syntax is the same as guilabel. Example: ``:ref:\`get_note\```.
|
||||||
The characters '()' are automatically added to the function name when
|
The characters '()' are automatically added to the function name when
|
||||||
displayed. For HTML it generates the same as the inline program code text
|
displayed. For HTML it generates the same as the inline program code text
|
||||||
@ -84,49 +97,52 @@ operator (\`\`) with no link. Example: ``:ref:`add` `` produces ``add()``.
|
|||||||
For RST it generates a ``:ref:`` reference that works only in an RST document
|
For RST it generates a ``:ref:`` reference that works only in an RST document
|
||||||
containing formatter function documentation. Example: ``:ref:\`get_note\```
|
containing formatter function documentation. Example: ``:ref:\`get_note\```
|
||||||
generates \:ref\:\`get_note() <ff_get_note>\`
|
generates \:ref\:\`get_note() <ff_get_note>\`
|
||||||
[*]Example program code text blocks. Surround the code block with ``[CODE]``
|
[*][B]Example program code text blocks.[/B] Surround the code block with ``[CODE]``
|
||||||
and ``[/CODE]`` tags. These tags must be first on a line. Example:
|
and ``[/CODE]`` tags. These tags must be first on a line. Example:
|
||||||
[CODE]
|
[CODE]
|
||||||
\[CODE]program:
|
[CODE]program:
|
||||||
get_note('authors', 'Isaac Asimov', 1)
|
get_note('authors', 'Isaac Asimov', 1)
|
||||||
\[/CODE]
|
[\/CODE]
|
||||||
[/CODE]
|
[/CODE]
|
||||||
produces
|
produces
|
||||||
[CODE]
|
[CODE]
|
||||||
program:
|
program:
|
||||||
get_note('authors', 'Isaac Asimov', 1)[/CODE]
|
get_note('authors', 'Isaac Asimov', 1)
|
||||||
|
[/CODE]
|
||||||
[*]Bulleted lists, using BBCODE tags. Surround the list with ``[LIST]`` and
|
If you want the literal text ``[/CODE]`` in a code block then it must be entered as ``[\/CODE]``
|
||||||
|
to ensure that the FFML parser doesn't interpret it as the end of the code block. The ``'\'``
|
||||||
|
character is removed.
|
||||||
|
[*][B]Bulleted lists[/B], using BBCODE tags. Surround the list with ``[LIST]`` and
|
||||||
``[/LIST]``. List items are indicated with ``[*]``. All of the tags must be
|
``[/LIST]``. List items are indicated with ``[*]``. All of the tags must be
|
||||||
first on a line. Bulleted lists can be nested and can contain other FFML
|
first on a line. Bulleted lists can be nested and can contain other FFML
|
||||||
elements.
|
elements.
|
||||||
|
|
||||||
Example: a two bullet list containing CODE blocks
|
Example: a two bullet list containing CODE blocks
|
||||||
[CODE]
|
[CODE]
|
||||||
\[LIST]
|
[LIST]
|
||||||
[*]Return the HTML of the note attached to the tag `Fiction`:
|
[*]Return the HTML of the note attached to the tag `Fiction`:
|
||||||
\[CODE]
|
[CODE]
|
||||||
program:
|
program:
|
||||||
get_note('tags', 'Fiction', '')
|
get_note('tags', 'Fiction', '')
|
||||||
\[/CODE]
|
[\/CODE]
|
||||||
[*]Return the plain text of the note attached to the author `Isaac Asimov`:
|
[*]Return the plain text of the note attached to the author `Isaac Asimov`:
|
||||||
\[CODE]
|
[CODE]
|
||||||
program:
|
program:
|
||||||
get_note('authors', 'Isaac Asimov', 1)
|
get_note('authors', 'Isaac Asimov', 1)
|
||||||
\[/CODE]
|
[\/CODE]
|
||||||
\[/LIST]
|
[/LIST]
|
||||||
[/CODE]
|
[/CODE]
|
||||||
[*]End of summary marker. A summary is generated from the first characters of
|
[*][B]End of summary marker[/B]. A summary is generated from the first characters of
|
||||||
the documentation. The summary includes text up to a \[/] tag. There is no
|
the documentation. The summary includes text up to a \[\/] tag. There is no
|
||||||
opening tag because the summary starts at the first character. If there is
|
opening tag because the summary starts at the first character. If there is
|
||||||
no \[/] tag then all the document is used for the summary. The \[/] tag
|
no \[\/] tag then all the document is used for the summary. The \[\/] tag
|
||||||
is not replaced with white space or any other character.
|
is removed, not replaced with white space or any other character.
|
||||||
[*]Escaped character: precede the character with a backslash. This is useful
|
[*][B]Escaped character[/B]: precede the character with a backslash. This is useful
|
||||||
to escape tags. For example to make the \[CODE] tag not a tag, use \\\[CODE].
|
to escape tags. For example to make the \[CODE] tag not a tag, use \\\[CODE].
|
||||||
|
Escaping characters doesn't work in `Inline program code text` or
|
||||||
[*]HTML output contains no CSS and does not start with a tag such as <DIV> or <P>.
|
`Example program code text blocks`.
|
||||||
[/LIST]
|
|
||||||
[/LIST]
|
[/LIST]
|
||||||
|
Note: HTML output contains no CSS and does not start with a tag such as <DIV> or <P>.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,91 +165,13 @@ class FFMLProcessor:
|
|||||||
|
|
||||||
FFML is a basic markup language used to document formatter functions. It is
|
FFML is a basic markup language used to document formatter functions. It is
|
||||||
based on a combination of RST used by sphinx and BBCODE used by many
|
based on a combination of RST used by sphinx and BBCODE used by many
|
||||||
bulletin board systems such as MobileRead. It provides a way to specify:
|
bulletin board systems such as MobileRead. You can see the documentation
|
||||||
|
(in FFML) in the file gui2.dialogs.template_general_info.py. A formatted
|
||||||
- inline program code text: surround this text with `` as in ``foo``.
|
version is available by:
|
||||||
|
- pushing the "General information" button in the Template tester
|
||||||
- bold text: surrond this text with [B] [/B], as in [B]foo[/B]. Note: bold
|
- pushing the "FFML documentation" button in the "Formatter function
|
||||||
italics don't work in RST.
|
documentation editor". How to access the editor is described in "General
|
||||||
|
information" dialog mentioned above.
|
||||||
- italic text: surround this text with `, as in `foo`. Note: bold italics
|
|
||||||
don't work in RST.
|
|
||||||
|
|
||||||
- text intended to reference a calibre GUI action. This uses RST syntax.
|
|
||||||
Example: :guilabel:`Preferences->Advanced->Template functions`
|
|
||||||
|
|
||||||
- empty lines, indicated by two newlines in a row. A visible empty line
|
|
||||||
in the FFMC will become an empty line in the output.
|
|
||||||
|
|
||||||
- URLs. The syntax is similar to BBCODE: [URL href="http..."]Link text[/URL].
|
|
||||||
Example: [URL href="https://en.wikipedia.org/wiki/ISO_8601"]ISO[/URL]
|
|
||||||
|
|
||||||
- Internal function reference links. These are links to some formatter function
|
|
||||||
documentation. The syntax is the same as guilabel. Example: :ref:`get_note`.
|
|
||||||
The characters '()' are automatically added to the function name when
|
|
||||||
displayed. For HTML it generates the same as the inline program code text
|
|
||||||
operator (``) with no link. Example: :ref:`add` produces <code>add()</code>.
|
|
||||||
For RST it generates a :ref: reference that works only in an RST document
|
|
||||||
containing formatter function documentation. Example: :ref:`get_note`
|
|
||||||
generates :ref:`get_note() <ff_get_note>`
|
|
||||||
|
|
||||||
- example program code text blocks. Surround the code block with [CODE]
|
|
||||||
and [/CODE] tags. These tags must be first on a line. Example:
|
|
||||||
[CODE]
|
|
||||||
program:
|
|
||||||
get_note('authors', 'Isaac Asimov', 1)
|
|
||||||
[/CODE]
|
|
||||||
|
|
||||||
- bulleted lists, using BBCODE tags. Surround the list with [LIST] and
|
|
||||||
[/LIST]. List items are indicated with [*]. All of the tags must be
|
|
||||||
first on a line. Bulleted lists can be nested and can contain other FFML
|
|
||||||
elements. Example: a two bullet list containing CODE blocks
|
|
||||||
[LIST]
|
|
||||||
[*]Return the HTML of the note attached to the tag `Fiction`:
|
|
||||||
[CODE]
|
|
||||||
program:
|
|
||||||
get_note('tags', 'Fiction', '')
|
|
||||||
[/CODE]
|
|
||||||
[*]Return the plain text of the note attached to the author `Isaac Asimov`:
|
|
||||||
[CODE]
|
|
||||||
program:
|
|
||||||
get_note('authors', 'Isaac Asimov', 1)
|
|
||||||
[/CODE]
|
|
||||||
[/LIST]
|
|
||||||
|
|
||||||
- end of summary marker. A summary is generated from the first characters of
|
|
||||||
the documentation. The summary includes text up to a \[/] tag. There is no
|
|
||||||
opening tag because the summary starts at the first character. If there is
|
|
||||||
no \[/] tag then all the document is used for the summary. The \[/] tag
|
|
||||||
is not replaced with white space or any other character.
|
|
||||||
|
|
||||||
- escaped character: precede the character with a backslash. This is useful
|
|
||||||
to escape tags. For example to make the [CODE] tag not a tag, use \[CODE].
|
|
||||||
|
|
||||||
HTML output contains no CSS and does not start with a tag such as <DIV> or <P>.
|
|
||||||
|
|
||||||
API example: generate documents for all builtin formatter functions
|
|
||||||
--------------------
|
|
||||||
from calibre.utils.ffml_processor import FFMLProcessor
|
|
||||||
from calibre.utils.formatter_functions import formatter_functions
|
|
||||||
from calibre.db.legacy import LibraryDatabase
|
|
||||||
|
|
||||||
# We need this to load the formatter functions
|
|
||||||
db = LibraryDatabase('<path to some library>')
|
|
||||||
|
|
||||||
ffml = FFMLProcessor()
|
|
||||||
funcs = formatter_functions().get_builtins()
|
|
||||||
|
|
||||||
with open('all_docs.html', 'w') as w:
|
|
||||||
for name in sorted(funcs):
|
|
||||||
w.write(f'\n<h2>{name}</h2>\n')
|
|
||||||
w.write(ffml.document_to_html(funcs[name].doc, name))
|
|
||||||
|
|
||||||
with open('all_docs.rst', 'w') as w:
|
|
||||||
for name in sorted(funcs):
|
|
||||||
w.write(f"\n\n{name}\n{'^'*len(name)}\n\n")
|
|
||||||
w.write(ffml.document_to_rst(funcs[name].doc, name))
|
|
||||||
--------------------
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ====== API ======
|
# ====== API ======
|
||||||
@ -581,7 +503,7 @@ class FFMLProcessor:
|
|||||||
end = self.find('[/CODE]')
|
end = self.find('[/CODE]')
|
||||||
if end < 0:
|
if end < 0:
|
||||||
self.error('Missing [/CODE] for block')
|
self.error('Missing [/CODE] for block')
|
||||||
node = CodeBlock(self.text_to(end))
|
node = CodeBlock(self.text_to(end).replace(r'[\/CODE]', '[/CODE]'))
|
||||||
self.move_pos(end + len('[/CODE]'))
|
self.move_pos(end + len('[/CODE]'))
|
||||||
if self.text_to(1) == '\n':
|
if self.text_to(1) == '\n':
|
||||||
self.move_pos(1)
|
self.move_pos(1)
|
||||||
@ -592,7 +514,7 @@ class FFMLProcessor:
|
|||||||
end = self.find('``')
|
end = self.find('``')
|
||||||
if end < 0:
|
if end < 0:
|
||||||
self.error('Missing closing "``" for CODE_TEXT')
|
self.error('Missing closing "``" for CODE_TEXT')
|
||||||
node = CodeText(self.text_to(end))
|
node = CodeText(self.text_to(end).rstrip(' '))
|
||||||
self.move_pos(end + len('``'))
|
self.move_pos(end + len('``'))
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user