# -*- coding: UTF-8 -*-
#    This file is part of arena.
#
#    arena 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 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    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 arena.  If not, see <http://www.gnu.org/licenses/>.

## @file
#  This file extends AnArenaPost to allow for syntax highlighting within
#  code blocks.

from Plugins.Content.PerUser.Arena.Posts import AnArenaPost
from Library.IO.StringStreams import AStringStream
from Plugins.User.Subscriptions import Right
from Plugins.Content.Parse.MarkdownParsers import AMarkdownParser
from Plugins.Content.Parse.Semantic.CustomMarkdownStatements import \
    ACustomMarkdownTabBlock, CustomOpcode, HighlightOpcode

from Plugins.Content.Parse.Lex.Languages import MarkdownCharacterTypes
from Library.Parse.Lex.Languages import CharacterType

## A post handler that allows for syntax highlighting by replacing the
#  default Markdown parser with a modified one.
class AnArenaPostWithHighlighting(AnArenaPost):
    ## Parse the contents of the post.
    #
    #  Descendant classes should override this method to parse the contents
    #  of the post before it is displayed to the end user.
    def parseContent(Self):  
               
        result = ""
               
        Event = Self.generate("parseContent")
        if Event.handled():
            result = Event.result()
            del Event
            return result
            
        del Event
        
        if "content" in Self._fieldsValues:
            if len(Self._fieldsValues["content"]) > 0:
                # Construct a string stream for use in parsing.
                # We add the newline character to the beginning of the stream
                # in case a postfix header line is the very first line of the
                # stream.  We add the EOF character to the end of the stream to
                # ensure that the parser knows when to stop, since we are not
                # reading from an actual file.
                Input = AStringStream("\n" + Self._fieldsValues["content"] + 
                  MarkdownCharacterTypes[CharacterType.endOfStream])
                  
                Output = AStringStream()
            
                # Parse the stream
                Markdown = AMarkdownParser(
                    Source = Input, 
                    Log = Self._Log,
                    Content = Self)
                    
                # Register our opcode with the parser
                Markdown.Language().registerOpcodes(**HighlightOpcode)
                #Markdown.Language().Opcodes().printTo(Output)
                #Output.write("<br/>")
                
                Markdown.OutputTo(Output)
                Markdown.parse()
            
                result = Output.toString()
                    
                del Markdown
                del Output
                del Input
                
        return result

