Search:   Help

Developers' side bar

Selected categories

Edit

Shared groups

Links

SourceCodeExploration

<< | Page list | >>

Because of the limitations of the wiki the content of this page was moved here, where it suffered a great deal of changes. That location is temporary, until the article reaches a certain maturity. It is expected to move to a proper place afterwards.

This page is obsolete.

Table of contents (hide)

  1.   1.  Introduction
  2.   2.  Logical structure of the code
    1.   2.1  The almighty buffer
    2.   2.2  Color handling
    3.   2.3  Error handling
    4.   2.4  Font handling
    5.   2.5  LFUNs

1.  Introduction

The FilesInTrunk page gives an overview of the trunk folder's content. One of the folders is src, which is the target of this page.

2.  Logical structure of the code

This section gives an overview of the files placed directly in src folder, while organising them in logical groups.

2.1  The almighty buffer

TODO: this section has to be the top level node, that reference as many other elements as it can

The Buffer class represents a document loaded into LyX. Beside the file that should be loaded and a read-only marker (that can be alter altered via setReadonly() and querried with isReadonly(), the constructor also accepts another Buffer to clone. Cloning may also be achieved with dedicated clone() method and, when in doubt, use isClone() to tell which is which..

To execute a command (either in the form of a string or of a FuncRequest) over this document use the high-level interface to buffer functionality provided by dispatch(). Afterwards, DispatchResult will tell about the completion status of the function. An arbitrary FuncRequest may or may not be executed at a given time; getStatus() will attempt to decide the case. Further informations about the dispatch mechanism are given in NotesOnDispatchMechanism.

TODO: make section for par. and reference it here Paragraphs in a document have unique IDs that can be used to retrieve them using getParFromID(). One can always check if a certain ID is present in a document with hasParWithID(). Paragraphs are organised in a linked list hidden behind a ParagraphList class and paragraphs() method that gets that ParagraphList. The list may be iterated by getting par_iterator_begin() and par_iterator_end().

A document may be associated with a WorkAreaManager when in GUI mode IDEA: hidden load for scripts in GUI mode that is retrievable using workAreaManager(). TODO: expand this to give a reference to the front end

bufferErrors() is capable of matching a list defined as TeXErrors to the actual places in the document. runChktex() is the one that can produce a TeXErrors instance to give a meaning to bufferErrors().TODO: OK, this sounds awful. Understand what's going on! Rephrase!

A document has a main language that is is reported by language() as a Language class pointer. To change the language of a document use changeLanguage() that will, essentially, change the language of each contained paragraph. isMultiLingual() will also extract the information from the same list. getLanguages() is able to provide a list of all the languages that are used in a buffer, including the buffer's main language, even if that's not used at all inside.

Buffers may be arranged in a tree-like network, with one buffer being the parent() and one or more being the kids. hasChildren() is a nice simple way of telling which buffer is prolific. If isChild() says yay then the buffer argument will be amongst the ones in the list returned by getChildren() (only direct children) and getDescendents() (kids and kid's kids on all levels). While at the tree of buffers, one neat function is allRelatives(), that collects all relative buffers, in the order in which they appear, starting with the masterBuffer(), and having same structure whatever the origin of the call is. The tree is constructed using calls to setParent() and a buffer is placed at a specific position withing another buffer with setChild(). A helper function in this regard is firstChildPosition() that finds first occurrence of the child inside the master (not parent) as a DocIterator.

Undo / redo functionality is provided using embedded Undo.

changed() function is called whenever a buffer is modified.

Bibliography TODO: superficial

Reference information is cached in the Buffer to speed up the execution by not having to check or read things over and over. LyX uses a system of two caches: one is a cache of the BibTeX files from which reference info is being gathered. This cache is PER BUFFER, and the cache for the master essentially includes the cache for its children. This gets invalidated when invalidateBibinfoCache() gets called or an InsetBibtex is created, deleted, or modified. invalidateBibfileCache() invalidates de cache of files to be checked. The other is a cache of the reference information itself. This exists only in the master buffer, and when it needs to be updated, the children add their information to the master's cache. To get access to BiblioInfo there is a masterBibInfo() provided. It will retrieve BiblioInfo for the master (the root of the tree).

reloadBibInfoCache() takes into account cache's validity when deciding to reload all BibTeX info. Also, collectBibKeys() will look into various insets in the Buffer and collect their bibliography info. Both addBiblioInfo() and addBibTeXInfo() can be used to enrich the bibliography. A citation label may be valid or in the need for an update, as reported by citeLabelsValid().

getLabelList() does indeed get a list of labels. TODO: wtf is that?

I/O

A document has unsaved changes if isClean() is false and, of course, isReadonly() is false, too. isDepClean() searches included documents, also, beside current buffer. To reset these values (mark as not needing save) use markClean() and markDepClean(). save() is the function to deal with all aspects of dumping the content of the Buffer to a file; this includes enforcing the read-only flag, IDEA: when found read-only, offer to SaveAs checking for modifications on the file from outside the environment, creating a backup and so on. saveAs() also relies on save() after it first asks for a new file path and name. writeFile() is then called, but this is also a top level function that prepares the ground to write(). Latter one writes a header, generic parameters and the document content to provided stream. saveCheckSum() will compute and store a checksum for current file. While slow, the function helps in checking if a file isExternallyModified() (outside this environment) and is related to the functionality presented here. TODO: reference to file format

Most Buffers have an associated fileName() (but one that isInternal(), holding some auxiliary text segment, never has). To see which is which, use isUnnamed() and change this state with setUnnamed(). Beside the output type, absFileName() looks identical to fileName(), since the comments in source code suggest that both tell the absolute file path. The names, on the other hand, suggest that fileName() may return a relative path or only the name. TODO: help needed One may find itself wondering what's the absolute path of the file and, then, filePath() comes in handy. Also related to the file name is latexName(), that gets a transformed version of the file name, adequate for LaTeX, and logName() to tell the name and type of the log. Ok, that's not really related. :)

Reading a file into a Buffer is handled, at top level, by two methods: loadThisLyXFile() will invoke internal readFile() method on the file provided as a path string and loadLyXFile() will attempt several other options (version control via extractFromVC(), emergency load, autosave TODO:link to abstract description of these features) before falling back to loadThisLyXFile(). An already loaded file may be reload()ed (internally, it also uses loadLyXFile()).

A set of functions deal with autosave and emergency files. Autosave is activated at certain intervals that may be reset by resetAutosaveTimers(). emergencyWrite() will attempt to write the content of the Buffer instance in a file named getEmergencyFileName() to various places (like same folder as the file, home folder, temp folder) before giving up. autoSave() does a similar job on regular intervals, according to user settings, over the file returned by getAutosaveFileName(). The autosave file is moved by moveAutosaveFile() and removed by removeAutosaveFile(). To load the content of a file like this, the implementation will call either loadAutosave() or loadEmergency() (at this time loadLyXFile() is the only function that makes use of this functionality). TODO:link to abstract description of these features

As mentioned, the medium level function for reading is readFile(). It checks for file existence and attempts to parse the content using Lexer. The code tries to derive the format from the header (see parseLyXFormat() below) and, if the format is not native, a conversion is attempted. In case of success, readFile() is re-run over the resulted file. In the end, readFile() function asks readDocument() to look into the content and perform actual loading. Each of the enumerated steps may fail for a number of reasons, so readFile() sets a flag indicating that loading was successful that can be queried by isFullyLoaded() function (setFullyLoaded() directly alters that flag). readString() function is similar to readFile(), except that the input is a string.

parseLyXFormat() is simply interested in detecting if the header of the file indicates a valid .lyx file and, if so, what is the version of the format used to write that file. readHeader() is another low level function invoked by readDocument() that works on a Lexer argument. A file from a different version than current one (indicated by LYX_FORMAT) is converted using convertLyXFormat() which will run a conversion script on that file and output a temporary file in current version so that other functions may understand it.

To save the content of a Buffer to a LaTeX file one may use makeLaTeXFile(), that relies on writeLaTeXSource() to perform actual serialization, after the buffer is validate()ed for requested LaTeXFeatures (there is one terrifying graphic on that page. Go see.). Particularly, latexParagraphs() is use to save the list of paragraphs in the document, and it relies to TeXOnePar(), among other things. Same pattern is used with DocBook output, where makeDocBookFile() deals with the file, writeDocBookSource() deals with a stream and docbookParagraphs() saves individual paragraphs. A LyXHTML file may also be exported with makeLyXHTMLFile() (again, several steps are involved, among which: writeLyXHTMLSource() and a XHTMLStream stream). For a detailed discussion of the output formats and the steps involved, see the section. TODO: proper link to section (how?)

Macros

updateMacros() will clear current definitions in the table of macros and will scan each paragraph starting with the first for macro definitions. updateMacroInstances() will also iterate the buffer in order to resolve the macros. To get a MacroNameSet (a list of macro names) hosted by this buffer, the parent and the children. A slightly different version is to get the a MacroSet (list of MacroData) from the parent of this buffer, along with macros from inside all it's children.

To get the MacroData for a particular macro name a three variant getMacro() is provided. By providing a DocIterator as argument the variant that will search the macro before provided position (or in the master buffer) is selected. When a Buffer is used, it is interpreted as the child buffer before which the definition needs to be found. Last variant searches for the macro in the whole body of the buffer and, eventually, in the master buffer.

At readDocument() time the macros are stored in a custom list (UserMacroSet). For kids, the list will be flushed to parent parent list, leaving it empty.

Various

B_() is capable of returning the message argument in document's language via gettext.

temppath() tells where to place temporary files for this buffer.

texrow() will get you an TexRow instance that maps between paragraphs and the generated LaTeX file., usable when typesetting to place error boxes.

Buffers have version control functionality provided by LyXVC class that is retrievable with lyxvc().

BufferParams contains all the parameters for a buffer's use and is retrievable using params().

loader() function gets the PreviewLoader associated with this buffer. To update previews associated with the buffer use updatePreviews(). removePreviews() surprisingly removes all associated previews.

class, that encapsulates the main text data and operations in LyX, is accessed via text(). Top-level InsetText is found with inset().

changeRefsIfUnique() will replace the inset contents for insets which InsetCode is equal to the provided code.

getSourceCode() to get source code (latex/docbook) for some paragraphs, or all paragraphs including preamble.

errorList() get's one access to the error list and is used only for GUI visualisation of Buffer related errors (like parsing or LateX compilation). This method is const because modifying the returned ErrorList does not touch the document contents.

tocBackend() is useful only for screen visualisation of the Buffer. This method is const because modifying this backend does not touch the document contents. updateTocItem() is called when the buffer structure has been updated.

structureChanged() is informed when the buffer structure is changed.

One can always tell if we're in the middle of the export operation using isExporting(). Internal setExportStatus() changes the relevant status. setMathFlavor() selects the way mathematical expressions are exported to html; options include MathML, images, HTML and LaTeX.

The list of references() consist of pairs of Insets and ParIterators. The cache of references may be cleared with clearReferenceCache()""". Inside this cache, the InsetLabel for a particular name is set with setInsetLabel() and may latter be retrieved using insetLabel()'''.

A list of names for used branches located both in master and in all its children is found with a call to getUsedBranches().

setBuffersForInsets() ToDo: what does this?. updateBuffer() is recursing in the buffer, visiting all insets and paragraphs and refreshing various information (like the labels).

spellCheck() starts from indicated position and looks for a misspelled word. If found, it returns it's position, misspelled word as a WordLangTuple (which also tells the language) and a list of suggestions.

checkChildBuffers() will ensure coherency inside this buffer and will alert the user if some child buffers were not found.

setFileName() does what it say, but also set the read only flag,, updates the checksum and visual appearance.

GuiBufferDelegate is the interface to Graphical User Interface and one may be associated with the buffer using setGuiDelegate(). To see if one buffer has indeed a GUI representation, use hasGuiDelegate(). errors() makes the connection with the GUI when faulty conditions arise. Another GUI-related function is setBusy(), that enables or disables certain features. To update the captions of panels for all users call updateTitles(). The user may be alerted with a message().

The files relevant to document buffer are: Buffer (.h, .cpp), buffer_funcs (.h, .cpp), BufferList (.h, .cpp), BufferParams (.h, .cpp) and BufferView (.h, .cpp).

2.2  Color handling

A single color is represented inside LyX using a Color class instance. Internally, it is represented using either by one base ColorCode or a combination of a base and an auxiliary ColorCode. A ColorSet is a class that associates actual RGB values with names and ColorCode indexes. Given any ColorCode code, ColorSet is able to tell it's GUI, X11, LaTeX or LyX name.

RGBColor structure provides an unified way to deal with explicit colors inside LyX. It stores actual color components and is used across application whenever internal representation is not appropriate.

The files relevant to color handling are ColorCode.h, ColorSet.h and Color (.h, .cpp).

2.3  Error handling

One error inside a document is represented by a ErrorItem class instance. It is capable of storing a pointer to the Buffer that caused this error, the ID of the paragraph and placement (start and end offset) inside this paragraph. Also, an error name and a description for that error are stored. To gather some error items together use ErrorList class.

TODO: other functions and methods for reporting the errors

The files relevant to error handling are ErrorList (.h, .cpp)

2.4  Font handling

A FontList instance is capable of storing a list of FontTable entries. Being a container, it allows the retrieval of first (begin()), last (end()) or arbitrary entry (get()). fontIterator() will get an iterator at specified position. One item may be erase()d or the list may be clear()ed out completely. The font at a certain position may be set() to hold characteristics of a Font or an entire range (setRange()) may be formatted. increasePosAfterPos() and decreasePosAfterPos() will change internally stored placement for the set of FontTable entries after or before specified position. The validate() method simply iterates the entire range and asks the Font instance embedded in FontTable.

As previously mentioned, a FontTable hosts a Font and a position. It's methods allow the change and retrieval of these internal properties. The Font envelops a FontInfo, a pointer and can tell if latexWriteStartChanges() opened an encoding environment ToDo: Come back when you know what this means . The methods in Font class are mostly related to it's constituents, allowing the caller to know details about the font using fontInfo(), the language(), the direction of writing. The characteristics are changed using setLanguage() or update(). The font may be saved toString() and may be loaded fromString(). lyxWriteChanges() deals with the .lyx file format and only appends to the stream if a characteristic is different from previous font. latexWriteStartChanges() and latexWriteEndChanges() write the head and the tail of the LaTeX needed to change to this font.

FontInfo class is the one that stores extended information about the way a chunk of text has to be rendered. Each of the properties below my hold special codes to inherit from the layout or default font and to ignore this property during an update.

  • FontFamily may hold well known families like Roman, Sans-serifs, Symbol and others;
  • the FontSeries property deals with the weight of the font (that may be normal or bold);
  • FontShape is either italic, slanted (unlike italic type it does not use different glyph shapes), regular shaped or written in small caps; to get the actual shape use realShape(), as it takes into consideration other elements (emphasis, noun);
  • FontSize is constrained to a set of values ranging from tiny to huge and huger. There are codes defined for increase and decrease of the size with one unit.
  • the background color is a ColorCode;
  • the fore-color is also a ColorCode, but it may be overridden by a Color using setPaintColor(); to get the Color that is used simply call realColor();
  • a number of boolean properties are also present: emphasis, underlined, strikeout, double-underlined, wavy underlined, number ? and noun ?.

The class is equipped with methods that alters or report individual properties. On top of that the size may be changed one step at a time using decSize() and incSize(). Other methods that alter internal state are reduce() (to mark fields that are identical with provided template as inheritors) and realize (the opposite action: copy actual values in the fields marked as inheritors). An FontInfo instance may be saved in CSS format to a string using asCSS().

The files relevant to font handling are FontEnums.h, Font (.h, .cpp), FontInfo (.h, .cpp) and FontList (.h, .cpp).

2.5  LFUNs

(for a discussion about the dispatch mechanism check out NotesOnDispatchMechanism)

TODO: Update NotesOnDispatchMechanism page. Benefits on merging this section with that page? The other way around?

LFUNs (or commands) are carriers that ship requests from the user to internal code. Each such function must have a corresponding code defined in FuncCode. To add a new function:

  • add a new enum constant immediately before LFUN_LASTACTION in FuncCode.h
  • add an appropriate line and documentation in LyXAction.cpp
  • add a branch to a suitable ::doDispatch() method
  • add correct test to the corresponding ::getStatus() method

A function is defined by a FuncStatus instance. It contains a list of boolean characteristics like:

  • is it checked or not via onOff() - usable for boolean LFUNs; the status is set using setOnOff();
  • is it enabled() or not (answers to: shall the user be able to use the command?); setEnabled() changes this state;
  • is it a valid command or it is unknown(), so to speak. To modify this status use setUnknown()

FuncStatus also holds a message that is modifiable. clear() function removes the message and sets enabled state to on and marks it as being valid.

When a command is issued a FuncRequest instance is created. Beside the mandatory FuncCode, this also has the ability to store arguments in the form of a string, the source of the command (like toolbar, menu, ...), the position of the mouse and what mouse buttons were pressed. Arguments may latter be retrieved by index using getArg() or getLongArg().

LyXAction is the main class dealing with commands, as it plays the role of an action container and associates a human-readable name to most of them. Internally, each function/command is represented by a FuncInfo class that comprises a name, a FuncType, that may be:

  • Hidden: Not listed for configuration
  • Edit: Cursor and mouse movement, copy/paste etc.
  • Math: Mathematics
  • Buffer: Buffer and window related
  • Layout: Font, Layout and textclass related
  • System: Lyx preference, server etc

and a set of boolean switches defined by FuncAttribs to be:

  • Noop: Nothing special about this function
  • ReadOnly: Can be used in RO mode (perhaps this should change)
  • NoBuffer: Can be used when there is no document open
  • Argument: Requires argument
  • NoUpdate: Does not (usually) require update
  • SingleParUpdate: Usually only requires this par updated
  • AtPoint: dispatch first to inset at cursor if there is one
  • NoInternal: Cannot be used for internal, non-document Buffers

A string is parsed into a FuncRequest instance by lookupFunc(). The name that is associated with a FuncCode is obtained using getActionName(). The list of LFUNs may be iterated from the start (func_begin()) and from the end (func_end().

The files relevant to function handling are LyXAction (.h, .cpp)FuncCode.h (defines internal LFUNs. Doxygen section for FuncCode does a good job documenting the actions.), FuncRequest (.h, .cpp) and FuncStatus (.h, .cpp)

... content stripped ...


Credits: This page shamelessly incorporates text from other pages in this wiki, comments in the source code, Wikipedia, Google search results and so on and so forth. If anyone feels that some piece of text is part of her/his thesaurus, please edit and add a note about this fact, while accepting deepest and sincere apologies from the editors of this page.


Category: Development, Documentation

Edit - History - Print - Recent Changes - All Recent Changes - Search
Page last modified on 2011-12-12 07:11 UTC