]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Parser: Add support for lists
authorDidier 'Ptitjes <ptitjes at free dot fr>
Sat, 31 Oct 2009 02:31:43 +0000 (03:31 +0100)
committerFlorian Brosch <flo.brosch@gmail.com>
Sat, 31 Oct 2009 02:31:43 +0000 (03:31 +0100)
13 files changed:
icons/devhelpstyle.css
icons/style.css
icons/wikistyle.css
src/libvaladoc/content/list.vala
src/libvaladoc/content/listitem.vala
src/libvaladoc/documentation/documentationparser.vala
src/libvaladoc/documentation/wikiscanner.vala
src/libvaladoc/html/htmlmarkupwriter.vala
src/libvaladoc/html/htmlrenderer.vala
src/libvaladoc/parser/optionalrule.vala
src/libvaladoc/parser/rule.vala
src/libvaladoc/parser/sequencerule.vala
src/libvaladoc/parser/tokentype.vala

index e3271c5ad141edec79e9bfe763059aa3b049853b..9e40478d7374d93a24c0bfc79df9873e1ab67d77 100644 (file)
@@ -467,7 +467,9 @@ a.navi_link:hover, a.external_link:hover {
        text-decoration: underline;
 }
 
-
+ul.no_bullet > li {
+       list-style-type: none;
+}
 
 
 .main_see_list {
index eb4d280e4ff0d2a1c46fbfa474c8867387af4e19..3124d44a742e12ba2b932ccf3d494be946662c35 100644 (file)
@@ -481,7 +481,9 @@ a.navi_link:hover, a.external_link:hover {
        text-decoration: underline;
 }
 
-
+ul.no_bullet > li {
+       list-style-type: none;
+}
 
 
 .main_see_list {
index 5f7f0eb82ae423f399be3b8ecbbc5d82e20d1437..ab128be8a59510da3a483e163f5dea1f9fb3c7c7 100644 (file)
@@ -479,6 +479,11 @@ a.navi_link:hover, a.external_link:hover {
        text-decoration: underline;
 }
 
+ul.no_bullet > li {
+       list-style-type: none;
+}
+
+
 .main_see_list {
 }
 
index 882715a64242dcfb5ce0369aafff0422688877bf..4170a43291ed543d4c60a4d898411ed7bd37bcf0 100755 (executable)
@@ -24,18 +24,30 @@ using Gee;
 
 
 public class Valadoc.Content.List : ContentElement, Block {
+       public enum Bullet {
+               NONE,
+               UNORDERED,
+               ORDERED,
+               ORDERED_NUMBER,
+               ORDERED_LOWER_CASE_ALPHA,
+               ORDERED_UPPER_CASE_ALPHA,
+               ORDERED_LOWER_CASE_ROMAN,
+               ORDERED_UPPER_CASE_ROMAN
+       }
+
+       public Bullet bullet { get; set; }
+       // TODO add initial value (either a number or some letters)
        public Gee.List<ListItem> items { get { return _items; } }
 
        private Gee.List<ListItem> _items;
 
        internal List () {
                base ();
+               _bullet = Bullet.NONE;
                _items = new ArrayList<ListItem> ();
        }
 
        public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
-               // Check the list consistency in terms of successive item levels ?
-
                // Check individual list items
                foreach (ListItem element in _items) {
                        element.check (api_root, container, reporter);
@@ -45,5 +57,10 @@ public class Valadoc.Content.List : ContentElement, Block {
        public override void accept (ContentVisitor visitor) {
                visitor.visit_list (this);
        }
-}
 
+       public override void accept_children (ContentVisitor visitor) {
+               foreach (ListItem element in _items) {
+                       element.accept (visitor);
+               }
+       }
+}
index 31f7db5fababd08b4d0dac20815271764165871f..8a2c6f9f9210ba422d336becc9aada55e88e2935 100755 (executable)
@@ -24,34 +24,30 @@ using Gee;
 
 
 public class Valadoc.Content.ListItem : InlineContent {
-       public enum Bullet {
-               NONE,
-               UNORDERED,
-               ORDERED,
-               ORDERED_LATIN,
-               ORDERED_CAPITAL,
-               ORDERED_NUMBER,
-               ORDERED_LOWER_CASE
-       }
-
-       public Bullet bullet { get; set; }
-       public int level { get; set; }
+       public List? sub_list { get; set; }
 
        internal ListItem () {
                base ();
-               _bullet = Bullet.UNORDERED;
-               _level = 0;
        }
 
        public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
-               // TODO report error if level == 0 ?
-
                // Check inline content
                base.check (api_root, container, reporter);
+
+               if (sub_list != null) {
+                       sub_list.check (api_root, container, reporter);
+               }
        }
 
        public override void accept (ContentVisitor visitor) {
                visitor.visit_list_item (this);
        }
-}
 
+       public override void accept_children (ContentVisitor visitor) {
+               base.accept_children (visitor);
+
+               if (sub_list != null) {
+                       sub_list.accept (visitor);
+               }
+       }
+}
index 273b9d601265e7ad09728c3071a9f47ec8f5d444..28e0fcc3814e419cb44c61f2422c6cacee8cbe52 100644 (file)
@@ -115,9 +115,9 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
                _stack.add (element);
        }
 
