SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Enthusiast
    Join Date
    Jan 2008
    Posts
    86
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    bbcode style lists help

    I'm trying to make a parser for bbcode style formatting but i'm having problems with embedded lists...

    Code:
    [olist colors=#eee;#fce]
        [item]item
            [olist colors=#ddd;#ebd]
                [item]item[/item]
                [item]item[/item]
            [/olist]
        [/item]
        [item]item[/item]
    [/olist]
    
    <ol>
        <li style="background-color:#eee;">item
            <ol>
                <li style="background-color:#ddd;">item</item>
                <li style="background-color:#ebd;">item</item>
            </ol>
        </li>
        <li style="background-color:#fce;">item</li>
    </ol>
    How would I go about this?

  2. #2
    SitePoint Evangelist simshaun's Avatar
    Join Date
    Apr 2008
    Location
    North Carolina
    Posts
    438
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'd use a RegEx callback. With slight changes you could use a DOM parser.

    Personally, I think BBCode is overrated. I would allow HTML and ensure each tag and its attributes pass through a whitelist of allowed tags.

    Either way, it shouldn't be too hard to write a RegEx callback.

  3. #3
    SitePoint Enthusiast
    Join Date
    Jan 2008
    Posts
    86
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm using bbcode because the person I'm doing this for doesn't want to learn HTML. The problem I am having is with an embedded [olist] inside the [olist]. The only way i know how to do something like this is...

    PHP Code:
    private function buildList($tag$colors$items) {
        
    preg_match_all("~\[item](.*?)\[/item\]~is"$items$items);
        
    $colors explode(";"$colors);
        
    $i 0;
        
    $out "<".$tag.">";
        foreach (
    $items[1] as $item) {
            
    $color $colors[($i &#37; count($colors))];
            
    $out .= "<li style=\"background-color:".$color.";\">".$item."</li>";
            
    $i++;
        }
        
    $out .= "</".$tag.">";
        return 
    $out;
    }

    private function 
    parseLists() {
        
    $this->str preg_replace("~\[olist(=(.*?))\](.*?)\[/olist\]~ies""\$this->buildList('ol', '$2', '$3')"$this->str);
        
    $this->str preg_replace("~\[olist(=(.*?))\](.*?)\[/olist\]~ies""\$this->buildList('ol', '$2', '$3')"$this->str);

    But this breaks when I have [olist][item]...[olist][item]...[/item][/olist][/item][/olist]

  4. #4
    SitePoint Enthusiast Almasty's Avatar
    Join Date
    Mar 2009
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could also use a pre-written library like

    simplehtmldom dot sourceforge dot net

    It is under the MIT license. It contains a single file

    simple_html_dom dot php

    If you open the file I think you can change the open / end tag delimiters

    e.g.,

    Code:
    protected function read_tag() {
            if ($this->char!=='<') {
                $this->root->_[HDOM_INFO_END] = $this->cursor;
                return false;
            }
    Perhaps to

    Code:
    protected function read_tag() {
            if ($this->char!=='[') {
                $this->root->_[HDOM_INFO_END] = $this->cursor;
                return false;
            }
    Making sure you contribute your change back to the community of course.

    Al

  5. #5
    SitePoint Evangelist simshaun's Avatar
    Join Date
    Apr 2008
    Location
    North Carolina
    Posts
    438
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    **Sigh**
    If I would think before replying...

    Without knowing the amount of recursion in the nested set, I don't think its possible to do this with RegEx. The reason being, RegEx does not work like a DOM parser. RegEx goes 1 letter at a time trying to match your expression. On the first [/olist] it sees, it considers the expression complete. Now you can hard-code in the expression further logic that tells it not to stop on the first [/olist] it sees, IF you know how many levels deep it can go.

    Use DOMDocument or something of the likes.....

    Also here are some links for ya:
    http://www.sitepoint.com/article/bb-...p-application/
    http://www.phpclasses.org/browse/package/4374.html
    http://www.christian-seiler.de/proje.../index_en.html
    http://bbcparser.recgr.com/


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •