[go: up one dir, main page]

Menu

[80c337]: / qtextdocumentscript.h  Maximize  Restore  History

Download this file

296 lines (282 with data), 17.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/** \file qtextdocumentscript.h
*
* \brief Functions for adding to a script engine the API for dealing with word processing Lobs
*
* The LurchDocumentConverter class helps keep a QTextDocument (such as one in a visual editor)
* in sync with a Lob structure behind the scenes. This makes the word processing interface to
* Lurch documents possible, but also necessitates a certain structure to the Lobs that store the
* document; they must have the structure appropriate for syncing back and forth with the
* QTextDocument.
*
* This file contains routines that can add to a Qt Javascript environment an API for dealing
* with Lobs that encode the text fragments, paragraphs, and frames of a QTextDocument, together
* with their various character, paragraph, and list formatting codes. This way scripts in a
* LurchEnvironment can manipulate the document in ways that are easier to understand and that
* preserve the necessary structures.
*
* Cursor placement routines are also provided, as well as routines for converting Lob word
* processing structures to and from both HTML and plain text.
*
* The main routine defined herein is addLobTextToScriptEngine().
* Much of it is simply exposing routines and data that already exit in the Qt toolkit
* to Javascript. To have this routine called on a LurchEnvironment whenever it refreshes its
* interpreter, see the KeepLobTextAdded class.
*/
#ifndef QTEXTDOCUMENTSCRIPT_H
#define QTEXTDOCUMENTSCRIPT_H
#include <QtScript>
#include "lob.h"
/** \brief Adds to the given script engine all the API for dealing with Lobs as word processor text
*
* This routine assumes that Lobs have already been added to the script engine, using
* addLobsToScriptEngine() as documented in lobscript.h. If that is not so, this function will
* detect their absence, and finish without adding anything to the script engine. This is because
* most of what this function adds to the script engine it puts in the Lob prototype, and if that
* has not yet been defined, this routine has nowhere to put most of its routines and data.
*
* <h3>Global functions defined</h3>
* <ul>
* <li><tt>text(arg1,arg2,...)</tt> converts each argument into a string, replaces
* all newline characters with spaces, and joins them into one string with
* spaces in between. The result is then converted into a string Lob and
* returned, ready for placement in a paragraph. If zero or one arguments
* are passed, the empty Lob is returned, because word processor text fragments
* may not be empty.</li>
* <li><tt>paragraph(arg1,arg2,...)</tt> creates paragraphs for use in word
* processing structures. Each argument that is not already a text Lob (that
* is, passes the isText() test) is converted to one using the text() function.
* Then the resulting Lobs are made children to a new paragraph Lob, which is
* returned.</li>
* <li><tt>frame(arg1,arg2,...)</tt> creates frames for use in word processing
* structures. Each argument that is not already a paragraph Lob (that is,
* passes the isParagraph() test) is converted to one as if it had been passed
* to the paragraph() function.
* Then the resulting Lobs are made children to a new frame Lob,
* which is returned.</li>
* <li><tt>table(arg1,arg2,...)</tt> functions exactly like frame(), but the new
* frame returned is a table frame, rather than a standard one. This is still
* rather useless because functions have not been provided (yet) for setting the
* table structure (number of rows and columns, etc.).</li>
* <li><tt>fromPlainText('...text...')</tt> returns an array of Lobs representing
* one or more paragraphs constructed from the given text. Newlines in the
* text are interpreted as paragraph breaks.<br>
* <li><tt>fromHTML('...HTML code...')</tt> returns an array of Lobs representing
* one or more paragraphs and/or frames constructed from the given HTML.<br>
* See Qt's <a href='http://doc.qt.nokia.com/latest/richtext-html-subset.html'
* >supported HTML subset</a> to know what you can include.</li>
* </ul>
*
* <h3>Additions to the Lob prototype</h3>
* <ul>
* <li><tt>myLob.isText()</tt> returns whether <tt>myLob</tt> is a word
* processing Lob representing a text fragment inside a paragraph.
* The decision procedure is imperfect: any
* OpenMath string Lob might be a fragment of word processor text. Thus this
* check is simply a convenient renaming of the test for whether the Lob's
* type is <tt>OMTypes.String</tt>.</li>
* <li><tt>myLob.isParagraph()</tt> returns whether <tt>myLob</tt> is a word
* processing Lob representing a paragraph.</li>
* <li><tt>myLob.isFrame()</tt> returns whether <tt>myLob</tt> is a word
* processing Lob representing a frame. Frames are structures that contain
* paragraphs; they can be of a generic type (like an HTML DIV) or a specific
* type such as a table. Right now there are no functions available for
* manipulating frame-specific properties, such as their formatting or their
* layout or the rows and columns of a table. They are just plain DIV-like
* things for now.</li>
* <li><tt>myLob.isListItem()</tt> returns whether <tt>myLob</tt> is a word
* processing Lob representing a paragraph that has been formatted as part of a list.
* Lists can be of a variety of formats.</li>
* <li><tt>myLob.paragraph()</tt> returns the paragraph containing <tt>myLob</tt>,
* if there is one. If not, an empty Lob is returned. If <tt>myLob</tt> is
* itself a paragraph, then it is returned.</li>
* <li><tt>myLob.nextParagraph()</tt> returns the paragraph immediately following
* <tt>myLob</tt>, if there is one in the context in which <tt>myLob</tt> sits.
* If there is no such Lob, an empty Lob is returned. If <tt>myLob</tt> is not
* itself a paragraph, but instead contains paragraphs, this routine will yield
* the first contained paragraph.</li>
* <li><tt>myLob.previousParagraph()</tt> returns the paragraph immediately before
* <tt>myLob</tt>, if there is one in the context in which <tt>myLob</tt> sits.
* If there is no such Lob, an empty Lob is returned. If <tt>myLob</tt> is not
* itself a paragraph, but instead is contained in one, this routine will yield
* that containing paragraph.</li>
* <li><tt>myLob.frame()</tt> returns the frame containing <tt>myLob</tt>,
* if there is one. If not, an empty Lob is returned. If <tt>myLob</tt> is
* itself a frame, it will not be returned, but rather the nearest containing
* frame will be, if any.</li>
* <li><tt>myLob.setCharacterFormat(key,value)</tt> sets an aspect of the character
* format of <tt>myLob</tt>, but only if it passes the <tt>isParagraph()</tt>
* or <tt>isText()</tt> test. Acceptable keys are those that appear in the
* following examples.<br>
* Make the text a hyperlink as follows (empty URL to remove the link):<br>
* <tt>myLob.setCharacterFormat('href','http://www.example.com')</tt><br>
* Change the font family as follows:<br>
* <tt>myLob.setCharacterFormat('family','Courier New')</tt><br>
* Change the font point size as follows:<br>
* <tt>myLob.setCharacterFormat('size',12.0)</tt><br>
* Set the foreground or background style as follows:<br>
* <tt>myLob.setCharacterFormat('fg style',Formats.SolidPattern)</tt><br>
* <tt>myLob.setCharacterFormat('bg style',Formats.CrossPattern)</tt><br>
* Set the foreground or background color as follows:<br>
* <tt>myLob.setCharacterFormat('fg color','\#ff007f')</tt><br>
* <tt>myLob.setCharacterFormat('bg color','\#000000')</tt><br>
* Note!! When setting a color, first ensure that the style has been set to
* something other than Formats.NoBrush, or your color settings will have no
* effect.<br>
* Set the bold, italic, and underline as follows:<br>
* <tt>myLob.setCharacterFormat('weight',Formats.BoldWeight)</tt><br>
* <tt>myLob.setCharacterFormat('italic',true)</tt><br>
* <tt>myLob.setCharacterFormat('underline',false)</tt></li>
* <li><tt>myLob.characterFormat(key)</tt> returns the current value for the given
* key. For a list of keys and what they mean, see immediately above.
* Note that some return values may be integers that need to be compared against values
* in the Formats data structure, described below. Furthermore,
* some may not be set at all, and thus return default values when queried.</li>
* <li>The above two functions can also be used without the "key" parameter. That is, you
* can lift a character format out of one Lob using <tt>myLob.characterFormat()</tt> and
* then apply it to another Lob using <tt>myLob.setCharacterFormat(value)</tt>. (The
* value is a string that encodes all the formatting data; its format was not designed
* for reading/editing.)</li>
* <li><tt>myLob.setParagraphFormat(key,value)</tt> sets an aspect of the paragraph
* format of <tt>myLob</tt>, but only if it passes the <tt>isParagraph()</tt>
* test. Acceptable keys are those that appear in the
* following examples.<br>
* Indent the paragraph as follows (zero for no indent, no negatives):<br>
* <tt>myLob.setParagraphFormat('indent',3)</tt>
* (Note that changing the indent to zero will make a paragraph no longer a
* list item.)<br>
* Change the paragraph's alignment as follows:<br>
* <tt>myLob.setParagraphFormat('align',Formats.AlignHCenter)</tt><br>
* Set the foreground or background style as follows:<br>
* <tt>myLob.setParagraphFormat('fg style',Formats.SolidPattern)</tt><br>
* <tt>myLob.setParagraphFormat('bg style',Formats.CrossPattern)</tt><br>
* Set the foreground or background color as follows:<br>
* <tt>myLob.setParagraphFormat('fg color','\#ff007f')</tt><br>
* <tt>myLob.setParagraphFormat('bg color','\#000000')</tt><br>
* Note!! When setting a color, first ensure that the style has been set to
* something other than Formats.NoBrush, or your color settings will have no
* effect.</li>
* <li><tt>myLob.paragraphFormat(key)</tt> returns the current value for the given
* key. For a list of keys and what they mean, see immediately above.
* Note that some return values may be integers that need to be compared against values
* in the Formats data structure, described below. Furthermore,
* some may not be set at all, and thus return default values when queried.</li>
* <li>The above two functions can also be used without the "key" parameter. That is, you
* can lift a paragraph format out of one Lob using <tt>myLob.paragraphFormat()</tt> and
* then apply it to another Lob using <tt>myLob.setParagraphFormat(value)</tt>. (The
* value is a string that encodes all the formatting data; its format was not designed
* for reading/editing.)</li>
* <li><tt>myLob.setListFormat(key,value)</tt> sets an aspect of the list
* format of <tt>myLob</tt>, but only if it passes the <tt>isListItem()</tt>
* test. Note!! Changes made to one list item affect only that list item,
* not the entire list.
* Acceptable keys are those that appear in the following examples.<br>
* Indent the list as follows (zero for no indent, no negatives):<br>
* <tt>myLob.setListFormat('indent',3)</tt><br>
* Change the item's style as follows:<br>
* <tt>myLob.setListFormat('style',Formats.ListLowerAlpha)</tt><br>
* Change whether the item starts a new list (if false, it is part of an
* ongoing list):<br>
* <tt>myLob.setListFormat('new',true)</tt></li>
* <li><tt>myLob.setIsListItem(true)</tt> makes <tt>myLob</tt> a list item, if it
* is not already one. It will have the attribute \"new\" (discussed in
* <tt>setListFormat()</tt>) by default.<br>
* <tt>myLob.setIsListItem(false)</tt> makes <tt>myLob</tt> no longer a list
* item, or does nothing if it already was not one.<br>
* Both of these functions can only be applied to paragraph Lobs.</li>
* <li><tt>myLob.listFormat(key)</tt> returns the current value for the given
* key. For a list of keys and what they mean, see immediately above.
* Note that some return values may be integers that need to be compared against values
* in the Formats data structure. Furthermore,
* some may not be set at all, and thus return default values when queried.</li>
* <li>Two fo the above functions can also be used without the "key" parameter. That is,
* you can lift a list format out of one Lob using <tt>myLob.listFormat()</tt> and
* then apply it to another Lob using <tt>myLob.setListFormat(value)</tt>. (The
* value is a string that encodes all the formatting data; its format was not designed
* for reading/editing.)</li>
* <li><tt>myLob.normalize()</tt> finds any text blocks inside the Lob hierarchy
* <tt>myLob</tt> and combines any adjacent text fragments with identical
* character formatting.<br>
* In other words, it is possible for a block to contain a text fragment
* <tt>"hello "</tt> followed immediately by a text fragment
* <tt>"there!"</tt>, with neither having any formatting (or both having the
* same non-default formatting), when in reality such a block could be
* represented more simply with just one text fragment. Thus we provide this
* normalization routine that combines all such sequences into one.<br>
* Any other attributes of either text fragment are copied to the combined
* text fragment, with those of the first (left) text fragment taking
* precedence in the case of conflicts.</li>
* </ul>
*
* <h3>Global Formats object</h3>
* This routine also provides a global object called <tt>Formats</tt> that
* stores constants relating to text, paragraphs, and lists.
* These constants all come from the underlying Qt framework on which
* Lurch is built. You can search Qt docs for any of these constants
* for more information.
*
* \code
* // Brush patterns
* Formats.NoBrush == Qt::NoBrush
* Formats.SolidPattern == Qt::SolidPattern
* Formats.Dense1Pattern == Qt::Dense1Pattern
* Formats.Dense2Pattern == Qt::Dense2Pattern
* Formats.Dense3Pattern == Qt::Dense3Pattern
* Formats.Dense4Pattern == Qt::Dense4Pattern
* Formats.Dense5Pattern == Qt::Dense5Pattern
* Formats.Dense6Pattern == Qt::Dense6Pattern
* Formats.Dense7Pattern == Qt::Dense7Pattern
* Formats.HorPattern == Qt::HorPattern
* Formats.VerPattern == Qt::VerPattern
* Formats.CrossPattern == Qt::CrossPattern
* Formats.BDiagPattern == Qt::BDiagPattern
* Formats.FDiagPattern == Qt::FDiagPattern
* Formats.DiagCrossPattern == Qt::DiagCrossPattern
* Formats.LinearGradientPattern == Qt::LinearGradientPattern
* Formats.ConicalGradientPattern == Qt::ConicalGradientPattern
* Formats.RadialGradientPattern == Qt::RadialGradientPattern
* // Alignments
* Formats.AlignLeft == Qt::AlignLeft
* Formats.AlignRight == Qt::AlignRight
* Formats.AlignJustify == Qt::AlignJustify
* Formats.AlignHCenter == Qt::AlignHCenter
* Formats.AlignTop == Qt::AlignTop
* Formats.AlignBottom == Qt::AlignBottom
* Formats.AlignVCenter == Qt::AlignVCenter
* Formats.AlignCenter == Qt::AlignCenter
* // Font weights
* Formats.Light == QFont::Light
* Formats.Normal == QFont::Normal
* Formats.DemiBold == QFont::DemiBold
* Formats.Bold == QFont::Bold
* Formats.Black == QFont::Black
* // List styles
* Formats.ListDisc == QTextListFormat::ListDisc
* Formats.ListCircle == QTextListFormat::ListCircle
* Formats.ListSquare == QTextListFormat::ListSquare
* Formats.ListDecimal == QTextListFormat::ListDecimal
* Formats.ListLowerAlpha == QTextListFormat::ListLowerAlpha
* Formats.ListUpperAlpha == QTextListFormat::ListUpperAlpha
* Formats.ListLowerRoman == QTextListFormat::ListLowerRoman
* Formats.ListUpperRoman == QTextListFormat::ListUpperRoman
* \endcode
*/
void addLobTextToScriptEngine ( QScriptEngine& engine );
/** \brief A class that can hear a signal from a LurchEnvironment and refill its engine with the
* text API
*
* LurchEnvironments recreate their script engines regularly for various reasons, and thus need
* to have the new versions refilled with any necessary tools, such as the Lob text API provided
* by addLobTextToScriptEngine(). This class is simply a slot that calls that function, and
* thus it can be connected to LurchEnvironment::newScriptEngine().
*/
class KeepLobTextAdded : public QObject
{
Q_OBJECT
public slots:
/** \brief Calls addLobTextToScriptEngine() on \a engine
*
* Can be connected to LurchEnvironment::newScriptEngine() signal.
*/
void addLobText ( QScriptEngine* engine );
};
#endif // QTEXTDOCUMENTSCRIPT_H