Dear list, The attached code is as ugly as it can be. It implements a feature (subject to random crash :-) that I was dreaming of when I first used lyx 1.1.6: preview piece of latex code for selected text. This feature can be useful in many ways:
1. to learn latex. You can enter things in lyx, and have a look at corresponding latex code. 2. to debug. latex errors will happen, and the best way to debug, at least for me, is to have a look at the generated latex code. Using this feature, I just need to select suspected paragraphs and view->latex. 3. for developers to debug latex output? Please, if someone has time, have a look at the patch and tell me what you think about it. Also, please tell me how you want the outputted latex code to be displayed: save to /tmp/... and use an external text editor, or use a message box. BTW, the ultimate form of this feature, is something like the 'show both' view of dreamweaver. You can write either in pure HTML code in the top panel, or in WYSIWYG in the bottom panel. Two panels will be in sync automatically. Of course, this is way too difficult for latex code. Cheers, Bo
Index: src/LyXAction.C =================================================================== --- src/LyXAction.C (revision 13545) +++ src/LyXAction.C (working copy) @@ -124,6 +124,7 @@ { LFUN_READ_ONLY_TOGGLE, "buffer-toggle-read-only", ReadOnly }, { LFUN_UPDATE, "buffer-update", ReadOnly }, { LFUN_PREVIEW, "buffer-view", ReadOnly }, + { LFUN_VIEW_LATEX, "view-latex", ReadOnly }, { LFUN_MENUWRITE, "buffer-write", ReadOnly }, { LFUN_WRITEAS, "buffer-write-as", ReadOnly }, { LFUN_CANCEL, "cancel", NoBuffer }, Index: src/output_latex.h =================================================================== --- src/output_latex.h (revision 13545) +++ src/output_latex.h (working copy) @@ -20,8 +20,19 @@ class OutputParams; class TexRow; +#include "support/types.h" + /// Just a wrapper for the method below, first creating the ofstream. +void latexParagraphRange(Buffer const & buf, + ParagraphList const & paragraphs, + lyx::pit_type par, + lyx::pit_type parend, + std::ostream & ofs, + TexRow & texrow, + OutputParams const &, + std::string const & everypar = std::string()); + void latexParagraphs(Buffer const & buf, ParagraphList const & paragraphs, std::ostream & ofs, Index: src/buffer.C =================================================================== --- src/buffer.C (revision 13545) +++ src/buffer.C (working copy) @@ -944,7 +944,62 @@ << '.' << endl; } +void Buffer::makePartialLaTeXFile(ostream & os, + lyx::pit_type pit_begin, + lyx::pit_type pit_end) +{ + OutputParams runparams; + runparams.flavor = OutputParams::LATEX; + runparams.nice = false; + // validate the buffer. + lyxerr[Debug::LATEX] << " Validating buffer..." << endl; + LaTeXFeatures features(*this, params(), runparams); + validate(features); + lyxerr[Debug::LATEX] << " Buffer validation done." << endl; + + texrow().reset(); + + // The starting paragraph of the coming rows is the + // first paragraph of the document. (Asger) + // I do not understand this. (bpeng) + texrow().start(paragraphs().begin()->id(), 0); + + os << "%% This is partial LyX output for paragraph"; + if (pit_begin == pit_end) + os << " " << pit_begin << "\n"; + else + os << "s from " << pit_begin << " to " << pit_end << "\n"; + texrow().newline(); + + if (!lyxrc.language_auto_begin) { + os << subst(lyxrc.language_command_begin, "$$lang", + params().language->babel()) + << endl; + texrow().newline(); + } + + // the real stuff + latexParagraphRange(*this, paragraphs(), pit_begin, pit_end, + os, texrow(), runparams); + + // add this just in case after all the paragraphs + os << endl; + texrow().newline(); + + if (!lyxrc.language_auto_end) { + os << subst(lyxrc.language_command_end, "$$lang", + params().language->babel()) + << endl; + texrow().newline(); + } + + lyxerr[Debug::INFO] << "Finished making LaTeX file." << endl; + lyxerr[Debug::INFO] << "Row count was " << texrow().rows() - 1 + << '.' << endl; +} + + bool Buffer::isLatex() const { return params().getLyXTextClass().outputType() == LATEX; Index: src/lyxfunc.C =================================================================== --- src/lyxfunc.C (revision 13545) +++ src/lyxfunc.C (working copy) @@ -388,6 +388,12 @@ return flag; } + // enable if there is a buffer. + if (cmd.action == LFUN_VIEW_LATEX) { + flag.setOnOff(buf); + return flag; + } + // I would really like to avoid having this switch and rather try to // encode this in the function itself. // -- And I'd rather let an inset decide which LFUNs it is willing @@ -1580,6 +1586,28 @@ break; } + case LFUN_VIEW_LATEX: { + // first, if there is no selection, + lyx::pit_type pitBegin; + lyx::pit_type pitEnd; + if ( !view()->cursor().selection() ) { + pitBegin = view()->cursor().pit(); + pitEnd = pitBegin + 1; + } + // choose the whole paragraph + // other wise, choose the selection + else { + std::cout << "the selection " << endl; + pitBegin = view()->cursor().selBegin().pit(); + pitEnd = view()->cursor().selEnd().pit() + 1; + } + // now, get the latex output + view()->buffer()->makePartialLaTeXFile(std::cout, pitBegin, pitEnd); + // flush + std::cout << std::endl; + break; + } + default: { view()->cursor().dispatch(cmd); update |= view()->cursor().result().update(); Index: src/buffer.h =================================================================== --- src/buffer.h (revision 13545) +++ src/buffer.h (working copy) @@ -152,6 +152,10 @@ OutputParams const &, bool output_preamble = true, bool output_body = true); + /// export partial latex, for view-latex + void makePartialLaTeXFile(std::ostream & os, + lyx::pit_type beginPit, + lyx::pit_type endPit); /// void makeLinuxDocFile(std::string const & filename, OutputParams const & runparams_in, Index: src/lfuns.h =================================================================== --- src/lfuns.h (revision 13545) +++ src/lfuns.h (working copy) @@ -358,6 +358,8 @@ LFUN_BIBDB_DEL, LFUN_INSERT_CITATION, LFUN_OUTLINE, // Vermeer 20060323 + // 275 + LFUN_VIEW_LATEX, // bpeng 20060401 LFUN_LASTACTION // end of the table }; Index: src/output_latex.C =================================================================== --- src/output_latex.C (revision 13545) +++ src/output_latex.C (working copy) @@ -450,8 +450,10 @@ // LaTeX all paragraphs -void latexParagraphs(Buffer const & buf, +void latexParagraphRange(Buffer const & buf, ParagraphList const & paragraphs, + lyx::pit_type par_begin, + lyx::pit_type par_end, ostream & os, TexRow & texrow, OutputParams const & runparams, @@ -460,9 +462,15 @@ bool was_title = false; bool already_title = false; LyXTextClass const & tclass = buf.params().getLyXTextClass(); - ParagraphList::const_iterator par = paragraphs.begin(); - ParagraphList::const_iterator endpar = paragraphs.end(); + // be a little bit more careful. + if (par_begin > paragraphs.size() || par_end > paragraphs.size() || par_begin >= par_end ) { + std::cout << "Wrong range? " << par_begin << " to " << par_end << endl; + return; + } + ParagraphList::const_iterator par = boost::next(paragraphs.begin(), par_begin); + ParagraphList::const_iterator endpar = boost::next(paragraphs.begin(), par_end); + // if only_body while (par != endpar) { // well we have to check if we are in an inset with unlimited @@ -530,3 +538,16 @@ texrow.newline(); } } + +// LaTeX all paragraphs +void latexParagraphs(Buffer const & buf, + ParagraphList const & paragraphs, + ostream & os, + TexRow & texrow, + OutputParams const & runparams, + string const & everypar) +{ + latexParagraphRange(buf, paragraphs, + 0, paragraphs.size(), + os, texrow, runparams, everypar); +} Index: lib/ui/stdmenus.ui =================================================================== --- lib/ui/stdmenus.ui (revision 13545) +++ lib/ui/stdmenus.ui (working copy) @@ -217,6 +217,7 @@ # Item "Close All Footnotes|C" "close-footnotes" Item "Display Tooltips|i" "toggle-tooltips" Separator + Item "View latex|l" "view-latex" Submenu "Update|U" "document_update" ViewFormats Separator