X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Foutput_xhtml.cpp;h=f01b0b8e62d04692277661fbba77f8df7b958767;hb=5cb80b867f4a59c3253487652ba74a29ad5b3f0f;hp=3f8c0a43b1c7e484ec4fb241dea12616abfba9dd;hpb=ebcaa5b1db605a3420c23a2e6b28a3b06ed4e180;p=lyx.git diff --git a/src/output_xhtml.cpp b/src/output_xhtml.cpp index 3f8c0a43b1..f01b0b8e62 100644 --- a/src/output_xhtml.cpp +++ b/src/output_xhtml.cpp @@ -3,7 +3,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Richard Heck + * \author Richard Kimberly Heck * * This code is based upon output_docbook.cpp * @@ -15,12 +15,11 @@ #include "output_xhtml.h" #include "Buffer.h" -#include "buffer_funcs.h" #include "BufferParams.h" #include "Counters.h" #include "Font.h" #include "Layout.h" -#include "OutputParams.h" +#include "LayoutEnums.h" #include "Paragraph.h" #include "ParagraphList.h" #include "ParagraphParameters.h" @@ -28,13 +27,10 @@ #include "Text.h" #include "TextClass.h" -#include "support/convert.h" -#include "support/debug.h" #include "support/lassert.h" -#include "support/lstrings.h" -#include "support/textutils.h" -#include +#include +#include // Uncomment to activate debugging code. // #define XHTML_DEBUG @@ -161,18 +157,27 @@ namespace { // convenience functions inline void openParTag(XMLStream & xs, Layout const & lay, - const std::string & parlabel) + std::string const & parlabel) { - string attrs = lay.htmlattr(); + string attrs = lay.htmlGetAttrString(); if (!parlabel.empty()) attrs += " id='" + parlabel + "'"; xs << xml::ParTag(lay.htmltag(), attrs); } +void openParTag(XMLStream & xs, Layout const & lay, + std::string const & cssclass, + std::string const & parlabel) { + string attrs = "class='" + cssclass + "'"; + if (!parlabel.empty()) + attrs += " id='" + parlabel + "'"; + xs << xml::ParTag(lay.htmltag(), attrs); +} + void openParTag(XMLStream & xs, Layout const & lay, ParagraphParameters const & params, - const std::string & parlabel) + std::string const & parlabel) { // FIXME Are there other things we should handle here? string const align = alignmentToCSS(params.align()); @@ -180,7 +185,7 @@ void openParTag(XMLStream & xs, Layout const & lay, openParTag(xs, lay, parlabel); return; } - string attrs = lay.htmlattr() + " style='text-align: " + align + ";'"; + string attrs = lay.htmlGetAttrString() + " style='text-align: " + align + ";'"; if (!parlabel.empty()) attrs += " id='" + parlabel + "'"; xs << xml::ParTag(lay.htmltag(), attrs); @@ -207,27 +212,33 @@ inline void closeLabelTag(XMLStream & xs, Layout const & lay) inline void openItemTag(XMLStream & xs, Layout const & lay) { - xs << xml::StartTag(lay.htmlitemtag(), lay.htmlitemattr(), true); + if (lay.htmlitemtag() != "NONE") { + xs << xml::StartTag(lay.htmlitemtag(), lay.htmlitemattr(), true); + } } void openItemTag(XMLStream & xs, Layout const & lay, ParagraphParameters const & params) { - // FIXME Are there other things we should handle here? - string const align = alignmentToCSS(params.align()); - if (align.empty()) { - openItemTag(xs, lay); - return; + if (lay.htmlitemtag() != "NONE") { + // FIXME Are there other things we should handle here? + string const align = alignmentToCSS(params.align()); + if (align.empty()) { + openItemTag(xs, lay); + return; + } + string attrs = lay.htmlGetAttrString() + " style='text-align: " + align + ";'"; + xs << xml::StartTag(lay.htmlitemtag(), attrs); } - string attrs = lay.htmlattr() + " style='text-align: " + align + ";'"; - xs << xml::StartTag(lay.htmlitemtag(), attrs); } inline void closeItemTag(XMLStream & xs, Layout const & lay) { - xs << xml::EndTag(lay.htmlitemtag()); + if (lay.htmlitemtag() != "NONE") { + xs << xml::EndTag(lay.htmlitemtag()); + } } // end of convenience functions @@ -403,7 +414,42 @@ ParagraphList::const_iterator makeEnvironment(Buffer const & buf, depth_type const origdepth = pbegin->params().depth(); // open tag for this environment - openParTag(xs, bstyle, pbegin->magicLabel()); + if ((bstyle.labeltype == LABEL_ENUMERATE || bstyle.labeltype == LABEL_ITEMIZE) + && bstyle.htmlclass().empty()) { + // In this case, we have to calculate the CSS class ourselves, each time + // through + // FIXME We assume in these cases that the standard counters are being used. + // (We also do not deal with 'resume' counters, though I'm not sure that can + // be done at all in HTML.) + + // Code adapated from Buffer::Impl::setLabel + bool const isenum = bstyle.labeltype == LABEL_ENUMERATE; + docstring enumcounter = bstyle.counter.empty() ? + ( isenum ? from_ascii("enum") : from_ascii("lyxitem") ) : + bstyle.counter; + switch (par->itemdepth) { + case 2: + enumcounter += 'i'; + // fall through + case 1: + enumcounter += 'i'; + // fall through + case 0: + enumcounter += 'i'; + break; + case 3: + enumcounter += "iv"; + break; + default: + // not a valid enumdepth... + break; + } + openParTag(xs, bstyle, + string( isenum ? "lyxenum" : "lyxitem" ) + " " + + to_utf8(enumcounter), pbegin->magicLabel()); + } + else + openParTag(xs, bstyle, pbegin->magicLabel()); xs << xml::CR(); // we will on occasion need to remember a layout from before. @@ -422,7 +468,7 @@ ParagraphList::const_iterator makeEnvironment(Buffer const & buf, if (!style.counter.empty() && (par == pbegin || !isNormalEnv(style)) && cnts.hasCounter(cntr) - ) + ) cnts.step(cntr, OutputUpdate); ParagraphList::const_iterator send; @@ -471,10 +517,13 @@ ParagraphList::const_iterator makeEnvironment(Buffer const & buf, xs << xml::CR(); } else { - openLabelTag(xs, style); - xs << par->params().labelString(); - closeLabelTag(xs, style); - xs << xml::CR(); + docstring const & ls = par->params().labelString(); + if (!ls.empty()) { + openLabelTag(xs, style); + xs << ls; + closeLabelTag(xs, style); + xs << xml::CR(); + } } } } // end label output @@ -590,6 +639,8 @@ void xhtmlParagraphs(Text const & text, ParagraphList::const_iterator const pend = (epit == (int) paragraphs.size()) ? paragraphs.end() : paragraphs.iterator_at(epit); + std::stack headerLevels; + while (bpit < epit) { ParagraphList::const_iterator par = paragraphs.iterator_at(bpit); if (par->params().startOfAppendix()) { @@ -607,6 +658,35 @@ void xhtmlParagraphs(Text const & text, ParagraphList::const_iterator const lastpar = par; ParagraphList::const_iterator send; + // Think about adding
and/or
s. + // Document title is not in Sectioning, but rather in FrontMatter, so that it does not need to be taken + // into account. + if (style.category() == from_utf8("Sectioning")) { + int level = style.toclevel; + + // Need to close a previous section if it has the same level or a higher one (close
if opening a + //

