From: Didier 'Ptitjes Date: Sat, 31 Oct 2009 02:31:43 +0000 (+0100) Subject: Parser: Add support for lists X-Git-Tag: 0.37.1~3^2~503 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c473f549d04477ea4515e05b8f219f5ada354002;p=thirdparty%2Fvala.git Parser: Add support for lists --- diff --git a/icons/devhelpstyle.css b/icons/devhelpstyle.css index e3271c5ad..9e40478d7 100644 --- a/icons/devhelpstyle.css +++ b/icons/devhelpstyle.css @@ -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 { diff --git a/icons/style.css b/icons/style.css index eb4d280e4..3124d44a7 100644 --- a/icons/style.css +++ b/icons/style.css @@ -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 { diff --git a/icons/wikistyle.css b/icons/wikistyle.css index 5f7f0eb82..ab128be8a 100644 --- a/icons/wikistyle.css +++ b/icons/wikistyle.css @@ -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 { } diff --git a/src/libvaladoc/content/list.vala b/src/libvaladoc/content/list.vala index 882715a64..4170a4329 100755 --- a/src/libvaladoc/content/list.vala +++ b/src/libvaladoc/content/list.vala @@ -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 items { get { return _items; } } private Gee.List _items; internal List () { base (); + _bullet = Bullet.NONE; _items = new ArrayList (); } 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); + } + } +} diff --git a/src/libvaladoc/content/listitem.vala b/src/libvaladoc/content/listitem.vala index 31f7db5fa..8a2c6f9f9 100755 --- a/src/libvaladoc/content/listitem.vala +++ b/src/libvaladoc/content/listitem.vala @@ -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); + } + } +} diff --git a/src/libvaladoc/documentation/documentationparser.vala b/src/libvaladoc/documentation/documentationparser.vala index 273b9d601..28e0fcc38 100644 --- a/src/libvaladoc/documentation/documentationparser.vala +++ b/src/libvaladoc/documentation/documentationparser.vala @@ -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 diff --git a/src/libvaladoc/documentation/wikiscanner.vala b/src/libvaladoc/documentation/wikiscanner.vala index 3f0c8dfc2..47640a7aa 100644 --- a/src/libvaladoc/documentation/wikiscanner.vala +++ b/src/libvaladoc/documentation/wikiscanner.vala @@ -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 { } } } - diff --git a/src/libvaladoc/html/htmlmarkupwriter.vala b/src/libvaladoc/html/htmlmarkupwriter.vala index 004a704bc..d5c56c4d9 100755 --- a/src/libvaladoc/html/htmlmarkupwriter.vala +++ b/src/libvaladoc/html/htmlmarkupwriter.vala @@ -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" diff --git a/src/libvaladoc/html/htmlrenderer.vala b/src/libvaladoc/html/htmlrenderer.vala index e02076bfa..6ff7d49cb 100755 --- a/src/libvaladoc/html/htmlrenderer.vala +++ b/src/libvaladoc/html/htmlrenderer.vala @@ -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) { diff --git a/src/libvaladoc/parser/optionalrule.vala b/src/libvaladoc/parser/optionalrule.vala index 2498c76a0..693b581de 100644 --- a/src/libvaladoc/parser/optionalrule.vala +++ b/src/libvaladoc/parser/optionalrule.vala @@ -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 { diff --git a/src/libvaladoc/parser/rule.vala b/src/libvaladoc/parser/rule.vala index abbaeffd4..b63495c49 100644 --- a/src/libvaladoc/parser/rule.vala +++ b/src/libvaladoc/parser/rule.vala @@ -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 (); + } + } } diff --git a/src/libvaladoc/parser/sequencerule.vala b/src/libvaladoc/parser/sequencerule.vala index 3cad1a583..b2f9d5a94 100644 --- a/src/libvaladoc/parser/sequencerule.vala +++ b/src/libvaladoc/parser/sequencerule.vala @@ -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); diff --git a/src/libvaladoc/parser/tokentype.vala b/src/libvaladoc/parser/tokentype.vala index 6ebc19ad6..598aac3e8 100644 --- a/src/libvaladoc/parser/tokentype.vala +++ b/src/libvaladoc/parser/tokentype.vala @@ -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 ("^");