Enhancement for a pretty format that combines BLOCK and FLOW
diff --git a/AUTHORS b/AUTHORS
index 318769e..456a19e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -22,3 +22,4 @@
 Christophe Desguez
 Magne at edb
 infinity0x
+obastard
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cf2d1a6..ac3a0f5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -7,7 +7,10 @@
 	</properties>

 	<body>

 		<release version="1.7" date="in Mercurial" description="development">

-	        <action dev="py4fun" type="fix" issue="50" due-to="sualeh.fatehi">

+	        <action dev="obastard" type="fix" issue="53" due-to="obastard">

+                Enhancement for a pretty format that combines BLOCK and FLOW (2010-03-03)

+            </action>

+            <action dev="py4fun" type="fix" issue="50" due-to="sualeh.fatehi">

                 Unable to dump JavaBean that inherits from a protected base class (2010-03-02)

             </action>

             <action dev="py4fun" type="update">

diff --git a/src/main/java/org/yaml/snakeyaml/DumperOptions.java b/src/main/java/org/yaml/snakeyaml/DumperOptions.java
index ee05ad1..1cee9c4 100644
--- a/src/main/java/org/yaml/snakeyaml/DumperOptions.java
+++ b/src/main/java/org/yaml/snakeyaml/DumperOptions.java
@@ -166,6 +166,7 @@
     private Tag explicitRoot = null;
     private Version version = null;
     private Map<String, String> tags = null;