after a

,

,

,

or
). More examples: + // - current: h2; back: h1; do not close any
+ // - current: h1; back: h2; close two
(first the

, then the

, so a new

can come) + while (!headerLevels.empty() && level <= headerLevels.top()) { + // Output the tag only if it corresponds to a legit section. + int stackLevel = headerLevels.top(); + if (stackLevel != Layout::NOT_IN_TOC) { + xs << xml::EndTag("section"); + xs << xml::CR(); + } + headerLevels.pop(); + } + + // Open the new section: first push it onto the stack, then output it in XHTML. + headerLevels.push(level); + // Some sectioning-like elements should not be output (such as FrontMatter). + if (level != Layout::NOT_IN_TOC ) { + xs << xml::StartTag("section"); + xs << xml::CR(); + } + } + switch (style.latextype) { case LATEX_COMMAND: { // The files with which we are working never have more than @@ -643,6 +723,14 @@ void xhtmlParagraphs(Text const & text, } bpit += distance(lastpar, par); } + + // If need be, close
s, but only at the end of the document (otherwise, dealt with at the beginning + // of the loop). + while (!headerLevels.empty() && headerLevels.top() != Layout::NOT_IN_TOC) { + headerLevels.pop(); + xs << xml::EndTag("section"); + xs << xml::CR(); + } }