Rewrote the output so that it emits correct YAML.

Fixed a bug in the last newline of a block folded scalar.
This commit is contained in:
beder
2008-07-05 05:28:23 +00:00
parent 5feaef3748
commit ba97c9f719
12 changed files with 98 additions and 145 deletions

View File

@@ -19,7 +19,7 @@ namespace YAML
virtual ~Content();
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
virtual void Write(std::ostream& out, int indent) = 0;
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) = 0;
virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const { return false; }
virtual bool GetBegin(std::map <Node *, Node *>::const_iterator& it) const { return false; }

View File

@@ -73,10 +73,7 @@ int main()
YAML::Node doc;
parser.GetNextDocument(doc);
Level level;
doc >> level;
std::cout << level;
std::cout << doc;
} catch(YAML::Exception&) {
std::cout << "Error parsing the yaml!\n";
}

27
map.cpp
View File

@@ -125,22 +125,27 @@ namespace YAML
}
}
void Map::Write(std::ostream& out, int indent)
void Map::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
{
for(int i=0;i<indent;i++)
out << " ";
out << "{map}\n";
if(startedLine && !onlyOneCharOnLine)
out << std::endl;
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
for(int i=0;i<indent + 1;i++)
if((startedLine && !onlyOneCharOnLine) || it != m_data.begin()) {
for(int i=0;i<indent;i++)
out << " ";
out << "{key}\n";
it->first->Write(out, indent + 2);
}
for(int i=0;i<indent + 1;i++)
out << "? ";
it->first->Write(out, indent + 1, true, it!= m_data.begin() || !startedLine || onlyOneCharOnLine);
for(int i=0;i<indent;i++)
out << " ";
out << "{value}\n";
it->second->Write(out, indent + 2);
}
out << ": ";
it->second->Write(out, indent + 1, true, true);
}
if(m_data.empty())
out << std::endl;
}
}

2
map.h
View File

@@ -17,7 +17,7 @@ namespace YAML
virtual bool GetBegin(std::map <Node *, Node *>::const_iterator& it) const;
virtual bool GetEnd(std::map <Node *, Node *>::const_iterator& it) const;
virtual void Parse(Scanner *pScanner, const ParserState& state);
virtual void Write(std::ostream& out, int indent);
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine);
private:
void ParseBlock(Scanner *pScanner, const ParserState& state);

View File

@@ -112,28 +112,30 @@ namespace YAML
pScanner->PopNextToken();
}
void Node::Write(std::ostream& out, int indent)
void Node::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const
{
if(m_tag != "") {
for(int i=0;i<indent;i++)
out << " ";
out << "{tag: " << m_tag << "}\n";
}
// write anchor/alias
if(m_anchor != "") {
for(int i=0;i<indent;i++)
out << " ";
if(m_alias)
out << "{alias: " << m_anchor << "}\n";
out << "*";
else
out << "{anchor: " << m_anchor << "}\n";
out << "&";
out << m_anchor << " ";
startedLine = true;
onlyOneCharOnLine = false;
}
// write tag
if(m_tag != "") {
out << "!<" << m_tag << "> ";
startedLine = true;
onlyOneCharOnLine = false;
}
if(!m_pContent) {
for(int i=0;i<indent;i++)
out << " ";
out << "{no content}\n";
out << std::endl;
} else {
m_pContent->Write(out, indent);
m_pContent->Write(out, indent, startedLine, onlyOneCharOnLine);
}
}
@@ -266,4 +268,10 @@ namespace YAML
node.m_pContent->Read(c);
}
std::ostream& operator << (std::ostream& out, const Node& node)
{
node.Write(out, 0, false, false);
return out;
}
}

5
node.h
View File

@@ -46,7 +46,7 @@ namespace YAML
void Clear();
void Parse(Scanner *pScanner, const ParserState& state);
void Write(std::ostream& out, int indent);
void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const;
// accessors
Iterator begin() const;
@@ -92,6 +92,9 @@ namespace YAML
friend void operator >> (const Node& node, double& d);
friend void operator >> (const Node& node, char& c);
// insertion
friend std::ostream& operator << (std::ostream& out, const Node& node);
private:
void ParseHeader(Scanner *pScanner, const ParserState& state);
void ParseTag(Scanner *pScanner, const ParserState& state);

