📄 sorter.cpp
字号:
#include <cstdlib>
#include <iostream>
#include "tinyxml.h"
#include <vector>
#include <algorithm>
using namespace std;
struct xmlname{
TiXmlElement * node;
const char * name;
xmlname(TiXmlElement * n, const char * na) { node = n; name = na;}
};
//true if x1 smaller
bool sortXMLCase(const xmlname & x1, const xmlname & x2) {
return (strcmp(x1.name, x2.name) < 0);
}
inline bool lower(char c) {
return (c >= 'a' && c <= 'z');
}
inline bool match(char c1, char c2) {
if (c1 == c2) return true;
if (lower(c1))
return ((c1-32) == c2);
if (lower(c2))
return ((c2-32) == c1);
return false;
}
//true if x1 smaller
bool sortXML(const xmlname & x1, const xmlname & x2) {
const char * n1 = x1.name, * n2 = x2.name;
int i = 0;
while(match(n2[i], n1[i])) {
if (n1[i] == 0) {
return true; //equal
}
i++;
}
int subs1 = lower(n1[i])?32:0;
int subs2 = lower(n2[i])?32:0;
return ( (n1[i]-subs1) < (n2[i]-subs2) );
}
void merge(TiXmlElement * n1, TiXmlElement * n2);
int main(int argc, char *argv[])
{
const char * file = NULL;
if (argc < 2) {
cout << "Usage: sorter.exe xmlfile.xml" << endl;
return 1;
}
file = argv[1];
TiXmlDocument *pXmlApi = NULL;
pXmlApi = new TiXmlDocument(file);
bool loadOkay = pXmlApi->LoadFile();
if (!loadOkay) return 1;
TiXmlNode *root = pXmlApi->FirstChild("NotepadPlus");
if (!root) {
cout << "NotepadPlus node not found\n";
return 1;
}
TiXmlElement *autoc = root->FirstChildElement("AutoComplete");
if (!autoc) {
cout << "AutoComplete node not found\n";
return 1;
}
const char * langName = autoc->Attribute("language");
TiXmlElement *envNode = autoc->FirstChildElement("Environment");
bool ignoreCase = false;
if (envNode) {
cout << "Found environment settings\n";
const char * ignoreCaseText = envNode->Attribute("ignoreCase");
if (ignoreCaseText) {
ignoreCase = (strcmp(ignoreCaseText, "yes") == 0);
if (ignoreCase) {
cout << "Sorting case insensitive\n";
} else {
cout << "Sorting case sensitive\n";
}
} else {
cout <<"Cannot find attribute \"ignoreCase\", defaulting to case sensitive sort\nConsider adding the node\n";
}
} else {
cout << "No environment settings found, defaulting to case sensitive sort\nConsider adding the node\n";
}
vector<xmlname> words;
for (TiXmlElement *childNode = autoc->FirstChildElement("KeyWord");
childNode ;
childNode = childNode->NextSiblingElement("KeyWord") )
{
const char * name = childNode->Attribute("name");
if (!name) {
cout << "Warning: KeyWord without name!, skipping...\n";
continue;
} else {
int i = 0;
while(name[i] != 0) {
if (!isalnum(name[i]) && name[i] != '_') {
cout << "Warning, keyword " << name << " contains unsupported characters!\n";
break;
}
i++;
}
words.push_back(xmlname(childNode, name));
}
}
if (ignoreCase)
sort(words.begin(), words.end(), sortXML);
else
sort(words.begin(), words.end(), sortXMLCase);
for(size_t i = 1; i < words.size(); i++) {
//merge duplicates
if (!strcmp(words[i].name, words[i-1].name)) {
merge(words[i-1].node, words[i].node);
words.erase(words.begin() + i);
}
}
TiXmlDocument doc;
TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "Windows-1252", "" );
doc.LinkEndChild( decl );
TiXmlElement * element = new TiXmlElement( "NotepadPlus" );
doc.LinkEndChild( element );
TiXmlElement * element2 = new TiXmlElement( "AutoComplete" );
element->LinkEndChild( element2 );
if (langName)
element2->SetAttribute("language", langName);
if (envNode)
element2->LinkEndChild(envNode);
for(size_t i = 0; i < words.size(); i++) {
element2->LinkEndChild(words[i].node);
}
doc.SaveFile( file );
return 0;
}
void merge(TiXmlElement * n1, TiXmlElement * n2) {
const char * funcAttr = NULL;
funcAttr = n2->Attribute("func");
if (!funcAttr || !strcmp(funcAttr, "yes")) {
return;
}
n1->SetAttribute("func", "yes");
for (TiXmlElement *childNode = n2->FirstChildElement("Overload");
childNode ;
childNode = childNode->NextSiblingElement("Overload") )
{
n1->LinkEndChild(childNode);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -