Some doc fixes as preparation for PDF generation (#1044)

* Some doc fixes as preparation for PDF generation

* Some doc bug fixes and enhancements for PDF manual generation
This commit is contained in:
Matthias Köfferlein
2022-04-02 16:07:38 +02:00
committed by GitHub
parent 5929ea3bc6
commit 779c2392e7
17 changed files with 202 additions and 92 deletions
+4 -4
View File
@@ -600,22 +600,22 @@ delete shapes on layer 6 of cell TOP
</tr> </tr>
<tr> <tr>
<td>bbox</td> <td>bbox</td>
<td><class_ref href="Box"/></td> <td><class_doc href="Box"/></td>
<td>The cell's bounding box.</td> <td>The cell's bounding box.</td>
</tr> </tr>
<tr> <tr>
<td>dbbox</td> <td>dbbox</td>
<td><class_ref href="DBox"/></td> <td><class_doc href="DBox"/></td>
<td>The cell's bounding box in micrometer units.</td> <td>The cell's bounding box in micrometer units.</td>
</tr> </tr>
<tr> <tr>
<td>cell_bbox</td> <td>cell_bbox</td>
<td><class_ref href="Box"/></td> <td><class_doc href="Box"/></td>
<td>Same as "bbox" (disambiguator from shape and instance bounding boxes).</td> <td>Same as "bbox" (disambiguator from shape and instance bounding boxes).</td>
</tr> </tr>
<tr> <tr>
<td>cell_dbbox</td> <td>cell_dbbox</td>
<td><class_ref href="DBox"/></td> <td><class_doc href="DBox"/></td>
<td>Same as "dbbox" (disambiguator from shape and instance bounding boxes).</td> <td>Same as "dbbox" (disambiguator from shape and instance bounding boxes).</td>
</tr> </tr>
</table> </table>
+4 -4
View File
@@ -22,10 +22,10 @@
sequence of symbolic names separated by a dot. For example: sequence of symbolic names separated by a dot. For example:
</p> </p>
<li> <ul>
<ul><tt>edit_menu.end</tt> is the end of the "Edit" menu </ul> <li><tt>edit_menu.end</tt> is the end of the "Edit" menu </li>
<ul><tt>edit_menu.undo</tt> is the "Undo" entry in the "Edit" menu</ul> <li><tt>edit_menu.undo</tt> is the "Undo" entry in the "Edit" menu</li>
</li> </ul>
<p>To obtain <p>To obtain
a list of the paths available, have a look at the "Key Bindings" page in the "Application" a list of the paths available, have a look at the "Key Bindings" page in the "Application"
+2 -2
View File
@@ -425,7 +425,7 @@ M$2 2 1 4 6 NMOS L=0.25U W=0.9U AS=0.405P AD=0.405P PS=2.7U PD=2.7U
</p> </p>
<p> <p>
<img src="inv_with_diodes.png"/> <img src="/manual/inv_with_diodes.png"/>
</p> </p>
<p> <p>
@@ -433,7 +433,7 @@ M$2 2 1 4 6 NMOS L=0.25U W=0.9U AS=0.405P AD=0.405P PS=2.7U PD=2.7U
</p> </p>
<p> <p>
<img src="inv_schematic2.png"/> <img src="/manual/inv_schematic2.png"/>
</p> </p>
<p> <p>
+1 -1
View File
@@ -226,7 +226,7 @@ schematic.blank_circuit("CIRCUIT_NAME")</pre>
</p> </p>
<p> <p>
<img src="lvs_symm_nodes.png"/> <img src="/manual/lvs_symm_nodes.png"/>
</p> </p>
<p> <p>
+3 -3
View File
@@ -54,9 +54,9 @@
</p> </p>
<table> <table>
<tr valign="top"><td><p>Default:</p></td><td width="5%"/><td><img src="/manual/fill_default.png"/></td></tr> <tr valign="top"><td width="10%"><b>Default:</b></td><td width="5%"/><td><img src="/manual/fill_default.png"/></td></tr>
<tr valign="top"><td><p>Enhanced:</p></td><td width="5%"/><td><img src="/manual/fill_enhanced.png"/></td></tr> <tr valign="top"><td width="10%"><b>Enhanced:</b></td><td width="5%"/><td><img src="/manual/fill_enhanced.png"/></td></tr>
<tr valign="top"><td><p>Enhanced plus<br/>second order:</p></td><td width="5%"/><td><img src="/manual/fill_second_order.png"/></td></tr> <tr valign="top"><td width="10%"><b>Enhanced plus<br/>second order:</b></td><td width="5%"/><td><img src="/manual/fill_second_order.png"/></td></tr>
</table> </table>
</doc> </doc>
+3 -3
View File
@@ -1139,9 +1139,9 @@ end</pre>
<p>A Shape object represents a box if it returns true on <class_doc href="Shape#is_box?"/>. <p>A Shape object represents a box if it returns true on <class_doc href="Shape#is_box?"/>.
The only specific methods that are provided for box type shapes are the <class_doc href="Shape#box"/> The only specific methods that are provided for box type shapes are the <class_doc href="Shape#box"/>
getter and <class_doc href="Shape#box="/> setter. <class_box href="Shape#box_center"/>, getter and <class_doc href="Shape#box="/> setter. <class_doc href="Shape#box_center"/>,
<class_box href="Shape#box_center="/>, <class_box href="Shape#box_p1"/>, <class_box href="Shape#box_p1="/>, <class_doc href="Shape#box_center="/>, <class_doc href="Shape#box_p1"/>, <class_doc href="Shape#box_p1="/>,
<class_box href="Shape#box_p2"/> and <class_box href="Shape#box_p2="/> get or modify individual aspects of the <class_doc href="Shape#box_p2"/> and <class_doc href="Shape#box_p2="/> get or modify individual aspects of the
box. box.
</p> </p>
+10 -1
View File
@@ -84,10 +84,19 @@ Class<lay::HelpDialog> decl_HelpDialog (QT_EXTERNAL_BASE (QDialog) "lay", "HelpD
LAYBASIC_PUBLIC Class<lay::BrowserSource> &laybasicdecl_BrowserSource (); LAYBASIC_PUBLIC Class<lay::BrowserSource> &laybasicdecl_BrowserSource ();
static lay::HelpSource *plain_help_source ()
{
return new lay::HelpSource (false);
}
Class<lay::HelpSource> decl_HelpSource (laybasicdecl_BrowserSource (), "lay", "HelpSource", Class<lay::HelpSource> decl_HelpSource (laybasicdecl_BrowserSource (), "lay", "HelpSource",
gsi::constructor ("plain", &plain_help_source, "@brief Reserved for internal use") +
gsi::method ("scan", static_cast<void (lay::HelpSource::*) ()> (&lay::HelpSource::scan), "@brief Reserved internal use") +
#if defined(HAVE_QTBINDINGS) && defined(HAVE_QT_XML) #if defined(HAVE_QTBINDINGS) && defined(HAVE_QT_XML)
gsi::method ("get_dom", &lay::HelpSource::get_dom, "@brief For internal use") + gsi::method ("get_dom", &lay::HelpSource::get_dom, gsi::arg ("path"), "@brief Reserved for internal use") +
#endif #endif
gsi::method ("set_option", &lay::HelpSource::set_option, gsi::arg ("key"), gsi::arg ("value"), "@brief Reserved for internal use") +
gsi::method ("get_option", &lay::HelpSource::get_option, gsi::arg ("key"), "@brief Reserved for internal use") +
gsi::method ("urls", &lay::HelpSource::urls, "@brief Reserved for internal use") + gsi::method ("urls", &lay::HelpSource::urls, "@brief Reserved for internal use") +
gsi::method ("title_for", &lay::HelpSource::title_for, gsi::arg ("path"), "@brief Reserved internal use") + gsi::method ("title_for", &lay::HelpSource::title_for, gsi::arg ("path"), "@brief Reserved internal use") +
gsi::method ("parent_of", &lay::HelpSource::parent_of, gsi::arg ("path"), "@brief Reserved internal use") + gsi::method ("parent_of", &lay::HelpSource::parent_of, gsi::arg ("path"), "@brief Reserved internal use") +
+50 -35
View File
@@ -460,14 +460,19 @@ replace_references (const std::string &t, const gsi::ClassBase *cls_base)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Implementation // Implementation
GSIHelpProvider::GSIHelpProvider ()
{
// .. nothing yet ..
}
std::string std::string
GSIHelpProvider::folder () const GSIHelpProvider::folder (lay::HelpSource * /*src*/) const
{ {
return "code"; return "code";
} }
std::string std::string
GSIHelpProvider::title () const GSIHelpProvider::title (lay::HelpSource * /*src*/) const
{ {
return tl::to_string (QObject::tr ("API Reference")); return tl::to_string (QObject::tr ("API Reference"));
} }
@@ -485,7 +490,7 @@ void produce_toc (const gsi::ClassBase *cls, std::vector <std::string> &toc)
} }
void void
GSIHelpProvider::toc (std::vector<std::string> &t) GSIHelpProvider::toc (lay::HelpSource * /*src*/, std::vector<std::string> &t)
{ {
std::set<std::string> mod_names; std::set<std::string> mod_names;
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
@@ -499,7 +504,7 @@ GSIHelpProvider::toc (std::vector<std::string> &t)
} }
QDomDocument QDomDocument
GSIHelpProvider::get (const std::string &path) const GSIHelpProvider::get (lay::HelpSource *src, const std::string &path) const
{ {
QUrl url = QUrl::fromEncoded (path.c_str ()); QUrl url = QUrl::fromEncoded (path.c_str ());
QString url_path = url.path (); QString url_path = url.path ();
@@ -508,9 +513,9 @@ GSIHelpProvider::get (const std::string &path) const
std::string text; std::string text;
if (url_path == QString::fromUtf8 ("/code/index.xml")) { if (url_path == QString::fromUtf8 ("/code/index.xml")) {
text = produce_class_index (0); text = produce_class_index (src, 0);
} else if (module_index_url.indexIn (url_path) == 0) { } else if (module_index_url.indexIn (url_path) == 0) {
text = produce_class_index (from_encoded_class_name (tl::to_string (module_index_url.cap (1))).c_str ()); text = produce_class_index (src, from_encoded_class_name (tl::to_string (module_index_url.cap (1))).c_str ());
} else if (class_doc_url.indexIn (url_path) == 0) { } else if (class_doc_url.indexIn (url_path) == 0) {
text = produce_class_doc (from_encoded_class_name (tl::to_string (class_doc_url.cap (1)))); text = produce_class_doc (from_encoded_class_name (tl::to_string (class_doc_url.cap (1))));
} else { } else {
@@ -539,23 +544,6 @@ GSIHelpProvider::get (const std::string &path) const
return doc; return doc;
} }
static
void produce_doc_index (const gsi::ClassBase *cls, std::ostringstream &os)
{
DocumentationParser &doc = cls_documentation (cls);
std::string qname = make_qualified_name (cls);
// Only list the name if the class is not hidden, it's a top-level class or the path is an expanded one
// (the last criterion avoids generating classes such as A::B_C)
if (! doc.hidden) {
os << "<topic-ref href=\"" << escape_xml (class_doc_url (qname)) << "\"/>" << std::endl;
}
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = cls->begin_child_classes (); cc != cls->end_child_classes (); ++cc) {
produce_doc_index (cc.operator-> (), os);
}
}
static static
void collect_class_info (const gsi::ClassBase *cls, const std::string &module, std::vector <std::pair <std::string, std::pair<std::string, std::string> > > &class_names, std::vector <std::pair <std::string, std::pair<std::string, std::string> > > &qt_class_names) void collect_class_info (const gsi::ClassBase *cls, const std::string &module, std::vector <std::pair <std::string, std::pair<std::string, std::string> > > &class_names, std::vector <std::pair <std::string, std::pair<std::string, std::string> > > &qt_class_names)
{ {
@@ -578,8 +566,9 @@ void collect_class_info (const gsi::ClassBase *cls, const std::string &module, s
} }
std::string std::string
GSIHelpProvider::produce_class_index (const char *module_name) const GSIHelpProvider::produce_class_index (lay::HelpSource *src, const char *module_name) const
{ {
bool skip_qt_classes = src->get_option ("skip-qt-classes").to_bool ();
std::ostringstream os; std::ostringstream os;
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
@@ -605,10 +594,17 @@ GSIHelpProvider::produce_class_index (const char *module_name) const
} }
} }
if (skip_qt_classes) {
qt_class_names.clear ();
}
if (! module_name) { if (! module_name) {
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { for (class_index_t::const_iterator i = class_names.begin (); i != class_names.end (); ++i) {
produce_doc_index (c.operator-> (), os); os << "<topic-ref href=\"" << escape_xml (class_doc_url (i->first)) << "\"/>" << std::endl;
}
for (class_index_t::const_iterator i = qt_class_names.begin (); i != qt_class_names.end (); ++i) {
os << "<topic-ref href=\"" << escape_xml (class_doc_url (i->first)) << "\"/>" << std::endl;
} }
std::set<std::string> mod_names; std::set<std::string> mod_names;
@@ -643,7 +639,7 @@ GSIHelpProvider::produce_class_index (const char *module_name) const
} }
if (! qt_class_names.empty ()) { if (! qt_class_names.empty ()) {
os << tl::to_string (QObject::tr ("Find Qt class documentation")) << " <a href=\"#qtclasses\">" << tl::to_string (QObject::tr ("here")) << "</a>" << std::endl; os << "<p>" << tl::to_string (QObject::tr ("Find Qt class documentation")) << " <a href=\"#qtclasses\">" << tl::to_string (QObject::tr ("here")) << "</a></p>" << std::endl;
} }
if (! class_names.empty ()) { if (! class_names.empty ()) {
@@ -657,9 +653,9 @@ GSIHelpProvider::produce_class_index (const char *module_name) const
os << "<tr class=\"row" << (n % 2) << "\">" << std::endl; os << "<tr class=\"row" << (n % 2) << "\">" << std::endl;
os << "<td><a href=\"" << escape_xml (class_doc_url (cc->first)) << "\">" << escape_xml (cc->first) << "</a></td>"; os << "<td><a href=\"" << escape_xml (class_doc_url (cc->first)) << "\">" << escape_xml (cc->first) << "</a></td>";
if (! module_name) { if (! module_name) {
os << "<td>&nbsp;&nbsp;&nbsp;<nobr><a href=\"" << module_doc_url (cc->second.first) << "\">" << escape_xml (cc->second.first) << "</a></nobr></td>"; os << "<td><a href=\"" << module_doc_url (cc->second.first) << "\">" << escape_xml (cc->second.first) << "</a></td>";
} }
os << "<td>&nbsp;&nbsp;&nbsp;<nobr>" << escape_xml (cc->second.second) << "</nobr></td></tr>" << std::endl; os << "<td>" << escape_xml (cc->second.second) << "</td></tr>" << std::endl;
} }
os << "</table>" << std::endl; os << "</table>" << std::endl;
@@ -676,9 +672,9 @@ GSIHelpProvider::produce_class_index (const char *module_name) const
os << "<tr class=\"row" << (n % 2) << "\">" << std::endl; os << "<tr class=\"row" << (n % 2) << "\">" << std::endl;
os << "<td><a href=\"" << escape_xml (class_doc_url (cc->first)) << "\">" << escape_xml (cc->first) << "</a></td>"; os << "<td><a href=\"" << escape_xml (class_doc_url (cc->first)) << "\">" << escape_xml (cc->first) << "</a></td>";
if (! module_name) { if (! module_name) {
os << "<td>&nbsp;&nbsp;&nbsp;<nobr><a href=\"" << module_doc_url (cc->second.first) << "\">" << escape_xml (cc->second.first) << "</a></nobr></td>"; os << "<td><a href=\"" << module_doc_url (cc->second.first) << "\">" << escape_xml (cc->second.first) << "</a></td>";
} }
os << "<td>&nbsp;&nbsp;&nbsp;<nobr>" << escape_xml (cc->second.second) << "</nobr></td></tr>" << std::endl; os << "<td>" << escape_xml (cc->second.second) << "</td></tr>" << std::endl;
} }
os << "</table>" << std::endl; os << "</table>" << std::endl;
@@ -992,6 +988,7 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
<< std::endl; << std::endl;
os << "<doc><title>" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls) << "</title>" << std::endl; os << "<doc><title>" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls) << "</title>" << std::endl;
os << "<property name=\"module\" value=\"" << escape_xml (cls_obj->module ()) << "\"/>" << std::endl;
os << "<keyword name=\"" << escape_xml (cls) << "\"/>" << std::endl; os << "<keyword name=\"" << escape_xml (cls) << "\"/>" << std::endl;
@@ -1328,6 +1325,9 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "<table>"; os << "<table>";
int rowindex = -1;
int sigindex = -1;
for (std::multimap <std::string, std::pair<const gsi::MethodBase *, size_t> >::const_iterator i = mm.begin (); i != mm.end (); ++i, ++n) { for (std::multimap <std::string, std::pair<const gsi::MethodBase *, size_t> >::const_iterator i = mm.begin (); i != mm.end (); ++i, ++n) {
const gsi::MethodBase::MethodSynonym &syn = i->second.first->begin_synonyms () [i->second.second]; const gsi::MethodBase::MethodSynonym &syn = i->second.first->begin_synonyms () [i->second.second];
@@ -1335,13 +1335,23 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
DocumentationParser method_doc (i->second.first); DocumentationParser method_doc (i->second.first);
std::string pydoc = pya::PythonInterpreter::python_doc (i->second.first); std::string pydoc = pya::PythonInterpreter::python_doc (i->second.first);
os << "<tr>"; if (i->first != prev_title) {
rowindex += 1;
}
os << "<tr class=\"bigrow" << (rowindex % 2) << "\">";
if (i->first != prev_title) { if (i->first != prev_title) {
int rows = 0; int rows = 0;
for (std::multimap <std::string, std::pair<const gsi::MethodBase *, size_t> >::const_iterator j = i; j != mm.end () && j->first == i->first; ++j) { for (std::multimap <std::string, std::pair<const gsi::MethodBase *, size_t> >::const_iterator j = i; j != mm.end () && j->first == i->first; ++j) {
++rows; ++rows;
} }
os << "<td rowspan=\"" << rows << "\">"; if (rows > 1) {
os << "<td rowspan=\"" << rows << "\">";
sigindex = 0;
} else {
os << "<td>";
sigindex = -1;
}
os << "<h3>" << escape_xml (i->first) << "</h3>" << std::endl; os << "<h3>" << escape_xml (i->first) << "</h3>" << std::endl;
prev_title = i->first; prev_title = i->first;
os << "</td>"; os << "</td>";
@@ -1352,7 +1362,12 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
<< "<a name=\"m_" << escape_xml (i->first) << "\"/>" << "<a name=\"m_" << escape_xml (i->first) << "\"/>"
<< "<keyword title=\"" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls) << ", " << tl::to_string (QObject::tr ("Method")) << " " << escape_xml (i->first) << "\" name=\"" << escape_xml (cls) << "#" << escape_xml (i->first) << "\"/>" << std::endl; << "<keyword title=\"" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls) << ", " << tl::to_string (QObject::tr ("Method")) << " " << escape_xml (i->first) << "\" name=\"" << escape_xml (cls) << "#" << escape_xml (i->first) << "\"/>" << std::endl;
os << "<p><b>" << tl::to_string (QObject::tr ("Signature")) << "</b>: "; os << "<p><b>";
if (sigindex >= 0) {
++sigindex;
os << "(" << sigindex << ") ";
}
os << tl::to_string (QObject::tr ("Signature")) << "</b>: ";
std::string attr = method_attributes (i->second.first, method_doc); std::string attr = method_attributes (i->second.first, method_doc);
if (! attr.empty ()) { if (! attr.empty ()) {
os << "<i>[" << escape_xml (attr) << "] </i>"; os << "<i>[" << escape_xml (attr) << "] </i>";
@@ -1395,7 +1410,7 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
if (! pydoc.empty ()) { if (! pydoc.empty ()) {
os << "<p><b>"; os << "<p><b>";
os << tl::to_string (QObject::tr ("Python specific notes:")); os << tl::to_string (QObject::tr ("Python specific notes: "));
os << "</b><br/>" << escape_xml (pydoc) << "</p>" << std::endl; os << "</b><br/>" << escape_xml (pydoc) << "</p>" << std::endl;
} }
+7 -5
View File
@@ -38,14 +38,16 @@ class GSIHelpProvider
: public HelpProvider : public HelpProvider
{ {
public: public:
virtual std::string folder () const; GSIHelpProvider ();
virtual std::string title () const;
virtual void toc (std::vector<std::string> &t); virtual std::string folder (lay::HelpSource *src) const;
virtual QDomDocument get (const std::string &u) const; virtual std::string title (lay::HelpSource *src) const;
virtual void toc (lay::HelpSource *src, std::vector<std::string> &t);
virtual QDomDocument get (lay::HelpSource *src, const std::string &u) const;
private: private:
std::string produce_class_doc (const std::string &cls) const; std::string produce_class_doc (const std::string &cls) const;
std::string produce_class_index (const char *module_name) const; std::string produce_class_index (HelpSource *src, const char *module_name) const;
}; };
} }
+7 -5
View File
@@ -30,6 +30,8 @@
namespace lay namespace lay
{ {
class HelpSource;
/** /**
* @brief A provider for documentation in the help system * @brief A provider for documentation in the help system
* *
@@ -58,9 +60,9 @@ public:
* *
* @return The documentation path for the main entry point for this provider. * @return The documentation path for the main entry point for this provider.
*/ */
virtual std::string index () const virtual std::string index (lay::HelpSource *src) const
{ {
return "/" + folder () + "/index.xml"; return "/" + folder (src) + "/index.xml";
} }
/** /**
@@ -69,7 +71,7 @@ public:
* The DOM is the document in XML form which can be converted to HTML form for example * The DOM is the document in XML form which can be converted to HTML form for example
* or scanned for keywords. * or scanned for keywords.
*/ */
virtual QDomDocument get (const std::string & /*path*/) const virtual QDomDocument get (lay::HelpSource * /*src*/, const std::string & /*path*/) const
{ {
return QDomDocument (); return QDomDocument ();
} }
@@ -80,12 +82,12 @@ public:
* If this string is "doc" for example, all help documents will be looked up under * If this string is "doc" for example, all help documents will be looked up under
* "doc/...". * "doc/...".
*/ */
virtual std::string folder () const = 0; virtual std::string folder (lay::HelpSource * /*src*/) const = 0;
/** /**
* @brief Gets the title for this category * @brief Gets the title for this category
*/ */
virtual std::string title () const = 0; virtual std::string title (lay::HelpSource * /*src*/) const = 0;
}; };
} }
+54 -14
View File
@@ -54,6 +54,9 @@
namespace lay namespace lay
{ {
static const std::string index_url ("/index.xml");
static const std::string search_url ("/search.xml");
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Some utilities // Some utilities
@@ -285,7 +288,14 @@ HelpSource::initialize_index ()
tl::XMLFileSource in (*c); tl::XMLFileSource in (*c);
help_index_structure.parse (in, *this); help_index_structure.parse (in, *this);
if (m_klayout_version == lay::ApplicationBase::version ()) { if (m_klayout_version == lay::ApplicationBase::version ()) {
if (tl::verbosity () >= 10) {
tl::info << tl::to_string (tr ("Help index initialized from ")) << *c;
}
ok = true; ok = true;
} else {
if (tl::verbosity () >= 10) {
tl::warn << tl::to_string (tr ("Help index ignored (wrong version) from ")) << *c;
}
} }
} catch (tl::Exception &ex) { } catch (tl::Exception &ex) {
tl::warn << ex.msg (); tl::warn << ex.msg ();
@@ -322,13 +332,8 @@ HelpSource::~HelpSource()
void void
HelpSource::produce_index_file (const std::string &path) HelpSource::produce_index_file (const std::string &path)
{ {
m_index.clear (); scan ();
m_titles.clear ();
m_title_map.clear ();
m_parent_of.clear ();
tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Initializing help index")), 1, false /*can't cancel*/);
scan ("/index.xml", progress);
try { try {
tl::OutputStream os (path, tl::OutputStream::OM_Plain); tl::OutputStream os (path, tl::OutputStream::OM_Plain);
@@ -350,6 +355,18 @@ HelpSource::create_index_file (const std::string &path)
source.produce_index_file (path); source.produce_index_file (path);
} }
void
HelpSource::scan ()
{
m_index.clear ();
m_titles.clear ();
m_title_map.clear ();
m_parent_of.clear ();
tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Initializing help index")), 1);
scan (index_url, progress);
}
std::string std::string
HelpSource::klayout_version () const HelpSource::klayout_version () const
{ {
@@ -461,21 +478,21 @@ HelpSource::get_dom (const std::string &u)
QString path = url.path (); QString path = url.path ();
for (tl::Registrar<lay::HelpProvider>::iterator cls = tl::Registrar<lay::HelpProvider>::begin (); cls != tl::Registrar<lay::HelpProvider>::end (); ++cls) { for (tl::Registrar<lay::HelpProvider>::iterator cls = tl::Registrar<lay::HelpProvider>::begin (); cls != tl::Registrar<lay::HelpProvider>::end (); ++cls) {
if (path.startsWith (tl::to_qstring ("/" + cls->folder () + "/"))) { if (path.startsWith (tl::to_qstring ("/" + cls->folder (this) + "/"))) {
if (tl::verbosity () >= 20) { if (tl::verbosity () >= 20) {
tl::info << "Help provider: create content for " << u; tl::info << "Help provider: create content for " << u;
} }
return cls->get (u); return cls->get (this, u);
} }
} }
if (path == QString::fromUtf8 ("/search.xml")) { if (path == tl::to_qstring (search_url)) {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
return produce_search (tl::to_string (QUrlQuery (url.query ()).queryItemValue (QString::fromUtf8 ("string")).toLower ())); return produce_search (tl::to_string (QUrlQuery (url.query ()).queryItemValue (QString::fromUtf8 ("string")).toLower ()));
#else #else
return produce_search (tl::to_string (url.queryItemValue (QString::fromUtf8 ("string")).toLower ())); return produce_search (tl::to_string (url.queryItemValue (QString::fromUtf8 ("string")).toLower ()));
#endif #endif
} else if (path == QString::fromUtf8 ("/index.xml")) { } else if (path == tl::to_qstring (index_url)) {
if (tl::verbosity () >= 20) { if (tl::verbosity () >= 20) {
tl::info << "Help provider: create content for " << u; tl::info << "Help provider: create content for " << u;
} }
@@ -581,9 +598,14 @@ std::string
HelpSource::next_topic (const std::string &url) HelpSource::next_topic (const std::string &url)
{ {
std::string u = tl::to_string (QUrl::fromEncoded (url.c_str ()).path ()); std::string u = tl::to_string (QUrl::fromEncoded (url.c_str ()).path ());
for (size_t t = 0; t + 1 < m_titles.size (); ++t) { for (size_t t = m_titles.size (); t > 0; ) {
--t;
if (m_titles [t].first == u) { if (m_titles [t].first == u) {
return "int:" + m_titles [t + 1].first; if (t + 1 >= m_titles.size ()) {
return std::string ();
} else {
return "int:" + m_titles [t + 1].first;
}
} }
} }
return std::string (); return std::string ();
@@ -618,7 +640,7 @@ HelpSource::produce_main_index ()
os << "<topics>" << std::endl; os << "<topics>" << std::endl;
for (tl::Registrar<lay::HelpProvider>::iterator cls = tl::Registrar<lay::HelpProvider>::begin (); cls != tl::Registrar<lay::HelpProvider>::end (); ++cls) { for (tl::Registrar<lay::HelpProvider>::iterator cls = tl::Registrar<lay::HelpProvider>::begin (); cls != tl::Registrar<lay::HelpProvider>::end (); ++cls) {
os << "<topic href=\"" << cls->index () << "\"/>" << std::endl; os << "<topic href=\"" << cls->index (this) << "\"/>" << std::endl;
} }
os << "</topics>" << std::endl; os << "</topics>" << std::endl;
@@ -1056,12 +1078,30 @@ std::vector<std::string>
HelpSource::urls () HelpSource::urls ()
{ {
std::vector<std::string> u; std::vector<std::string> u;
u.push_back ("/index.xml"); u.push_back (index_url);
for (std::map<std::string, std::string>::const_iterator p = m_parent_of.begin (); p != m_parent_of.end (); ++p) { for (std::map<std::string, std::string>::const_iterator p = m_parent_of.begin (); p != m_parent_of.end (); ++p) {
u.push_back (p->first); u.push_back (p->first);
} }
return u; return u;
} }
void
HelpSource::set_option (const std::string &key, const tl::Variant &value)
{
s_global_options[key] = value;
}
const tl::Variant &
HelpSource::get_option (const std::string &key) const
{
auto i = s_global_options.find (key);
if (i != s_global_options.end ()) {
return i->second;
} else {
static tl::Variant nil;
return nil;
}
}
} }
+19 -1
View File
@@ -75,6 +75,8 @@ class HelpSource
{ {
public: public:
HelpSource (); HelpSource ();
HelpSource (bool make_index);
~HelpSource(); ~HelpSource();
virtual std::string get (const std::string &url); virtual std::string get (const std::string &url);
@@ -152,6 +154,22 @@ public:
*/ */
static void create_index_file (const std::string &path); static void create_index_file (const std::string &path);
/**
* @brief Scans the help providers and produce the index
*/
void scan ();
/**
* @brief Sets a global options for tailoring the help output
*/
void set_option (const std::string &key, const tl::Variant &value);
/**
* @brief Sets a global options for tailoring the help output
* A null variant is returned if the option is not present.
*/
const tl::Variant &get_option (const std::string &key) const;
private: private:
std::vector<IndexEntry> m_index; std::vector<IndexEntry> m_index;
std::map<std::string, std::string> m_parent_of; std::map<std::string, std::string> m_parent_of;
@@ -159,8 +177,8 @@ private:
std::map<std::string, std::string> m_title_map; std::map<std::string, std::string> m_title_map;
std::string m_klayout_version; std::string m_klayout_version;
int m_kindex; int m_kindex;
std::map<std::string, tl::Variant> s_global_options;
HelpSource (bool make_index);
QDomDocument produce_search (const std::string &index); QDomDocument produce_search (const std::string &index);
QDomDocument produce_main_index (); QDomDocument produce_main_index ();
void produce_index_file (const std::string &path); void produce_index_file (const std::string &path);
+1 -1
View File
@@ -49,7 +49,7 @@ ResourceHelpProvider::ResourceHelpProvider (const char *folder, const std::strin
} }
QDomDocument QDomDocument
ResourceHelpProvider::get (const std::string &path) const ResourceHelpProvider::get (lay::HelpSource * /*src*/, const std::string &path) const
{ {
QString qpath = tl::to_qstring (path); QString qpath = tl::to_qstring (path);
QResource res (resource_url (qpath)); QResource res (resource_url (qpath));
+3 -3
View File
@@ -40,17 +40,17 @@ class ResourceHelpProvider
public: public:
ResourceHelpProvider (const char *folder, const std::string &title); ResourceHelpProvider (const char *folder, const std::string &title);
std::string folder () const std::string folder (lay::HelpSource * /*src*/) const
{ {
return m_folder; return m_folder;
} }
std::string title () const std::string title (lay::HelpSource * /*src*/) const
{ {
return m_title; return m_title;
} }
virtual QDomDocument get (const std::string &path) const; virtual QDomDocument get (lay::HelpSource *src, const std::string &path) const;
private: private:
std::string m_folder, m_title; std::string m_folder, m_title;
+26 -2
View File
@@ -379,6 +379,11 @@ static BrowserSource_Stub *new_html (const std::string &html)
} }
Class<lay::BrowserSource> decl_BrowserSource ("lay", "BrowserSource_Native", Class<lay::BrowserSource> decl_BrowserSource ("lay", "BrowserSource_Native",
#if defined(HAVE_QTBINDINGS)
gsi::method ("get_image", &lay::BrowserSource::get_image, gsi::arg ("url")) +
#endif
gsi::method ("next_topic", &lay::BrowserSource::next_topic, gsi::arg ("url")) +
gsi::method ("prev_topic", &lay::BrowserSource::prev_topic, gsi::arg ("url")) +
gsi::method ("get", &lay::BrowserSource::get), gsi::method ("get", &lay::BrowserSource::get),
"@hide\n@alias BrowserSource" "@hide\n@alias BrowserSource"
); );
@@ -391,12 +396,31 @@ Class<lay::BrowserSource> &laybasicdecl_BrowserSource ()
Class<BrowserSource_Stub> decl_BrowserSourceStub ("lay", "BrowserSource", Class<BrowserSource_Stub> decl_BrowserSourceStub ("lay", "BrowserSource",
gsi::constructor ("new|#new_html", &new_html, gsi::constructor ("new|#new_html", &new_html,
"@brief construct a BrowserSource object with a default HTML string\n" "@brief Constructs a BrowserSource object with a default HTML string\n"
"\n" "\n"
"The default HTML string is sent when no specific implementation is provided.\n" "The default HTML string is sent when no specific implementation is provided.\n"
) + ) +
#if defined(HAVE_QTBINDINGS)
gsi::method ("get_image", &lay::BrowserSource::get_image, gsi::arg ("url"),
"@brief Gets the image object for a specific URL\n"
"\n"
"This method has been introduced in version 0.28."
) +
#endif
gsi::method ("next_topic", &lay::BrowserSource::next_topic, gsi::arg ("url"),
"@brief Gets the next topic URL from a given URL\n"
"An empty string will be returned if no next topic is available.\n"
"\n"
"This method has been introduced in version 0.28."
) +
gsi::method ("prev_topic", &lay::BrowserSource::prev_topic, gsi::arg ("url"),
"@brief Gets the previous topic URL from a given URL\n"
"An empty string will be returned if no previous topic is available.\n"
"\n"
"This method has been introduced in version 0.28."
) +
gsi::callback ("get", &BrowserSource_Stub::get, &BrowserSource_Stub::get_cb, gsi::arg ("url"), gsi::callback ("get", &BrowserSource_Stub::get, &BrowserSource_Stub::get_cb, gsi::arg ("url"),
"@brief Get the HTML code for a given \"int\" URL.\n" "@brief Gets the HTML code for a given \"int\" URL.\n"
"\n" "\n"
"If this method returns an empty string, the browser will not be set to \n" "If this method returns an empty string, the browser will not be set to \n"
"a new location. This allows implementing any functionality behind such links.\n" "a new location. This allows implementing any functionality behind such links.\n"
@@ -262,13 +262,13 @@ gsi::Class<db::LEFDEFReaderOptions> decl_lefdef_config ("db", "LEFDEFReaderConfi
"\n" "\n"
"For example: the via layer is 'V1', \\via_geometry_suffix is 'GEO' and \\via_geometry_datatype is 1. Then:\n" "For example: the via layer is 'V1', \\via_geometry_suffix is 'GEO' and \\via_geometry_datatype is 1. Then:\n"
"\n" "\n"
"@li\n" "@ul\n"
"@ul If there is a mapping for 'V1.GEO', the layer and datatype will be taken from there. @/ul\n" "@li If there is a mapping for 'V1.GEO', the layer and datatype will be taken from there. @/li\n"
"@ul If there is a mapping for 'V1', the layer will be taken from there and the datatype will be taken from \\via_geometry_datatype. " "@li If there is a mapping for 'V1', the layer will be taken from there and the datatype will be taken from \\via_geometry_datatype. "
" The name of the produced layer will be 'V1.GEO'. @/ul\n" " The name of the produced layer will be 'V1.GEO'. @/li\n"
"@ul If there is no mapping for both, the layer number will be a unique value, the datatype will be taken from \\via_geometry_datatype " "@li If there is no mapping for both, the layer number will be a unique value, the datatype will be taken from \\via_geometry_datatype "
" and the layer name will be 'V1.GEO'. @/ul" " and the layer name will be 'V1.GEO'. @/li"
"@/li\n" "@/ul\n"
) + ) +
gsi::method ("produce_via_geometry=", &db::LEFDEFReaderOptions::set_produce_via_geometry, gsi::arg ("produce"), gsi::method ("produce_via_geometry=", &db::LEFDEFReaderOptions::set_produce_via_geometry, gsi::arg ("produce"),
"@brief Sets a value indicating whether via geometries shall be produced.\n" "@brief Sets a value indicating whether via geometries shall be produced.\n"
+1 -1
View File
@@ -1558,7 +1558,7 @@ public:
if (as_static) { if (as_static) {
if (tl::verbosity () >= 20) { if (tl::verbosity () >= 20) {
tl::log << tl::to_string (tr ("Registering class as Ruby module:) ")) << cls->name (); tl::log << tl::to_string (tr ("Registering class as Ruby module: ")) << cls->name ();
} }
std::string mixin_name = cls->name () + "_Mixin"; std::string mixin_name = cls->name () + "_Mixin";