# This file is part of python-ly, https://pypi.python.org/pypi/python-ly
#
# Copyright (c) 2008 - 2015 by Wilbert Berendsen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
# See http://www.gnu.org/licenses/ for more information.
"""
Parses and tokenizes HTML input, recognizing LilyPond in HTML.
"""
from __future__ import unicode_literals
from . import _token
from . import Parser, FallthroughParser
from . import lilypond
        
        
[docs]
class String(_token.String):
    pass 
[docs]
class Tag(_token.Token):
    pass 
        
[docs]
class TagEnd(Tag, _token.Leaver):
    rx = r"/?>" 
    
[docs]
class AttrName(_token.Token):
    rx = r"\w+([-_:]\w+)?" 
    
    
[docs]
class EqualSign(_token.Token):
    rx = "="
[docs]
    def update_state(self, state):
        state.enter(ParseValue()) 
 
[docs]
class Value(_token.Leaver):
    rx = r"\w+" 
    
[docs]
class StringDQStart(String, _token.StringStart):
    rx = r'"'
[docs]
    def update_state(self, state):
        state.enter(ParseStringDQ()) 
 
[docs]
class StringSQStart(String, _token.StringStart):
    rx = r"'"
[docs]
    def update_state(self, state):
        state.enter(ParseStringSQ()) 
 
    
[docs]
class StringDQEnd(String, _token.StringEnd, _token.Leaver):
    rx = r'"' 
    
[docs]
class StringSQEnd(String, _token.StringEnd, _token.Leaver):
    rx = r"'" 
[docs]
class EntityRef(_token.Character):
    rx = r"\&(#\d+|#[xX][0-9A-Fa-f]+|[A-Za-z_:][\w.:_-]*);" 
[docs]
class LilyPondTag(Tag):
    pass 
[docs]
class LilyPondVersionTag(LilyPondTag):
    rx = r"<lilypondversion/?>" 
[docs]
class LilyPondFileTag(LilyPondTag):
    rx = r"</?lilypondfile\b"
[docs]
    def update_state(self, state):
        state.enter(ParseLilyPondFileOptions()) 
 
[docs]
class LilyPondFileTagEnd(LilyPondTag, _token.Leaver):
    rx = r"/?>" 
[docs]
class LilyPondInlineTag(LilyPondTag):
    rx = r"<lilypond\b"
[docs]
    def update_state(self, state):
        state.enter(ParseLilyPondAttr()) 
 
[docs]
class LilyPondCloseTag(LilyPondTag, _token.Leaver):
    rx = r"</lilypond>" 
    
    
[docs]
class LilyPondTagEnd(LilyPondTag):
    rx = r">"
[docs]
    def update_state(self, state):
        state.replace(ParseLilyPond()) 
 
[docs]
class LilyPondInlineTagEnd(LilyPondTag, _token.Leaver):
    rx = r"/?>" 
    
[docs]
class SemiColon(_token.Token):
    rx = r":"
[docs]
    def update_state(self, state):
        state.replace(ParseLilyPondInline()) 
 
# Parsers:
[docs]
class ParseHTML(Parser):
    mode = "html"
    items = (
        _token.Space,
        LilyPondVersionTag,
        LilyPondFileTag,
        LilyPondInlineTag,
        CommentStart,
        TagStart,
        EntityRef,
    ) 
[docs]
class ParseAttr(Parser):
    items = (
        _token.Space,
        TagEnd,
        AttrName,
        EqualSign,
        StringDQStart,
        StringSQStart,
    ) 
[docs]
class ParseStringDQ(Parser):
    default = String
    items = (
        StringDQEnd,
        EntityRef,
    ) 
    
[docs]
class ParseStringSQ(Parser):
    default = String
    items = (
        StringSQEnd,
        EntityRef,
    ) 
    
[docs]
class ParseValue(FallthroughParser):
    """Finds a value or drops back."""
    items = (
        _token.Space,
        Value,
    )
[docs]
    def fallthrough(self, state):
        state.leave() 
 
[docs]
class ParseLilyPondAttr(Parser):
    items = (
        _token.Space,
        AttrName,
        EqualSign,
        StringDQStart,
        StringSQStart,
        LilyPondTagEnd,
        SemiColon,
    ) 
    
[docs]
class ParseLilyPondFileOptions(Parser):
    items = (
        _token.Space,
        AttrName,
        EqualSign,
        StringDQStart,
        StringSQStart,
        LilyPondFileTagEnd,
    ) 
[docs]
class ParseLilyPond(lilypond.ParseGlobal):
    items = (
        LilyPondCloseTag,
    ) + lilypond.ParseGlobal.items 
    
[docs]
class ParseLilyPondInline(lilypond.ParseMusic):
    items = (
        LilyPondInlineTagEnd,
    ) + lilypond.ParseMusic.items