<!--
Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
The copyrights embodied in the content of this file are licensed by
Yahoo! Inc. under the BSD (revised) open source license

@author Dan Vlad Dascalescu <dandv@yahoo-inc.com>

-->


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script src="../../js/codemirror.js" type="text/javascript"></script>
    <title>CodeMirror: PHP+HTML+JavaScript+CSS mixed-mode demonstration</title>
    <link rel="stylesheet" type="text/css" href="../../css/docs.css"/>
  </head>
  <body style="padding: 20px;">

    <p>This is a complex demonstration of the <b>PHP+HTML+JavaScript+CSS mixed-mode
    syntax highlight</b> capabilities of <a href="../../index.html">CodeMirror</a>.
    &lt;?php ... ?> tags use the PHP parser, &lt;script> tags use the JavaScript
    parser, and &lt;style> tags use the CSS parser. The rest of the content is
    parsed using the XML parser in HTML mode.</p>

    <p>Features of the PHP parser:
    <ul>
      <li>special "deprecated" style for PHP4 keywords like 'var'
      <li>support for PHP 5.3 keywords: 'namespace', 'use'
      <li>911 predefined constants, 1301 predefined functions, 105 predeclared classes
        from a typical PHP installation in a LAMP environment
      <li>new feature: syntax error flagging, thus enabling strict parsing of:
        <ol>
          <li>function definitions with explicitly or implicitly typed arguments and default values
          <li>modifiers (public, static etc.) applied to method and member definitions
          <li>foreach(array_expression as $key [=> $value]) loops
        </ol>
      <li>differentiation between single-quoted strings and double-quoted interpolating strings
    </ul>
    </p>

    <div style="border: 1px solid black; padding: 3px; background-color: #F8F8F8">
    <textarea id="code" cols="120" rows="30">