View File

@@ -21,14 +21,19 @@ namespace YAML
delete pToken;
}
void Scalar::Write(std::ostream& out, int indent)
void Scalar::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
{
for(int i=0;i<indent;i++)
out << " ";
out << "{scalar}\n";
for(int i=0;i<indent;i++)
out << " ";
out << m_data << std::endl;
out << "\"";
for(unsigned i=0;i<m_data.size();i++) {
switch(m_data[i]) {
case '\\': out << "\\\\"; break;
case '\t': out << "\\t"; break;
case '\n': out << "\\n"; break;
case '\r': out << "\\r"; break;
default: out << m_data[i]; break;
}
}
out << "\"\n";
}
void Scalar::Read(std::string& s)

View File

@@ -12,7 +12,7 @@ namespace YAML
virtual ~Scalar();
virtual void Parse(Scanner *pScanner, const ParserState& state);
virtual void Write(std::ostream& out, int indent);
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine);
// extraction
virtual void Read(std::string& s);

View File

@@ -110,7 +110,12 @@ namespace YAML
bool nextMoreIndented = (INPUT.peek() == ' ');
// for block scalars, we always start with a newline, so we should ignore it (not fold or keep)
if(pastOpeningBreak) {
bool useNewLine = pastOpeningBreak;
// and for folded scalars, we don't fold the very last newline to a space
if(params.fold && !emptyLine && INPUT.column < params.indent)
useNewLine = false;
if(useNewLine) {
if(params.fold && !emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented)
scalar += " ";
else

View File

@@ -133,12 +133,22 @@ namespace YAML
}
}
void Sequence::Write(std::ostream& out, int indent)
void Sequence::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
{
for(int i=0;i<indent;i++)
if(startedLine && !onlyOneCharOnLine)
out << std::endl;
for(unsigned i=0;i<m_data.size();i++) {
if((startedLine && !onlyOneCharOnLine) || i > 0) {
for(int j=0;j<indent;j++)
out << " ";
out << "{sequence}\n";
for(unsigned i=0;i<m_data.size();i++)
m_data[i]->Write(out, indent + 1);
}
out << "- ";
m_data[i]->Write(out, indent + 1, true, i > 0 || !startedLine || onlyOneCharOnLine);
}
if(m_data.empty())
out << std::endl;
}
}

View File

@@ -20,7 +20,7 @@ namespace YAML
virtual unsigned GetSize() const;
virtual void Parse(Scanner *pScanner, const ParserState& state);
virtual void Write(std::ostream& out, int indent);
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine);
private:
void ParseBlock(Scanner *pScanner, const ParserState& state);

114
test.yaml
View File

@@ -1,97 +1,17 @@
---
model:
file: data/models/compound.model
textures: data/materials/compound
rooms:
- name: "Room #1"
pos: [0, 0, 0]
size: [1000, 1000, 500]
height: 500
stairtype: none
display: []
pathfinding:
tilesize: 50
size: [24, 24]
map: |
-----------------------
-+++++++++++++++++++++-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+---------------------
-+---------------------
-+---------------------
-+---------------------
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+++++++++++++++++++++-
-----------------------
- name: Doorway
pos: [1000, 400, 0]
size: [50, 200, 500]
height: 500
stairtype: none
display: []
pathfinding:
tilesize: 50
size: [5, 9]
map: |
-----
-+++-
-----
-----
-----
-----
-----
-+++-
-----
- name: "Room #2"
pos: [1050, 0, 0]
size: [1000, 1000, 500]
height: 500
stairtype: none
display: []
pathfinding:
tilesize: 50
size: [24, 24]
map: |
-----------------------
-+++++++++++++++++++++-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
---------------------+-
---------------------+-
---------------------+-
---------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+++++++++++++++++++++-
-----------------------
exits:
- room1: "Room #1"
room2: "Room #2"
dir: e
pos: [400, 600]
literal: |
Here's a literal scalar.
That's a newline.
Let's go...
folded: >
Here's a folded scalar that
wraps over to a newline.
Let's go...
regular: Here's a regular
scalar that keeps
on wrapping...
Let's go!
and last key: so it doesn't go bonkers