]> git.lyx.org Git - lyx.git/blobdiff - src/sgml.cpp
Account for old versions of Pygments
[lyx.git] / src / sgml.cpp
index 4cd238d857cdf9954160a36a88e351809ec8db8c..2facb3ed539e280d459fed50a9f9fba1ba7f3b48 100644 (file)
@@ -3,7 +3,7 @@
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
- * \author José Matos
+ * \author José Matos
  * \author John Levon
  *
  * Full author contact details are available in file CREDITS.
 #include "Buffer.h"
 #include "BufferParams.h"
 #include "Counters.h"
-#include "LyXText.h"
+#include "Layout.h"
 #include "OutputParams.h"
 #include "Paragraph.h"
+#include "Text.h"
+#include "TextClass.h"
 
-#include "support/docstring.h"
-#include "support/lstrings.h"
-#include "support/std_ostream.h"
 #include "support/convert.h"
+#include "support/docstream.h"
+#include "support/lstrings.h"
 #include "support/textutils.h"
 
+#include <atomic>
 #include <map>
-#include <sstream>
+#include <QThreadStorage>
 
+using namespace std;
+using namespace lyx::support;
 
 namespace lyx {
 
-using support::subst;
-
-using std::map;
-using std::ostream;
-using std::ostringstream;
-using std::string;
 
 docstring sgml::escapeChar(char_type c)
 {
@@ -97,18 +95,19 @@ docstring sgml::escapeChar(char_type c)
 
 docstring sgml::escapeString(docstring const & raw)
 {
-       odocstringstream bin;
+       docstring bin;
+       bin.reserve(raw.size() * 2); // crude approximation is sufficient
+       for (size_t i = 0; i != raw.size(); ++i)
+               bin += sgml::escapeChar(raw[i]);
 
-       for(docstring::size_type i = 0; i < raw.size(); ++i) {
-               bin  << sgml::escapeChar(raw[i]);
-       }
-       return bin.str();
+       return bin;
 }
 
 
-docstring const sgml::uniqueID(docstring const label)
+docstring const sgml::uniqueID(docstring const label)
 {
-       static unsigned int seed = 1000;
+       // thread-safe
+       static atomic_uint seed(1000);
        return label + convert<docstring>(++seed);
 }
 
@@ -124,9 +123,9 @@ docstring sgml::cleanID(Buffer const & buf, OutputParams const & runparams,
        // and adds a number for uniqueness.
        // If you know what you are doing, you can set allowed==""
        // to disable this mangling.
-       LyXTextClass const & tclass = buf.params().getLyXTextClass();
-       string const allowed =
-               runparams.flavor == OutputParams::XML? ".-_:":tclass.options();
+       DocumentClass const & tclass = buf.params().documentClass();
+       docstring const allowed = from_ascii(
+               runparams.flavor == OutputParams::XML ? ".-_:" : tclass.options());
 
        if (allowed.empty())
                return orig;
@@ -137,12 +136,14 @@ docstring sgml::cleanID(Buffer const & buf, OutputParams const & runparams,
        docstring content;
 
        typedef map<docstring, docstring> MangledMap;
-       static MangledMap mangledNames;
-       static int mangleID = 1;
+       static QThreadStorage<MangledMap> tMangledNames;
+       static QThreadStorage<int> tMangleID;
+
+       MangledMap & mangledNames = tMangledNames.localData();
 
        MangledMap::const_iterator const known = mangledNames.find(orig);
        if (known != mangledNames.end())
-               return (*known).second;
+               return known->second;
 
        // make sure it starts with a letter
        if (!isAlphaASCII(*it) && allowed.find(*it) >= allowed.size())
@@ -150,7 +151,7 @@ docstring sgml::cleanID(Buffer const & buf, OutputParams const & runparams,
 
        bool mangle = false;
        for (; it != end; ++it) {
-               char c = *it;
+               char_type c = *it;
                if (isAlphaASCII(c) || isDigitASCII(c) || c == '-' || c == '.'
                      || allowed.find(c) < allowed.size())
                        content += c;
@@ -166,12 +167,12 @@ docstring sgml::cleanID(Buffer const & buf, OutputParams const & runparams,
                        mangle = true;
                }
        }
+
        if (mangle) {
+               int & mangleID = tMangleID.localData();
                content += "-" + convert<docstring>(mangleID++);
-       }
-       else if (isDigitASCII(content[content.size() - 1])) {
+       } else if (isDigitASCII(content[content.size() - 1]))
                content += ".";
-       }
 
        mangledNames[orig] = content;
 
@@ -181,12 +182,17 @@ docstring sgml::cleanID(Buffer const & buf, OutputParams const & runparams,
 
 void sgml::openTag(odocstream & os, string const & name, string const & attribute)
 {
-        // FIXME UNICODE
+       // FIXME UNICODE
        // This should be fixed in layout files later.
        string param = subst(attribute, "<", "\"");
        param = subst(param, ">", "\"");
 
-       if (!name.empty() && name != "!-- --") {
+       // Note: we ignore the name if it empty or if it is a comment "<!-- -->" or
+       // if the name is *dummy*.
+       // We ignore dummy because dummy is not a valid docbook element and it is
+       // the internal name given to single paragraphs in the latex output.
+       // This allow us to simplify the code a lot and is a reasonable compromise.
+       if (!name.empty() && name != "!-- --" && name != "dummy") {
                os << '<' << from_ascii(name);
                if (!param.empty())
                        os << ' ' << from_ascii(param);
@@ -197,7 +203,7 @@ void sgml::openTag(odocstream & os, string const & name, string const & attribut
 
 void sgml::closeTag(odocstream & os, string const & name)
 {
-       if (!name.empty() && name != "!-- --")
+       if (!name.empty() && name != "!-- --" && name != "dummy")
                os << "</" << from_ascii(name) << '>';
 }
 
@@ -205,15 +211,15 @@ void sgml::closeTag(odocstream & os, string const & name)
 void sgml::openTag(Buffer const & buf, odocstream & os,
        OutputParams const & runparams, Paragraph const & par)
 {
-       LyXLayout_ptr const & style = par.layout();
-       string const & name = style->latexname();
-       string param = style->latexparam();
-       Counters & counters = buf.params().getLyXTextClass().counters();
+       Layout const & style = par.layout();
+       string const & name = style.latexname();
+       string param = style.latexparam();
+       Counters & counters = buf.params().documentClass().counters();
 
        string id = par.getID(buf, runparams);
 
        string attribute;
-       if(!id.empty()) {
+       if (!id.empty()) {
                if (param.find('#') != string::npos) {
                        string::size_type pos = param.find("id=<");
                        string::size_type end = param.find(">");
@@ -224,10 +230,13 @@ void sgml::openTag(Buffer const & buf, odocstream & os,
        } else {
                if (param.find('#') != string::npos) {
                        // FIXME UNICODE
-                       if(!style->counter.empty())
-                               counters.step(style->counter);
+                       if (!style.counter.empty())
+                               // This uses InternalUpdate at the moment becuase sgml output
+                               // does not do anything with tracked counters, and it would need
+                               // to track layouts if it did want to use them.
+                               counters.step(style.counter, InternalUpdate);
                        else
-                               counters.step(from_ascii(name));
+                               counters.step(from_ascii(name), InternalUpdate);
                        int i = counters.value(from_ascii(name));
                        attribute = subst(param, "#", convert<string>(i));
                } else {
@@ -240,8 +249,8 @@ void sgml::openTag(Buffer const & buf, odocstream & os,
 
 void sgml::closeTag(odocstream & os, Paragraph const & par)
 {
-       LyXLayout_ptr const & style = par.layout();
-       closeTag(os, style->latexname());
+       Layout const & style = par.layout();
+       closeTag(os, style.latexname());
 }