The "root" parser is XML in HTML mode.
Next, we can switch into PHP mode, for example. This is
<?php echo 'text output by';
?>
PHP. </b>
On the line above, we just had an XML syntax error due to the </b> tag not being opened.

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>   HTML text will follow
<html>
  <head>
    <title>Similarly, the 'script' tag will switch to the JavaScript parser:</title>
    <script type="text/javascript">
       // Press enter inside the object and your new line will be suitably
       // indented.
       var keyBindings = {
         enter: "newline-and-indent",
         tab: "reindent-selection",
         ctrl_enter: "reparse-buffer",
         ctrl_z: "undo",
         ctrl_y: "redo",
         ctrl_backspace: "undo-for-safari-which-stupidly-enough-blocks-ctrl-z"
       };

       // Press tab on the next line and the wrong indentation will be fixed.
             var regex = /foo|bar/i;

       function example(x) {
         // Local variables get a different colour than global ones.
         var y = 44.4;
         return x + y - z;
       }
    </script>
    <style>
      /* Some example CSS */

      @import url("something.css");

      body {
        margin: 0;
        padding: 3em 6em;
        font-family: tahoma, arial, sans-serif;
        color: #000;
      }

      #navigation a {
        font-weight: bold;
        text-decoration: none !important;
      }

      h1 {
        font-size: 2.5em;
      }

      h1:before, h2:before {
        content: "::";
      }

      code {
        font-family: courier, monospace;
        font-size: 80%;
        color: #418A8A;
      }
    </style>
  </head>

  <body>

  The PHP code below contains some deliberate errors. Play with the editor by fixing them
  and observing how the highlight changes.

    <?php
    namespace A;
    namespace A::B::C;
    namespace A::::B;
    namespace A::B::C::;
    namespace A::B::C::D x;
    self::range($row['lft'], $row['rgt']));  // error: extra ')'
    $a = (b() + 4) 5 foo;  // error: missing operators
    self::$var;
    $parent = self::range($max + 1, $max + 1);
    $row[attributes][$attribute_name] = $attribute_value;
    $row[attributes()][$attribute_name] = $attribute_value;
    $row[attributes(5)][$attribute_name] = $attribute_value;
    $row[$attributes()][$attribute_name] = $attribute_value;
    abstract class 5 extends foo implements echo {
        private function domainObjectBuilder() {
            return $this->use_domain_object_builder
                   ? $this->domain()->objectBuilder()
                   : null;
        }

        const $myconst = 'some string';
        $array[myconst] = 4;
        // this is a single-line C++-style comment
        # this is a single-line shell-style comment
        private var $a = __FILE__;
        protected static $b = timezone_transitions_get('some parameter here');
        global $g = isset("string");
        static $s = hash_update_file;  // warning: predefined function non-call
        function mike ($var) $foo;
        mike(A::func(param));
        func($b $c);  // error: function parameters must be comma-separated
        foo bar;  // error: no operator
        $baz $quux;  // error: no operator
        public abstract function loadPageXML(util_FilePath $filename, $merge=0+$foo, $x, $y=3) {
            $newrow[$key] = $val;
            $newresult[] = $row;
            $state = $row['c'] == 1;
            $attribute_values[$attribute_name] = null;
            $row['attributes'][$attribute_name] = $attribute_value;
            $result[$row['element']][$row['attribute']] = $row['value'];
            $sql = "multiline string
line2 is special - it'll interpolate variables like $state and method calls
{$this->cache->add($key, 5)} and maybe \"more\"

line5";
            $sql = 'multiline string
single quoting means no \'interpolation\' like "$start" or method call
{$this->cache->add($key, 5)} will happen

line5';
            $bitpattern = 1 << 2;
            $bitpattern <<= 3;
            $incorrect = <<< 5 EOSTRING  // FIXME: CodeMirror update bug: add a letter before 5 and notice that syntax is not updated until EOF, even with continuousScanning: 500
error: the identifier must conform to the identifier rules
EOSTRING;
            $sql = <<< EOSQL
                SELECT attribute, element, value
                FROM attribute_values
                WHERE dimension = ?
EOSQL;
            $this->lr_cache->add($key, self::range($row['lft'], $row['rgt']));
            $composite_string = <<<EOSTRING
some lines here
EOSTRING
. 'something extra';
            $page_lft = ($domain->name() == 'page') ? $start + 1 : $page_start + 1;
            echo "This is class foo";
            echo "a = ".$this ->a[2+3*$array["foo"]]."";
            echo "b = {$this->b}";  // FIXME: highlight interpolation in strings
        }
        final function makecoffee error($types = array("cappuccino"), $coffeeMaker = NULL) {
            $out_of_way_amount = $max - $child->left() + 1;
            $absolute_pos = $child->left() - $move->width();
            $varfunc(1, 'x');
            $varfunc(1, 'x') + foo() - 5;
            $funcarray[$i]('param1', $param2);
                $lr[$domain_name] = $this->get_left_and_right($domain,
                                                              $dimension_name,
                                                              $element_name);
            $domain_list = is_null($domain) ?
                           r3_Domain::names() :
                           array($domain->name());
            foreach (r3_Domain::names() as $domain_name) {
                $placeholders = 'distance LIKE '
                            . implode(array_fill(1, $num_distances, '?'),
                                      ' OR distance LIKE ');

            }
            return $this->target*$this->trans+myfunc(__METHOD__);
            /*
            echo 'This is a test'; /* This comment will cause a problem */
            */
        }
        switch( $type ) {
            case "r3core_AddTemplateToTargetEvent":
                $this->notifyAddTemplateToTarget( $genevent );
                break;
            case "r3core_GenerateTargetEvent" $this:
                for($i=0; $i<=this->method(); $i++) {
                    echo 'Syntax "highlighting"';
                }
                try {
                    foreach($array xor $loader->parse_fn($filename) as $key => value) {
                        namespace r3;
                    }
                } catch( Exception $e ) {
                    /** restore the backup
                    */
                    $this->loadAll($tmp, $event, true);
                    // `php -l` doesn't complain at all at this (it assumes string constants):
                    this + makes * no - sense;
                }

                break;

            default moo:
                throw new r3_util_Exception( get_class( $genevent ) . " does not map" );
        }


    };

    ?>

    <r3:cphp>
        php("works", $here, 2);
    </r3:cphp>

    <r4:cphp>
    class foo {
        // a comment
        var $a;
        var $b;
    };
    </r4:cphp>

  <h1>This is an <?php # echo 'simple';?> example.</h1>
  <p>The header above will say 'This is an  example'.</p>
  <h1>This is an <?php // echo 'simple';?> example.</h1>

  <?php echo; ?>
    <body>

<?php echo "<html>
  <head>
    <script>
    var foo = 'bar';
    </script>
    <style>
      span.test {font-family: arial, 'lucida console', sans-serif}
    </style>
  </head>
  <body>
    <!-- comment -->
  </body>
</html>"; ?>

</body>
</html>


    </textarea>
    </div>

    <script type="text/javascript">
      var editor = CodeMirror.fromTextArea('code', {
        height: "350px",
        parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js",
                     "../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js",
                     "../contrib/php/js/parsephphtmlmixed.js"],
        stylesheet: ["../../css/xmlcolors.css", "../../css/jscolors.css", "../../css/csscolors.css", "css/phpcolors.css"],
        path: "../../js/",
        continuousScanning: 500
      });
    </script>


  </body>
</html>