+    private Boolean prettyFlow = false;
 
     public boolean isAllowUnicode() {
         return allowUnicode;
@@ -239,6 +240,21 @@
     }
 
     /**
+     * Force the emitter to produce a pretty YAML document when using the flow style.
+     *
+     * @param  prettyFlow  true produce pretty flow YAML document
+     */
+    public void setPrettyFlow(boolean prettyFlow)
+    {
+        this.prettyFlow = prettyFlow;
+    }
+
+    public boolean isPrettyFlow()
+    {
+        return this.prettyFlow;
+    }
+
+    /**
      * Specify the preferred width to emit scalars. When the scalar
      * representation takes more then the preferred with the scalar will be
      * split into a few lines. The default is 80.
diff --git a/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java b/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
index a62e05e..d2b9b0a 100644
--- a/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
+++ b/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
@@ -128,6 +128,9 @@
 
     // Formatting details.
     private Boolean canonical;
+    // pretty print flow by adding extra line breaks
+    private Boolean prettyFlow; 
+
     private boolean allowUnicode;
     private int bestIndent;
     private int bestWidth;
@@ -178,7 +181,8 @@
         openEnded = false;
 
         // Formatting details.
-        this.canonical = opts.isCanonical();
+        this.canonical    = opts.isCanonical();
+        this.prettyFlow   = opts.isPrettyFlow();
         this.allowUnicode = opts.isAllowUnicode();
         this.bestIndent = 2;
         if ((opts.getIndent() > MIN_INDENT) && (opts.getIndent() < MAX_INDENT)) {
@@ -423,7 +427,13 @@
         writeIndicator("[", true, true, false);
         flowLevel++;
         increaseIndent(true, false);
-        state = new ExpectFirstFlowSequenceItem();
+        
+        if (prettyFlow)
+        {
+            writeIndent();
+        }
+
+       state = new ExpectFirstFlowSequenceItem();
     }
 
     private class ExpectFirstFlowSequenceItem implements EmitterState {
@@ -432,9 +442,13 @@
                 indent = indents.pop();
                 flowLevel--;
                 writeIndicator("]", false, false, false);
+                if (prettyFlow)
+                {
+                    writeIndent();
+                }
                 state = states.pop();
             } else {
-                if (canonical || column > bestWidth) {
+                if (canonical || column > bestWidth || prettyFlow) {
                     writeIndent();
                 }
                 states.push(new ExpectFlowSequenceItem());
@@ -453,10 +467,14 @@
                     writeIndent();
                 }
                 writeIndicator("]", false, false, false);
+                if (prettyFlow)
+                {
+                    writeIndent();
+                }
                 state = states.pop();
             } else {
                 writeIndicator(",", false, false, false);
-                if (canonical || column > bestWidth) {
+                if (canonical || column > bestWidth || prettyFlow) {
                     writeIndent();
                 }
                 states.push(new ExpectFlowSequenceItem());
@@ -471,6 +489,12 @@
         writeIndicator("{", true, true, false);
         flowLevel++;
         increaseIndent(true, false);
+
+        if (prettyFlow)
+        {
+            writeIndent();
+        }
+
         state = new ExpectFirstFlowMappingKey();
     }
 
@@ -479,10 +503,14 @@
             if (event instanceof MappingEndEvent) {
                 indent = indents.pop();
                 flowLevel--;
+                if (prettyFlow)
+                {
+                    writeIndent();
+                }
                 writeIndicator("}", false, false, false);
                 state = states.pop();
             } else {
-                if (canonical || column > bestWidth) {
+                if (canonical || column > bestWidth || prettyFlow) {
                     writeIndent();
                 }
                 if (!canonical && checkSimpleKey()) {
@@ -506,11 +534,15 @@
                     writeIndicator(",", false, false, false);
                     writeIndent();
                 }
+                if (prettyFlow)
+                {
+                    writeIndent();
+                }
                 writeIndicator("}", false, false, false);
                 state = states.pop();
             } else {
                 writeIndicator(",", false, false, false);
-                if (canonical || column > bestWidth) {
+                if (canonical || column > bestWidth || prettyFlow) {
                     writeIndent();
                 }
                 if (!canonical && checkSimpleKey()) {
@@ -535,7 +567,7 @@
 
     private class ExpectFlowMappingValue implements EmitterState {
         public void expect() throws IOException {
-            if (canonical || column > bestWidth) {
+            if (canonical || column > bestWidth || prettyFlow) {
                 writeIndent();
             }
             writeIndicator(":", true, false, false);
diff --git a/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java b/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java
index f485ffa..769bcad 100644
--- a/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java
+++ b/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java
@@ -72,6 +72,12 @@
         assertEquals("[1, 2, 3]\n", yaml.dump(list));
         //
         options = new DumperOptions();
+        options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
+        options.setPrettyFlow(true);
+        yaml = new Yaml(options);
+        assertEquals("[\n  1,\n  2,\n  3]\n", yaml.dump(list));
+        //
+        options = new DumperOptions();
         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
         yaml = new Yaml(options);
         assertEquals("- 1\n- 2\n- 3\n", yaml.dump(list));
@@ -93,7 +99,8 @@
         Map<String, Object> map = new LinkedHashMap<String, Object>();
         map.put("a", "b");
         map.put("c", list);
-        assertEquals("a: b\nc: [1, 2, 3]\n", yaml.dump(map));
+        String result=yaml.dump(map);
+        assertEquals("a: b\nc: [1, 2, 3]\n", result);
         //
         DumperOptions options = new DumperOptions();
         options = new DumperOptions();
@@ -102,6 +109,13 @@
         assertEquals("{a: b, c: [1, 2, 3]}\n", yaml.dump(map));
         //
         options = new DumperOptions();
+        options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
+        options.setPrettyFlow(true);
+        yaml = new Yaml(options);
+        result=yaml.dump(map);
+        assertEquals("{\n  a: b,\n  c: [\n    1,\n    2,\n    3]\n  \n}\n", result);
+        //
+       options = new DumperOptions();
         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
         yaml = new Yaml(options);
         assertEquals("a: b\nc:\n- 1\n- 2\n- 3\n", yaml.dump(map));
diff --git a/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java b/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
index 802095b..b60dfd1 100644
--- a/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
+++ b/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
@@ -65,6 +65,24 @@
         assertEquals(etalon, output);

     }

 

+    public void testWritePlainPretty()

+    {

+        DumperOptions options = new DumperOptions();

+        options.setDefaultScalarStyle(ScalarStyle.PLAIN);

+        options.setPrettyFlow(true);

+

+        String              folded = "0123456789 0123456789\n0123456789 0123456789";

+        Map<String, String> map    = new LinkedHashMap<String, String>();

+        map.put("aaa", folded);

+        map.put("bbb", "\nbla-bla");

+

+        Yaml   yaml   = new Yaml(options);

+        String output = yaml.dump(map);

+        String etalon =

+            "{\n  aaa: '0123456789 0123456789\n\n    0123456789 0123456789',\n  bbb: '\n\n    bla-bla'\n}\n";

+        assertEquals(etalon, output);

+    }

+

     public void testWriteSingleQuoted() {

         DumperOptions options = new DumperOptions();

         options.setDefaultScalarStyle(ScalarStyle.SINGLE_QUOTED);

diff --git a/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java b/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java
index fb3280f..0947803 100644
--- a/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java
+++ b/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java
@@ -19,6 +19,7 @@
 

 import junit.framework.TestCase;

 

+import org.yaml.snakeyaml.DumperOptions;

 import org.yaml.snakeyaml.Yaml;

 

 public class StringArrayTest extends TestCase {

@@ -32,6 +33,19 @@
         A b = (A) yaml.load(output);

         assertTrue(Arrays.equals(a.getNames(), b.getNames()));

     }

+    

+    public void testStringsPretty() {

+        A a = new A();

+        a.setNames(new String[] { "aaa", "bbb", "ccc" });

+        DumperOptions options = new DumperOptions();

+        options.setPrettyFlow(true);

+        Yaml yaml = new Yaml(options);

+        String output = yaml.dump(a);

+        assertEquals("!!org.yaml.snakeyaml.javabeans.StringArrayTest$A\nnames: [\n  aaa,\n  bbb,\n  ccc]\n",

+                output);

+        A b = (A) yaml.load(output);

+        assertTrue(Arrays.equals(a.getNames(), b.getNames()));

+    }

 

     public static class A {

         String[] names;

diff --git a/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java b/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java
index 886bc7e..9bca959 100644
--- a/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java
+++ b/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java
@@ -28,12 +28,14 @@
 

 import junit.framework.TestCase;

 

+import org.yaml.snakeyaml.DumperOptions;

 import org.yaml.snakeyaml.JavaBeanDumper;

 import org.yaml.snakeyaml.JavaBeanLoader;

 import org.yaml.snakeyaml.Loader;

 import org.yaml.snakeyaml.TypeDescription;

 import org.yaml.snakeyaml.Util;

 import org.yaml.snakeyaml.Yaml;

+import org.yaml.snakeyaml.DumperOptions.FlowStyle;

 import org.yaml.snakeyaml.constructor.Constructor;

 

 public class HumanTest extends TestCase {

@@ -64,6 +66,35 @@
         assertSame(father2, father2.getBankAccountOwner());

     }

 

+    public void testNoChildrenPretty() throws IOException {

+        Human father = new Human();

+        father.setName("Father");

+        father.setBirthday(new Date(1000000000));

+        father.setBirthPlace("Leningrad");

+        father.setBankAccountOwner(father);

+        Human mother = new Human();

+        mother.setName("Mother");

+        mother.setBirthday(new Date(100000000000L));

+        mother.setBirthPlace("Saint-Petersburg");

+        father.setPartner(mother);

+        mother.setPartner(father);

+        mother.setBankAccountOwner(father);

+        DumperOptions options= new DumperOptions();

+        options.setPrettyFlow(true);

+        options.setDefaultFlowStyle(FlowStyle.FLOW);

+        Yaml yaml = new Yaml(options);

+        String output = yaml.dump(father);

+        String etalon = Util.getLocalResource("recursive/no-children-1-pretty.yaml");

+        assertEquals(etalon, output);

+        //

+        Human father2 = (Human) yaml.load(output);

+        assertNotNull(father2);

+        assertEquals("Father", father2.getName());

+        assertEquals("Mother", father2.getPartner().getName());

+        assertEquals("Father", father2.getBankAccountOwner().getName());

+        assertSame(father2, father2.getBankAccountOwner());

+    }

+

     public void testChildren() throws IOException {

         Human father = new Human();

         father.setName("Father");

@@ -133,6 +164,79 @@
         // check if hashCode is correct

         validateSet(children2);

     }

+    

+    public void testChildrenPretty() throws IOException {

+        Human father = new Human();

+        father.setName("Father");

+        father.setBirthday(new Date(1000000000));

+        father.setBirthPlace("Leningrad");

+        father.setBankAccountOwner(father);

+        //

+        Human mother = new Human();

+        mother.setName("Mother");

+        mother.setBirthday(new Date(100000000000L));

+        mother.setBirthPlace("Saint-Petersburg");

+        father.setPartner(mother);

+        mother.setPartner(father);

+        mother.setBankAccountOwner(father);

+        //

+        Human son = new Human();

+        son.setName("Son");

+        son.setBirthday(new Date(310000000000L));

+        son.setBirthPlace("Munich");

+        son.setBankAccountOwner(father);

+        son.setFather(father);

+        son.setMother(mother);

+        //

+        Human daughter = new Human();

+        daughter.setName("Daughter");

+        daughter.setBirthday(new Date(420000000000L));

+        daughter.setBirthPlace("New York");

+        daughter.setBankAccountOwner(father);

+        daughter.setFather(father);

+        daughter.setMother(mother);

+        //

+        Set<Human> children = new LinkedHashSet<Human>(2);

+        children.add(son);

+        children.add(daughter);

+        father.setChildren(children);

+        mother.setChildren(children);

+        //

+        DumperOptions options=new DumperOptions();

+        options.setDefaultFlowStyle(FlowStyle.FLOW);

+        options.setPrettyFlow(true);

+        Yaml beanDumper = new Yaml(options);

+        String output = beanDumper.dump(son);

+        // System.out.println(output);

+        String etalon = Util.getLocalResource("recursive/with-children-pretty.yaml");

+        assertEquals(etalon, output);

+        TypeDescription humanDescription = new TypeDescription(Human.class);

+        humanDescription.putMapPropertyType("children", Human.class, Object.class);

+        JavaBeanLoader<Human> beanLoader = new JavaBeanLoader<Human>(humanDescription);

+        //

+        Human son2 = beanLoader.load(output);

+        assertNotNull(son2);

+        assertEquals("Son", son.getName());

+

+        Human father2 = son2.getFather();

+        assertEquals("Father", father2.getName());

+        assertEquals("Mother", son2.getMother().getName());

+        assertSame(father2, father2.getBankAccountOwner());

+        assertSame(father2.getPartner(), son2.getMother());

+        assertSame(father2, son2.getMother().getPartner());

+

+        Set<Human> children2 = father2.getChildren();

+        assertEquals(2, children2.size());

+        assertSame(father2.getPartner().getChildren(), children2);

+

+        for (Object child : children2) {

+            // check if type descriptor was correct

+            assertSame(Human.class, child.getClass());

+        }

+

+        // check if hashCode is correct

+        validateSet(children2);

+    }

 

     public void testChildren2() throws IOException {

         Human2 father = new Human2();

diff --git a/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java b/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java
index c6360f4..6935435 100644
--- a/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java
+++ b/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java
@@ -114,4 +114,21 @@
         assertEquals("{'age': !!int '5', 'name': 'Ubuntu', 'list': [!!int '1', !!int '1']}\n",

                 output);

     }

+    public void testStyle2Pretty() {

+        List<Integer> list = new ArrayList<Integer>();

+        list.add(new Integer(1));

+        list.add(new Integer(1));

+        Map<String, Object> map = new LinkedHashMap<String, Object>();

+        map.put("age", 5);

+        map.put("name", "Ubuntu");

+        map.put("list", list);

+        DumperOptions options = new DumperOptions();

+        options.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);

+        options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);

+        options.setPrettyFlow(true);

+        Yaml yaml = new Yaml(options);

+        String output = yaml.dump(map);

+        assertEquals("{\n  'age': !!int '5',\n  'name': 'Ubuntu',\n  'list': [\n    !!int '1',\n    !!int '1']\n  \n}\n",

+                output);

+    }

 }

diff --git a/src/test/resources/recursive/no-children-1-pretty.yaml b/src/test/resources/recursive/no-children-1-pretty.yaml
new file mode 100644
index 0000000..89e9c1c
--- /dev/null
+++ b/src/test/resources/recursive/no-children-1-pretty.yaml
@@ -0,0 +1,23 @@
+&id001 !!org.yaml.snakeyaml.recursive.Human {

+  bankAccountOwner: *id001,

+  birthPlace: Leningrad,

+  birthday: !!timestamp '1970-01-12T13:46:40Z',

+  children: !!set {

+    

+  },

+  father: null,

+  mother: null,

+  name: Father,

+  partner: {

+    bankAccountOwner: *id001,

+    birthPlace: Saint-Petersburg,

+    birthday: !!timestamp '1973-03-03T09:46:40Z',

+    children: !!set {

+      

+    },

+    father: null,

+    mother: null,

+    name: Mother,

+    partner: *id001

+  }

+}

diff --git a/src/test/resources/recursive/with-children-pretty.yaml b/src/test/resources/recursive/with-children-pretty.yaml
new file mode 100644
index 0000000..0089c4f
--- /dev/null
+++ b/src/test/resources/recursive/with-children-pretty.yaml
@@ -0,0 +1,45 @@
+&id002 {
+  bankAccountOwner: &id001 {
+    bankAccountOwner: *id001,
+    birthPlace: Leningrad,
+    birthday: !!timestamp '1970-01-12T13:46:40Z',
+    children: &id003 !!set {
+      *id002: null,
+      ? {
+        bankAccountOwner: *id001,
+        birthPlace: New York,
+        birthday: !!timestamp '1983-04-24T02:40:00Z',
+        children: !!set {
+          
+        },
+        father: *id001,
+        mother: &id004 {
+          bankAccountOwner: *id001,
+          birthPlace: Saint-Petersburg,
+          birthday: !!timestamp '1973-03-03T09:46:40Z',
+          children: *id003,
+          father: null,
+          mother: null,
+          name: Mother,
+          partner: *id001
+        },
+        name: Daughter,
+        partner: null
+      }
+      : null
+    },
+    father: null,
+    mother: null,
+    name: Father,
+    partner: *id004
+  },
+  birthPlace: Munich,
+  birthday: !!timestamp '1979-10-28T23:06:40Z',
+  children: !!set {
+    
+  },
+  father: *id001,
+  mother: *id004,
+  name: Son,
+  partner: null
+}