+ void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+ {
+ size_t longestkey = 0;
+
+ HelpMap newhelp;
+ ConfigTagList tags = ServerInstance->Config->ConfTags("helpop");
+ if (tags.first == tags.second)
+ throw ModuleException("You have loaded the helpop module but not configured any help topics!");
+
+ for (ConfigIter i = tags.first; i != tags.second; ++i)
+ {
+ ConfigTag* tag = i->second;
+
+ // Attempt to read the help key.
+ const std::string key = tag->getString("key");
+ if (key.empty())
+ throw ModuleException(InspIRCd::Format("<helpop:key> is empty at %s", tag->getTagLocation().c_str()));
+ else if (irc::equals(key, "index"))
+ throw ModuleException(InspIRCd::Format("<helpop:key> is set to \"index\" which is reserved at %s", tag->getTagLocation().c_str()));
+ else if (key.length() > longestkey)
+ longestkey = key.length();
+
+ // Attempt to read the help value.
+ std::string value;
+ if (!tag->readString("value", value, true) || value.empty())
+ throw ModuleException(InspIRCd::Format("<helpop:value> is empty at %s", tag->getTagLocation().c_str()));
+
+ // Parse the help body. Empty lines are replaced with a single
+ // space because some clients are unable to show blank lines.
+ HelpMessage helpmsg;
+ irc::sepstream linestream(value, '\n', true);
+ for (std::string line; linestream.GetToken(line); )
+ helpmsg.push_back(line.empty() ? " " : line);
+
+ // Read the help title and store the topic.
+ const std::string title = tag->getString("title", InspIRCd::Format("*** Help for %s", key.c_str()), 1);
+ if (!newhelp.insert(std::make_pair(key, HelpTopic(helpmsg, title))).second)
+ {
+ throw ModuleException(InspIRCd::Format("<helpop> tag with duplicate key '%s' at %s",
+ key.c_str(), tag->getTagLocation().c_str()));
+ }
+ }
+
+ // The number of items we can fit on a page.
+ HelpMessage indexmsg;
+ size_t maxcolumns = 80 / (longestkey + 2);
+ for (HelpMap::iterator iter = newhelp.begin(); iter != newhelp.end(); )
+ {
+ std::string indexline;
+ for (size_t column = 0; column != maxcolumns; )
+ {
+ if (iter == newhelp.end())
+ break;
+
+ indexline.append(iter->first);
+ if (++column != maxcolumns)
+ indexline.append(longestkey - iter->first.length() + 2, ' ');
+ iter++;
+ }
+ indexmsg.push_back(indexline);
+ }
+ newhelp.insert(std::make_pair("index", HelpTopic(indexmsg, "List of help topics")));
+ cmd.help.swap(newhelp);