-       private Object peek () {
-               assert (_stack.size > 0);
-               return _stack.get (_stack.size - 1);
+       private Object peek (int offset = -1) {
+               assert (_stack.size >= - offset);
+               return _stack.get (_stack.size + offset);
        }
 
        private Object pop () {
@@ -127,6 +127,86 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
        }
 
        private Rule multiline_run;
+       private int current_level = 0;
+       private int[] levels = new int[0];
+
+       private void new_list_item (Content.List.Bullet bullet) throws ParserError {
+               var new_item = _factory.create_list_item ();
+
+               Content.List list = null;
+               if (levels.length >= 1) {
+                       if (current_level > levels[levels.length - 1]) {
+                               list = _factory.create_list ();
+                               list.bullet = bullet;
+
+                               var current_item = peek () as ListItem;
+                               current_item.sub_list = list;
+                               push (list);
+
+                               levels += current_level;
+                       } else {
+                               bool poped_some_lists = false;
+                               while (current_level < levels[levels.length - 1]) {
+                                       // Pop current item and list
+                                       pop ();
+                                       pop ();
+                                       levels.resize (levels.length - 1);
+                                       poped_some_lists = true;
+                               }
+                               list = peek (-2) as Content.List;
+
+                               if (!poped_some_lists && bullet == Content.List.Bullet.NONE) {
+                                       ((InlineContent) peek ()).content.add (_factory.create_text (" "));
+                                       return;
+                               } else if (list.bullet != bullet) {
+                                       _parser.error ("Invalid bullet type '%s': expected '%s'".printf (bullet_type_string (bullet), bullet_type_string (list.bullet)));
+                                       return;
+                               }
+
+                               pop ();
+                       }
+               } else {
+                       list = _factory.create_list ();
+                       list.bullet = bullet;
+
+                       ((BlockContent) peek ()).content.add (list);
+                       push (list);
+
+                       levels = new int[0];
+                       levels += current_level;
+               }
+
+               list.items.add (new_item);
+               push (new_item);
+       }
+
+       private string bullet_type_string (Content.List.Bullet bullet) {
+               switch (bullet) {
+               case Content.List.Bullet.NONE:
+                       return ".";
+               case Content.List.Bullet.UNORDERED:
+                       return "*";
+               case Content.List.Bullet.ORDERED_NUMBER:
+                       return "1.";
+               case Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA:
+                       return "a.";
+               case Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA:
+                       return "A.";
+               case Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN:
+                       return "i.";
+               case Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN:
+                       return "I.";
+               }
+               return "";
+       }
+
+       private void finish_list () {
+               while (peek () is ListItem) {
+                       pop ();
+                       pop ();
+                       levels.resize (levels.length - 1);
+               }
+       }
 
        private void init_rules () {
                // Inline rules
@@ -153,8 +233,6 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
                                        Rule.many ({
                                                Rule.one_of ({
                                                        word,
-                                                       TokenType.STAR.action (add_text),
-                                                       TokenType.SHARP.action (add_text),
                                                        TokenType.LESS_THAN.action (add_text),
                                                        TokenType.GREATER_THAN.action (add_text),
                                                        TokenType.ALIGN_RIGHT.action (add_text),
@@ -287,36 +365,37 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
                        .set_start (() => { push (_factory.create_source_code ()); })
                        .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
 
-               Rule list_item =
+               Rule indented_item =
                        Rule.seq ({
                                Rule.many ({
-                                       TokenType.SPACE.action ((token) => { ((ListItem) peek ()).level++; })
-                               }),
-                               Rule.one_of ({
-                                       TokenType.STAR.action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.UNORDERED; }),
-                                       TokenType.SHARP.action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED; }),
-                                       TokenType.str (".").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.NONE; }),
-                                       TokenType.str ("I.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_LATIN; }),
-                                       TokenType.str ("A.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_CAPITAL; }),
-                                       TokenType.str ("1.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_NUMBER; }),
-                                       TokenType.str ("a.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_LOWER_CASE; })
+                                       TokenType.SPACE.action ((token) => { current_level++; })
                                }),
+                               Rule.option ({
+                                       Rule.one_of ({
+                                               TokenType.str (".").action ((token) => { new_list_item (Content.List.Bullet.NONE); }),
+                                               TokenType.str ("*").action ((token) => { new_list_item (Content.List.Bullet.UNORDERED); }),
+                                               TokenType.str ("#").action ((token) => { new_list_item (Content.List.Bullet.ORDERED); }),
+                                               TokenType.str ("1.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_NUMBER); }),
+                                               TokenType.str ("a.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA); }),
+                                               TokenType.str ("A.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA); }),
+                                               TokenType.str ("i.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN); }),
+                                               TokenType.str ("I.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN); })
+                                       }),
+                                       TokenType.SPACE
+                               })
+                               .set_skip (() => { new_list_item (Content.List.Bullet.NONE); }),
                                run,
                                TokenType.EOL
                        })
-                       .set_name ("ListItem")
-                       .set_start (() => { push (_factory.create_list_item ()); })
-                       .set_reduce (() => { ((Content.List) peek ()).items.add ((ListItem) pop ()); });
-               Rule list =
-                       Rule.seq ({
-                               Rule.many ({
-                                       list_item
-                               }),
-                               TokenType.EOL
+                       .set_name ("IndentedItem")
+                       .set_start (() => { current_level = 0; });
+
+               Rule indented_blocks =
+                       Rule.many ({
+                               indented_item
                        })
-                       .set_name ("List")
-                       .set_start (() => { push (_factory.create_list ()); })
-                       .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+                       .set_name ("IndentedBlocks")
+                       .set_reduce (() => { finish_list (); });
 
                Rule table_cell_attributes =
                        Rule.seq ({
@@ -432,7 +511,7 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
                Rule blocks =
                        Rule.one_of ({
                                source_code,
-                               list,
+                               indented_blocks,
                                table,
                                headline,
                                paragraph
index 3f0c8dfc2a8c3e93bff44344bcaa50592ef8a26d..47640a7aac5e1a9ded020a519363427ca86c5881 100644 (file)
@@ -208,14 +208,6 @@ public class Valadoc.WikiScanner : Object, Scanner {
                                }
                                break;
 
-                       case '*':
-                               emit_token (TokenType.STAR);
-                               break;
-
-                       case '#':
-                               emit_token (TokenType.SHARP);
-                               break;
-
                        case '-':
                                if (_last_char.isalnum () || get_next_char ().isalnum ()) {
                                        append_char (c);
@@ -392,4 +384,3 @@ public class Valadoc.WikiScanner : Object, Scanner {
                }
        }
 }
-
index 004a704bcc66fd4198653deed47b91261112b7a2..d5c56c4d9f41a59d1c945e6225850c525b4eb566 100755 (executable)
@@ -86,6 +86,7 @@ public class Valadoc.Html.MarkupWriter : Valadoc.MarkupWriter {
                        || name == "h3"
                        || name == "h4"
                        || name == "h5"
+                       || name == "li"
                        || name == "span"
                        || name == "code"
                        || name == "b"
index e02076bfa48730d0edc5402b447c2cf169f52bb6..6ff7d49cb020748dd626ff87f7af315694ef5afb 100755 (executable)
@@ -225,9 +225,50 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
        }
 
        public override void visit_list (Content.List element) {
+               string list_type = null;
+               string bullet_type = null;
+               string css_class = null;
+               switch (element.bullet) {
+               case Content.List.Bullet.NONE:
+                       list_type = "ul";
+                       css_class = "no_bullet";
+                       break;
+               case Content.List.Bullet.UNORDERED:
+                       list_type = "ul";
+                       break;
+               case Content.List.Bullet.ORDERED:
+                       list_type = "ol";
+                       break;
+               case Content.List.Bullet.ORDERED_NUMBER:
+                       list_type = "ol";
+                       bullet_type = "1";
+                       break;
+               case Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA:
+                       list_type = "ol";
+                       bullet_type = "a";
+                       break;
+               case Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA:
+                       list_type = "ol";
+                       bullet_type = "A";
+                       break;
+               case Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN:
+                       list_type = "ol";
+                       bullet_type = "i";
+                       break;
+               case Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN:
+                       list_type = "ol";
+                       bullet_type = "I";
+                       break;
+               }
+               writer.start_tag (list_type, {"class", css_class, "type", bullet_type});
+               element.accept_children (this);
+               writer.end_tag (list_type);
        }
 
        public override void visit_list_item (ListItem element) {
+               writer.start_tag ("li");
+               element.accept_children (this);
+               writer.end_tag ("li");
        }
 
        public override void visit_page (Page element) {
index 2498c76a09e142eb700a9f744913b51174ad0e00..693b581de53b9774132caa4df1cfdf51c0bf9e3e 100644 (file)
@@ -57,7 +57,7 @@ internal class Valadoc.OptionalRule : Rule {
                        if (try_to_apply (_scheme, token, parser, out handled)) {
                                return handled;
                        } else {
-                               do_reduce (parser);
+                               do_skip (parser);
                                return false;
                        }
                } else {
index abbaeffd49a8281250d919bd7e3c5b19bfa88436..b63495c492f94eab7865c782bd009632164763f6 100644 (file)
@@ -54,6 +54,7 @@ public abstract class Valadoc.Rule : Object {
        private string? _name = null;
        private Action _start_action;
        private Action _reduce_action;
+       private Action _skip_action;
 
        public string name { get { return _name; } }
 
@@ -74,6 +75,11 @@ public abstract class Valadoc.Rule : Object {
                return this;
        }
 
+       public Rule set_skip (Action action) {
+               _skip_action = action;
+               return this;
+       }
+
        public enum Forward {
                NONE, PARENT, CHILD
        }
@@ -147,4 +153,10 @@ public abstract class Valadoc.Rule : Object {
                }
                parser.reduce ();
        }
+
+       protected void do_skip (ParserCallback parser) throws ParserError {
+               if (_skip_action != null) {
+                       _skip_action ();
+               }
+       }
 }
index 3cad1a583c17f70795802fd5007b772ce4ad6921..b2f9d5a94c93e62b1e38ebb1b3192c6a12a312b4 100644 (file)
@@ -91,6 +91,8 @@ internal class Valadoc.SequenceRule : Rule {
                        }
                        if (!is_optional_rule (scheme_element)) {
                                break;
+                       } else {
+                               ((Rule) scheme_element).do_skip (parser);
                        }
                        state.index++;
                } while (state.index < _scheme.length);
index 6ebc19ad64ca034d06f261e5e7fadffd4151a06e..598aac3e849382247e8387538f656aee02295101 100644 (file)
@@ -38,8 +38,6 @@ public class Valadoc.TokenType : Object {
        public static TokenType EQUAL_4;
        public static TokenType EQUAL_5;
        public static TokenType MINUS;
-       public static TokenType STAR;
-       public static TokenType SHARP;
        public static TokenType LESS_THAN;
        public static TokenType GREATER_THAN;
        public static TokenType ALIGN_TOP;
@@ -79,8 +77,6 @@ public class Valadoc.TokenType : Object {
                        EQUAL_4 = new TokenType.basic ("=====");
                        EQUAL_5 = new TokenType.basic ("======");
                        MINUS = new TokenType.basic ("-");
-                       STAR = new TokenType.basic ("*");
-                       SHARP = new TokenType.basic ("#");
                        LESS_THAN = new TokenType.basic ("<");
                        GREATER_THAN = new TokenType.basic (">");
                        ALIGN_TOP = new TokenType.basic ("^");