docutils.cpp
No OneTemporary

File Metadata

Created
Sun, Aug 23, 7:38 PM

docutils.cpp

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* \file docutils.cpp
* \brief Documentation processing
*
*/
#include "docutils.h"
#include <iostream>
#include <fstream>
#include <assert.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
using namespace std;
std::string
getDocumentationExampleById(std::string filename, std::string id) {
string query = string("(//db:programlisting | //db:code | //db:screen)[@xml:id='") + id + "']";
xmlDocPtr doc = xmlParseFile(filename.c_str());
if(!doc) {
cout << "Can't find documentation file: " << filename << endl;
assert(false);
return "";
}
xmlXPathContextPtr context = xmlXPathNewContext(doc);
xmlXPathRegisterNs(context, BAD_CAST "db", BAD_CAST "http://docbook.org/ns/docbook");
xmlXPathObjectPtr response = xmlXPathEvalExpression((xmlChar*) query.c_str(), context);
xmlXPathFreeContext(context);
xmlNodeSetPtr nodeset = response->nodesetval;
if(nodeset->nodeNr != 1) {
cout << "Can't find specified example " << id << endl;
assert(false);
return "";
}
string tag = (char*) nodeset->nodeTab[0]->name;
bool flagIsPrgListing = tag == "programlisting";
xmlChar* contentC = xmlNodeListGetString(doc, nodeset->nodeTab[0]->xmlChildrenNode, 1);
string content = (char*) contentC;
xmlFree(contentC);
xmlXPathFreeObject(response);
//skip first line(used as header)
if(flagIsPrgListing) {
content = content.substr(content.find('\n') + 1);
}
//replace no break spaces
replaceAll(content, "\u00A0", " ");
assert(content.size() && "Empty example");
return content;
}
std::string
getDocumentationExampleFromFile(std::string filename) {
std::ifstream stream(filename);
std::string result;
stream.seekg(0, std::ios::end);
result.reserve(stream.tellg());
stream.seekg(0, std::ios::beg);
result.assign((std::istreambuf_iterator<char>(stream)),
std::istreambuf_iterator<char>());
assert(result.size() && "Empty example");
return result;
}
void
replace(std::string &str, const std::string &subA, const std::string &subB) {
size_t posA = str.find(subA);
assert(posA != string::npos);
str.replace(posA, subA.size(), subB);
}
void
replaceAll(std::string &str, const std::string &subA, const std::string &subB) {
size_t posA = str.find(subA);
while(posA != string::npos) {
str.replace(posA, subA.size(), subB);
posA = str.find(subA);
}
}

Event Timeline