4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author Lars Gullik Bjønnes
9 * Full author contact details are available in file CREDITS.
15 #include "OutputEnums.h"
17 #include "support/unique_ptr.h"
18 #include "support/strfwd.h"
19 #include "support/types.h"
55 class ParConstIterator;
65 class GuiBufferDelegate;
66 class WorkAreaManager;
81 typedef std::list<Buffer *> ListOfBuffers;
82 /// a list of Buffers we cloned
83 typedef std::set<Buffer *> CloneList;
86 /** The buffer object.
87 * This is the buffer object. It contains all the information about
88 * a document loaded into LyX.
89 * The buffer object owns the Text (wrapped in an InsetText), which
90 * contains the individual paragraphs of the document.
93 * I am not sure if the class is complete or
94 * minimal, probably not.
95 * \author Lars Gullik Bjønnes
98 class MarkAsExporting;
102 /// What type of log will \c getLogName() return?
104 latexlog, ///< LaTeX log
105 buildlog ///< Literate build log
108 /// Result of \c readFile()
118 ReadEmergencyFailure,
135 ExportNoPathToFormat,
136 ExportTexPathHasSpaces,
137 ExportConverterError,
139 // Implies ExportSuccess.
141 // The exported file exists but there was an error when opening
146 /// Method to check if a file is externally modified, used by
147 /// isExternallyModified()
149 * timestamp is fast but inaccurate. For example, the granularity
150 * of timestamp on a FAT filesystem is 2 seconds. Also, various operations
151 * may touch the timestamp of a file even when its content is unchanged.
153 * checksum is accurate but slow, which can be a problem when it is
154 * frequently used, or used for a large file on a slow (network) file
157 * FIXME: replace this method with support/FileMonitor.
160 checksum_method, ///< Use file checksum
161 timestamp_method ///< Use timestamp, and checksum if timestamp has changed
171 explicit Buffer(std::string const & file, bool readonly = false,
172 Buffer const * cloned_buffer = 0);
177 /// Clones the entire structure of which this Buffer is part, starting
178 /// with the master and cloning all the children, too.
179 Buffer * cloneFromMaster() const;
180 /// Just clones this single Buffer. For autosave.
181 Buffer * cloneBufferOnly() const;
183 bool isClone() const;
185 /** High-level interface to buffer functionality.
186 This function parses a command string and executes it.
188 void dispatch(std::string const & command, DispatchResult & result);
190 /// Maybe we know the function already by number...
191 void dispatch(FuncRequest const & func, DispatchResult & result);
193 /// Can this function be exectued?
194 /// \return true if we made a decision
195 bool getStatus(FuncRequest const & cmd, FuncStatus & flag);
198 DocIterator getParFromID(int id) const;
199 /// do we have a paragraph with this id?
200 bool hasParWithID(int id) const;
203 frontend::WorkAreaManager & workAreaManager() const;
206 Takes care of auto-save files and backup file if requested.
207 Returns \c true if the save is successful, \c false otherwise.
210 /// Renames and saves the buffer
211 bool saveAs(support::FileName const & fn);
213 /// Write document to stream. Returns \c false if unsuccessful.
214 bool write(std::ostream &) const;
215 /// Write file. Returns \c false if unsuccessful.
216 bool writeFile(support::FileName const &) const;
218 /// \name Functions involved in reading files/strings.
220 /// Loads the LyX file into the buffer. This function
221 /// tries to extract the file from version control if it
222 /// cannot be found. If it can be found, it will try to
223 /// read an emergency save file or an autosave file.
224 /// \sa loadThisLyXFile
225 ReadStatus loadLyXFile();
226 /// Loads the LyX file \c fn into the buffer. If you want
227 /// to check for files in a version control container,
228 /// emergency or autosave files, one should use \c loadLyXFile.
230 ReadStatus loadThisLyXFile(support::FileName const & fn);
231 /// import a new document from a string
232 bool importString(std::string const &, docstring const &, ErrorList &);
233 /// import a new file
234 bool importFile(std::string const &, support::FileName const &, ErrorList &);
235 /// read a new document from a string
236 bool readString(std::string const &);
237 /// Reloads the LyX file
239 //FIXME: The following function should be private
241 /// read the header, returns number of unknown tokens
242 int readHeader(Lexer & lex);
244 double fontScalingFactor() const;
248 typedef std::map<Buffer const *, Buffer *> BufferMap;
250 void cloneWithChildren(BufferMap &, CloneList *) const;
251 /// save timestamp and checksum of the given file.
252 void saveCheckSum() const;
254 ReadStatus readFile(support::FileName const & fn);
255 /// Reads a file without header.
256 /// \param par if != 0 insert the file.
257 /// \return \c true if file is not completely read.
258 bool readDocument(Lexer &);
259 /// Try to extract the file from a version control container
260 /// before reading if the file cannot be found.
261 /// \sa LyXVC::file_not_found_hook
262 ReadStatus extractFromVC();
263 /// Reads the first tag of a LyX File and
264 /// returns the file format number.
265 ReadStatus parseLyXFormat(Lexer & lex, support::FileName const & fn,
266 int & file_format) const;
267 /// Convert the LyX file to the LYX_FORMAT using
268 /// the lyx2lyx script and returns the filename
269 /// of the temporary file to be read
270 ReadStatus convertLyXFormat(support::FileName const & fn,
271 support::FileName & tmpfile, int from_format);
272 /// get appropriate name for backing up files from older versions
273 support::FileName getBackupName() const;
277 /// \name Functions involved in autosave and emergency files.
279 /// Save an autosave file to #filename.lyx#
280 bool autoSave() const;
281 /// save emergency file
282 /// \return a status message towards the user.
283 docstring emergencyWrite();
285 //FIXME:The following function should be private
288 void removeAutosaveFile() const;
291 /// Try to load an autosave file associated to \c fn.
292 ReadStatus loadAutosave();
293 /// Try to load an emergency file associated to \c fn.
294 ReadStatus loadEmergency();
295 /// Get the filename of the emergency file associated with the Buffer
296 support::FileName getEmergencyFileName() const;
297 /// Get the filename of the autosave file associated with the Buffer
298 support::FileName getAutosaveFileName() const;
300 void moveAutosaveFile(support::FileName const & old) const;
304 /// Fill in the ErrorList with the TeXErrors
305 void bufferErrors(TeXErrors const &, ErrorList &) const;
315 /// Just a wrapper for writeLaTeXSource, first creating the ofstream.
316 bool makeLaTeXFile(support::FileName const & filename,
317 std::string const & original_path,
318 OutputParams const &,
319 OutputWhat output = FullSource) const;
320 /** Export the buffer to LaTeX.
321 If \p os is a file stream, and params().inputenc is "auto" or
322 "default", and the buffer contains text in different languages
323 with more than one encoding, then this method will change the
324 encoding associated to \p os. Therefore you must not call this
325 method with a string stream if the output is supposed to go to a
329 ofs.open("test.tex");
330 writeLaTeXSource(os, ...);
332 \endcode is NOT equivalent to \code
333 odocstringstream oss;
335 writeLaTeXSource(os, ...);
337 ofs.open("test.tex");
342 void writeLaTeXSource(otexstream & os,
343 std::string const & original_path,
344 OutputParams const &,
345 OutputWhat output = FullSource) const;
347 void makeDocBookFile(support::FileName const & filename,
348 OutputParams const & runparams_in,
349 OutputWhat output = FullSource) const;
351 void writeDocBookSource(odocstream & os, std::string const & filename,
352 OutputParams const & runparams_in,
353 OutputWhat output = FullSource) const;
355 void makeLyXHTMLFile(support::FileName const & filename,
356 OutputParams const & runparams_in) const;
358 void writeLyXHTMLSource(odocstream & os,
359 OutputParams const & runparams_in,
360 OutputWhat output = FullSource) const;
361 /// returns the main language for the buffer (document)
362 Language const * language() const;
363 /// get l10n translated to the buffers language
364 docstring const B_(std::string const & l10n) const;
368 /// return true if the main lyx file does not need saving
369 bool isClean() const;
371 bool isDepClean(std::string const & name) const;
373 /// whether or not disk file has been externally modified
374 bool isExternallyModified(CheckMethod method) const;
376 /// mark the main lyx file as not needing saving
377 void markClean() const;
380 void markDepClean(std::string const & name);
383 void setUnnamed(bool flag = true);
385 /// Whether or not a filename has been assigned to this buffer
386 bool isUnnamed() const;
388 /// Whether or not this buffer is internal.
390 /// An internal buffer does not contain a real document, but some auxiliary text segment.
391 /// It is not associated with a filename, it is never saved, thus it does not need to be
392 /// automatically saved, nor it needs to trigger any "do you want to save ?" question.
393 bool isInternal() const;
395 void setInternal(bool flag);
397 /// Mark this buffer as dirty.
400 /// Returns the buffer's filename. It is always an absolute path.
401 support::FileName fileName() const;
403 /// Returns the buffer's filename. It is always an absolute path.
404 std::string absFileName() const;
406 /// Returns the path where the buffer lives.
407 /// It is always an absolute path.
408 std::string filePath() const;
410 /** Contructs a file name of a referenced file (child doc, included graphics etc).
411 * Absolute names are returned as is. If the name is relative, it is
412 * interpreted relative to filePath() if the file exists, otherwise
413 * relative to the original path where the document was last saved.
414 * The original path may be different from filePath() if the document was
415 * later manually moved to a different location.
417 support::DocFileName getReferencedFileName(std::string const & fn) const;
419 /** Returns the path where a local layout file lives.
420 * An empty string is returned for standard system and user layouts.
421 * If possible, it is always relative to the buffer path.
423 std::string layoutPos() const;
425 /** Set the path to a local layout file.
426 * This must be an absolute path but, if possible, it is always
427 * stored as relative to the buffer path.
429 void setLayoutPos(std::string const & path);
431 /** A transformed version of the file name, adequate for LaTeX.
432 \param no_path optional if \c true then the path is stripped.
434 std::string latexName(bool no_path = true) const;
436 /// Get the name and type of the log.
437 std::string logName(LogType * type = 0) const;
439 /// Set document's parent Buffer.
440 void setParent(Buffer const *);
441 Buffer const * parent() const;
443 /** Get the document's master (or \c this if this is not a
446 Buffer const * masterBuffer() const;
448 /// \return true if \p child is a child of this \c Buffer.
449 bool isChild(Buffer * child) const;
451 /// \return true if this \c Buffer has children
452 bool hasChildren() const;
454 /// \return a list of the direct children of this Buffer.
455 /// this list has no duplicates and is in the order in which
456 /// the children appear.
457 ListOfBuffers getChildren() const;
459 /// \return a list of all descendents of this Buffer (children,
460 /// grandchildren, etc). this list has no duplicates and is in
461 /// the order in which the children appear.
462 ListOfBuffers getDescendents() const;
464 /// Collect all relative buffers, in the order in which they appear.
465 /// I.e., the "root" Buffer is first, then its first child, then any
466 /// of its children, etc. However, there are no duplicates in this
468 /// This is "stable", too, in the sense that it returns the same
469 /// thing from whichever Buffer it is called.
470 ListOfBuffers allRelatives() const;
472 /// Is buffer read-only?
473 bool isReadonly() const;
475 /// Set buffer read-only flag
476 void setReadonly(bool flag = true);
478 /** Validate a buffer for LaTeX.
479 This validates the buffer, and returns a struct for use by
480 #makeLaTeX# and others. Its main use is to figure out what
481 commands and packages need to be included in the LaTeX file.
482 It (should) also check that the needed constructs are there
483 (i.e. that the \refs points to coresponding \labels). It
484 should perhaps inset "error" insets to help the user correct
487 void validate(LaTeXFeatures &) const;
489 /// Reference information is cached in the Buffer, so we do not
490 /// have to check or read things over and over.
492 /// There are two caches.
494 /// One is a cache of the BibTeX files from which reference info is
495 /// being gathered. This cache is PER BUFFER, and the cache for the
496 /// master essentially includes the cache for its children. This gets
497 /// invalidated when an InsetBibtex is created, deleted, or modified.
499 /// The other is a cache of the reference information itself. This
500 /// exists only in the master buffer, and when it needs to be updated,
501 /// the children add their information to the master's cache.
503 /// Calling this method invalidates the cache and so requires a
505 void invalidateBibinfoCache() const;
506 /// This invalidates the cache of files we need to check.
507 void invalidateBibfileCache() const;
508 /// Updates the cached bibliography information, checking first to see
509 /// whether the cache is valid. If so, we do nothing. If not, then we
510 /// reload all the BibTeX info.
511 /// Note that this operates on the master document.
512 void reloadBibInfoCache() const;
513 /// \return the bibliography information for this buffer's master,
514 /// or just for it, if it isn't a child.
515 BiblioInfo const & masterBibInfo() const;
516 /// collect bibliography info from the various insets in this buffer.
517 void collectBibKeys() const;
518 /// add some BiblioInfo to our cache
519 void addBiblioInfo(BiblioInfo const & bi) const;
520 /// add a single piece of bibliography info to our cache
521 void addBibTeXInfo(docstring const & key, BibTeXInfo const & bi) const;
523 void makeCitationLabels() const;
525 bool citeLabelsValid() const;
527 void getLabelList(std::vector<docstring> &) const;
529 /// This removes the .aux and .bbl files from the temp dir.
530 void removeBiblioTempFiles() const;
533 void changeLanguage(Language const * from, Language const * to);
536 bool isMultiLingual() const;
538 std::set<Language const *> getLanguages() const;
541 BufferParams & params();
542 BufferParams const & params() const;
544 BufferParams const & masterParams() const;
546 /** The list of paragraphs.
547 This is a linked list of paragraph, this list holds the
548 whole contents of the document.
550 ParagraphList & paragraphs();
551 ParagraphList const & paragraphs() const;
553 /// LyX version control object.
555 LyXVC const & lyxvc() const;
557 /// Where to put temporary files.
558 std::string const temppath() const;
560 /// Used when typesetting to place errorboxes.
561 TexRow const & texrow() const;
565 ParIterator par_iterator_begin();
567 ParConstIterator par_iterator_begin() const;
569 ParIterator par_iterator_end();
571 ParConstIterator par_iterator_end() const;
573 // Position of the child buffer where it appears first in the master.
574 DocIterator firstChildPosition(Buffer const * child);
576 /** \returns true only when the file is fully loaded.
577 * Used to prevent the premature generation of previews
578 * and by the citation inset.
580 bool isFullyLoaded() const;
581 /// Set by buffer_funcs' newFile.
582 void setFullyLoaded(bool);
584 /// FIXME: Needed by RenderPreview.
585 graphics::PreviewLoader * loader() const;
586 /// Update the LaTeX preview snippets associated with this buffer
587 void updatePreviews() const;
588 /// Remove any previewed LaTeX snippets associated with this buffer
589 void removePreviews() const;
591 /// Our main text (inside the top InsetText)
594 /// Our top InsetText
595 Inset & inset() const;
600 /// Collect macro definitions in paragraphs
601 void updateMacros() const;
602 /// Iterate through the whole buffer and try to resolve macros
603 void updateMacroInstances(UpdateType) const;
605 /// List macro names of this buffer, the parent and the children
606 void listMacroNames(MacroNameSet & macros) const;
607 /// Collect macros of the parent and its children in front of this buffer.
608 void listParentMacros(MacroSet & macros, LaTeXFeatures & features) const;
610 /// Return macro defined before pos (or in the master buffer)
611 MacroData const * getMacro(docstring const & name, DocIterator const & pos, bool global = true) const;
612 /// Return macro defined anywhere in the buffer (or in the master buffer)
613 MacroData const * getMacro(docstring const & name, bool global = true) const;
614 /// Return macro defined before the inclusion of the child
615 MacroData const * getMacro(docstring const & name, Buffer const & child, bool global = true) const;
617 /// Collect user macro names at loading time
618 typedef std::set<docstring> UserMacroSet;
619 mutable UserMacroSet usermacros;
621 /// Replace the inset contents for insets which InsetCode is equal
622 /// to the passed \p inset_code.
623 void changeRefsIfUnique(docstring const & from, docstring const & to);
625 /// get source code (latex/docbook) for some paragraphs, or all paragraphs
626 /// including preamble
627 /// returns nullptr if Id to Row conversion is unsupported
628 unique_ptr<TexRow> getSourceCode(odocstream & os,
629 std::string const & format, pit_type par_begin,
630 pit_type par_end, OutputWhat output, bool master) const;
632 /// Access to error list.
633 /// This method is used only for GUI visualisation of Buffer related
634 /// errors (like parsing or LateX compilation). This method is const
635 /// because modifying the returned ErrorList does not touch the document
637 ErrorList & errorList(std::string const & type) const;
640 /// This is useful only for screen visualisation of the Buffer. This
641 /// method is const because modifying this backend does not touch
642 /// the document contents.
643 TocBackend & tocBackend() const;
648 /// This function is called when the buffer is changed.
649 void changed(bool update_metrics) const;
651 void setChild(DocIterator const & dit, Buffer * child);
653 void updateTocItem(std::string const &, DocIterator const &) const;
654 /// This function is called when the buffer structure is changed.
655 void structureChanged() const;
656 /// This function is called when some parsing error shows up.
657 void errors(std::string const & err, bool from_master = false) const;
658 /// This function is called when the buffer busy status change.
659 void setBusy(bool on) const;
660 /// Update window titles of all users.
661 void updateTitles() const;
662 /// Reset autosave timers for all users.
663 void resetAutosaveTimers() const;
665 void message(docstring const & msg) const;
668 void setGuiDelegate(frontend::GuiBufferDelegate * gui);
670 bool hasGuiDelegate() const;
673 ExportStatus doExport(std::string const & target, bool put_in_tempdir) const;
674 /// Export buffer to format \p format and open the result in a suitable viewer.
675 /// Note: This has nothing to do with preview of graphics or math formulas.
676 ExportStatus preview(std::string const & format) const;
677 /// true if there was a previous preview this session of this buffer and
678 /// there was an error on the previous preview of this buffer.
679 bool lastPreviewError() const;
683 ExportStatus doExport(std::string const & target, bool put_in_tempdir,
684 std::string & result_file) const;
685 /// target is a format name optionally followed by a space
686 /// and a destination file-name
687 ExportStatus doExport(std::string const & target, bool put_in_tempdir,
688 bool includeall, std::string & result_file) const;
690 ExportStatus preview(std::string const & format, bool includeall) const;
692 void setMathFlavor(OutputParams & op) const;
696 bool isExporting() const;
699 typedef std::vector<std::pair<Inset *, ParIterator> > References;
701 References const & references(docstring const & label) const;
703 void addReference(docstring const & label, Inset * inset, ParIterator it);
705 void clearReferenceCache() const;
707 void setInsetLabel(docstring const & label, InsetLabel const * il);
709 InsetLabel const * insetLabel(docstring const & label) const;
711 /// return a list of all used branches (also in children)
712 void getUsedBranches(std::list<docstring> &, bool const from_master = false) const;
714 /// sets the buffer_ member for every inset in this buffer.
715 // FIXME This really shouldn't be needed, but at the moment it's not
716 // clear how to do it just for the individual pieces we need.
717 void setBuffersForInsets() const;
718 /// Updates screen labels and some other information associated with
719 /// insets and paragraphs. Actually, it's more like a general "recurse
720 /// through the Buffer" routine, that visits all the insets and paragraphs.
721 void updateBuffer() const { updateBuffer(UpdateMaster, InternalUpdate); }
722 /// \param scope: whether to start with the master document or just
724 /// \param output: whether we are preparing for output.
725 void updateBuffer(UpdateScope scope, UpdateType utype) const;
727 void updateBuffer(ParIterator & parit, UpdateType utype) const;
729 /// Spellcheck starting from \p from.
730 /// \p from initial position, will then points to the next misspelled
732 /// \p to will points to the end of the next misspelled word.
733 /// \p word_lang will contain the found misspelled word.
734 /// \return progress if a new word was found.
735 int spellCheck(DocIterator & from, DocIterator & to,
736 WordLangTuple & word_lang, docstring_list & suggestions) const;
738 void checkChildBuffers();
740 void checkMasterBuffer();
742 /// If the document is being saved to a new location and the named file
743 /// exists at the old location, return its updated path relative to the
744 /// new buffer path if possible, otherwise return its absolute path.
745 /// In all other cases, this is a no-op and name is returned unchanged.
746 /// If a non-empty ext is given, the existence of name.ext is checked
747 /// but the returned path will not contain this extension.
748 /// Similarly, when loading a document that was moved from the location
749 /// where it was saved, return the correct path relative to the new
751 std::string includedFilePath(std::string const & name,
752 std::string const & ext = empty_string()) const;
754 /// compute statistics between \p from and \p to
755 /// \p from initial position
756 /// \p to points to the end position
757 /// \p skipNoOutput if notes etc. should be ignored
758 void updateStatistics(DocIterator & from, DocIterator & to,
759 bool skipNoOutput = true) const;
760 /// statistics accessor functions
761 int wordCount() const;
762 int charCount(bool with_blanks) const;
764 // this is const because it does not modify the buffer's real contents,
765 // only the mutable flag.
766 void setChangesPresent(bool) const;
767 bool areChangesPresent() const;
768 void updateChangesPresent() const;
771 friend class MarkAsExporting;
772 /// mark the buffer as busy exporting something, or not
773 void setExportStatus(bool e) const;
776 References & getReferenceCache(docstring const & label);
777 /// Change name of buffer. Updates "read-only" flag.
778 void setFileName(support::FileName const & fname);
780 void getLanguages(std::set<Language const *> &) const;
781 /// Checks whether any of the referenced bibfiles have changed since the
782 /// last time we loaded the cache. Note that this does NOT update the
783 /// cached information.
784 void checkIfBibInfoCacheIsValid() const;
785 /// Update the list of all bibfiles in use (including bibfiles
786 /// of loaded child documents).
787 void updateBibfilesCache(UpdateScope scope = UpdateMaster) const;
788 /// Return the list with all bibfiles in use (including bibfiles
789 /// of loaded child documents).
790 support::FileNameList const &
791 getBibfilesCache(UpdateScope scope = UpdateMaster) const;
793 void collectChildren(ListOfBuffers & children, bool grand_children) const;
796 Buffer(Buffer const &);
797 void operator=(Buffer const &);
799 /// Use the Pimpl idiom to hide the internals.
801 /// The pointer never changes although *pimpl_'s contents may.
806 /// Helper class, to guarantee that the export status
807 /// gets reset properly. To use, simply create a local variable:
808 /// MarkAsExporting mex(bufptr);
809 /// and leave the rest to us.
810 class MarkAsExporting {
812 MarkAsExporting(Buffer const * buf) : buf_(buf)
814 buf_->setExportStatus(true);
818 buf_->setExportStatus(false);
821 Buffer const * const buf_;