Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:15408 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 16205 invoked by uid 1010); 12 Mar 2005 23:48:16 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 16115 invoked from network); 12 Mar 2005 23:48:15 -0000 Received: from unknown (HELO syconet.de) (127.0.0.1) by localhost with SMTP; 12 Mar 2005 23:48:15 -0000 X-Host-Fingerprint: 203.59.3.38 mail-06.iinet.net.au Linux 2.4/2.6 Received: from ([203.59.3.38:52085] helo=mail.iinet.net.au) by pb1.pair.com (ecelerity HEAD r(5124)) with SMTP id 43/E0-31540-CBF73324 for ; Sat, 12 Mar 2005 18:48:14 -0500 Received: (qmail 31337 invoked from network); 12 Mar 2005 23:47:20 -0000 Received: from unknown (HELO ?10.1.1.66?) (203.173.46.98) by mail.iinet.net.au with SMTP; 12 Mar 2005 23:47:19 -0000 Message-ID: <42337F87.2010802@jefferyfernandez.id.au> Date: Sun, 13 Mar 2005 10:47:19 +1100 User-Agent: Mozilla Thunderbird 1.0 (X11/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Johannes Schlueter CC: internals@lists.php.net, smith@backendmedia.com References: <200503130016.15221.johannes@php.net> In-Reply-To: <200503130016.15221.johannes@php.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [patch] highlight_[file|string] and line numbers From: forums@jefferyfernandez.id.au (Jeffery Fernandez) Johannes Schlueter wrote: >Hi, > >some days (or even weeks?) ago Lukas asked on IRC wether there is a way to get >PHP code highlighted with linenumbers. The first reaction of most people >(including me) was "no" since you can't copy&paste the code but after >thinking I found out that
    works really fine. So I've implemented it that >way and added an optional bool parameter to the highlight functions. >Additionally I've added two other parameters to these functions: The first >one is a bool that adds jump targets (), second one is a >prefix to this number () which is needed to make sure >the jump target is unique even if more than one snippet is added to the >output. > >This doesn't work with .phps yet since we would a new php.ini setting which I >didn't want to add or numbered output would need to become default. > >My patch is attached and, if it doesn't come through, available on >http://www.schlueters.de/zend_highlight_20050312_1.diff a sample output is at >http://www.schlueters.de/highlight_pma.html > >johannes > > > > That looks very good but there seems to be serious html issues when I validated that page... Total 1789 erros when I validated that page at w3c. If you can fix that it would be awesome. my 2c >------------------------------------------------------------------------ > >Index: Zend/zend_highlight.h >=================================================================== >RCS file: /repository/ZendEngine2/zend_highlight.h,v >retrieving revision 1.24 >diff -u -r1.24 zend_highlight.h >--- Zend/zend_highlight.h 8 Jan 2004 17:31:47 -0000 1.24 >+++ Zend/zend_highlight.h 12 Mar 2005 14:40:12 -0000 >@@ -41,11 +41,16 @@ > > BEGIN_EXTERN_C() > ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC); >+ZEND_API void zend_highlight_numbered(zend_syntax_highlighter_ini *syntax_highlighter_ini, zend_bool mark_lines, char *line_prefix TSRMLS_DC); > ZEND_API void zend_strip(TSRMLS_D); > ZEND_API int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC); >+ZEND_API int highlight_file_ex(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini, zend_bool numbered, zend_bool mark_lines, char *line_prefix TSRMLS_DC); > ZEND_API int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC); >+ZEND_API int highlight_string_ex(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name, zend_bool numbered, zend_bool mark_lines, char *line_prefix TSRMLS_DC); > ZEND_API void zend_html_putc(char c); >+ZEND_API void zend_html_putc_ex(char c, char *last_color, int *line, char *line_prefix); > ZEND_API void zend_html_puts(const char *s, uint len TSRMLS_DC); >+ZEND_API void zend_html_puts_ex(const char *s, uint len, char *last_color, int *line, char *line_prefix TSRMLS_DC); > END_EXTERN_C() > > extern zend_syntax_highlighter_ini syntax_highlighter_ini; >Index: Zend/zend_highlight.c >=================================================================== >RCS file: /repository/ZendEngine2/zend_highlight.c,v >retrieving revision 1.47 >diff -u -r1.47 zend_highlight.c >--- Zend/zend_highlight.c 2 Jan 2005 23:53:43 -0000 1.47 >+++ Zend/zend_highlight.c 12 Mar 2005 14:40:12 -0000 >@@ -53,9 +53,35 @@ > } > } > >+ZEND_API void zend_html_putc_ex(char c, char *last_color, int *line, char *line_prefix) >+{ >+ if (c == '\n') { >+ /* the   is needed to work around https://bugzilla.mozilla.org/show_bug.cgi?id=194831 */ >+ zend_printf(" \n
  1. "); >+ if (last_color != NULL) { >+ if (line && *line) { >+ if (line_prefix) { >+ zend_printf("", line_prefix, ++*line); >+ } else { >+ zend_printf("", ++*line); >+ } >+ } >+ zend_printf("", last_color); >+ } else { >+ zend_printf(""); >+ } >+ } else { >+ zend_html_putc(c); >+ } >+} > > ZEND_API void zend_html_puts(const char *s, uint len TSRMLS_DC) > { >+ zend_html_puts_ex(s, len, NULL, NULL, NULL TSRMLS_CC); >+} >+ >+ZEND_API void zend_html_puts_ex(const char *s, uint len, char *last_color, int *line, char *line_prefix TSRMLS_DC) >+{ > const char *ptr=s, *end=s+len; > > #ifdef ZEND_MULTIBYTE >@@ -83,7 +109,11 @@ > ptr++; > } > } else { >- zend_html_putc(*ptr++); >+ if (last_color == NULL) { >+ zend_html_putc(*ptr++); >+ } else { >+ zend_html_putc_ex(*ptr++, last_color, line, line_prefix); >+ } > } > } > >@@ -196,6 +226,108 @@ > } > > >+ZEND_API void zend_highlight_numbered(zend_syntax_highlighter_ini *syntax_highlighter_ini, zend_bool mark_lines, char *line_prefix TSRMLS_DC) >+{ >+ zval token; >+ int token_type; >+ char *last_color = syntax_highlighter_ini->highlight_html; >+ char *next_color; >+ int in_string=0, post_heredoc = 0; >+ int line = 0; >+ >+ if (mark_lines) { >+ line = 1; >+ if (line_prefix) { >+ zend_printf("
    1. ", line_prefix, line, last_color); >+ } else { >+ zend_printf("
      1. ", line, last_color); >+ } >+ } else { >+ zend_printf("
        1. ", last_color); >+ } >+ /* highlight stuff coming back from zendlex() */ >+ token.type = 0; >+ while ((token_type=lex_scan(&token TSRMLS_CC))) { >+ switch (token_type) { >+ case T_INLINE_HTML: >+ next_color = syntax_highlighter_ini->highlight_html; >+ break; >+ case T_COMMENT: >+ case T_DOC_COMMENT: >+ next_color = syntax_highlighter_ini->highlight_comment; >+ break; >+ case T_OPEN_TAG: >+ case T_OPEN_TAG_WITH_ECHO: >+ next_color = syntax_highlighter_ini->highlight_default; >+ break; >+ case T_CLOSE_TAG: >+ next_color = syntax_highlighter_ini->highlight_default; >+ break; >+ case T_CONSTANT_ENCAPSED_STRING: >+ next_color = syntax_highlighter_ini->highlight_string; >+ break; >+ case '"': >+ next_color = syntax_highlighter_ini->highlight_string; >+ in_string = !in_string; >+ break; >+ case T_WHITESPACE: >+ zend_html_puts_ex(LANG_SCNG(yy_text), LANG_SCNG(yy_leng), last_color, &line, line_prefix TSRMLS_CC); /* no color needed */ >+ token.type = 0; >+ continue; >+ break; >+ default: >+ if (in_string) { >+ next_color = syntax_highlighter_ini->highlight_string; >+ } else if (token.type == 0) { >+ next_color = syntax_highlighter_ini->highlight_keyword; >+ } else { >+ next_color = syntax_highlighter_ini->highlight_default; >+ } >+ break; >+ } >+ >+ if (last_color != next_color) { >+ last_color = next_color; >+ zend_printf("", last_color); >+ >+ } >+ switch (token_type) { >+ case T_END_HEREDOC: >+ zend_html_puts_ex(token.value.str.val, token.value.str.len, last_color, &line, line_prefix TSRMLS_CC); >+ post_heredoc = 1; >+ break; >+ default: >+ zend_html_puts_ex(LANG_SCNG(yy_text), LANG_SCNG(yy_leng), last_color, &line, line_prefix TSRMLS_CC); >+ if (post_heredoc) { >+ zend_html_putc_ex('\n', last_color, &line, line_prefix); >+ post_heredoc = 0; >+ } >+ break; >+ } >+ >+ if (token.type == IS_STRING) { >+ switch (token_type) { >+ case T_OPEN_TAG: >+ case T_OPEN_TAG_WITH_ECHO: >+ case T_CLOSE_TAG: >+ case T_WHITESPACE: >+ case T_COMMENT: >+ case T_DOC_COMMENT: >+ break; >+ default: >+ efree(token.value.str.val); >+ break; >+ } >+ } else if (token_type == T_END_HEREDOC) { >+ efree(token.value.str.val); >+ } >+ token.type = 0; >+ } >+ zend_printf(""); >+ zend_printf("
        "); >+} >+ >+ > > ZEND_API void zend_strip(TSRMLS_D) > { >Index: Zend/zend_language_scanner.l >=================================================================== >RCS file: /repository/ZendEngine2/zend_language_scanner.l,v >retrieving revision 1.124 >diff -u -r1.124 zend_language_scanner.l >--- Zend/zend_language_scanner.l 7 Mar 2005 16:48:49 -0000 1.124 >+++ Zend/zend_language_scanner.l 12 Mar 2005 14:40:13 -0000 >@@ -557,11 +557,11 @@ > > > BEGIN_EXTERN_C() >-int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC) >+int highlight_file_ex(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini, zend_bool numbered, zend_bool mark_lines, char *line_prefix TSRMLS_DC) > { > zend_lex_state original_lex_state; > zend_file_handle file_handle; >- >+ > file_handle.type = ZEND_HANDLE_FILENAME; > file_handle.filename = filename; > file_handle.free_filename = 0; >@@ -571,7 +571,11 @@ > zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename); > return FAILURE; > } >- zend_highlight(syntax_highlighter_ini TSRMLS_CC); >+ if (numbered) { >+ zend_highlight_numbered(syntax_highlighter_ini, mark_lines, line_prefix TSRMLS_CC); >+ } else { >+ zend_highlight(syntax_highlighter_ini TSRMLS_CC); >+ } > #ifdef ZEND_MULTIBYTE > if (SCNG(script_org)) { > efree(SCNG(script_org)); >@@ -587,7 +591,12 @@ > return SUCCESS; > } > >-int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC) >+int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC) >+{ >+ return highlight_file_ex(filename, syntax_highlighter_ini, 0, 0, NULL TSRMLS_CC); >+} >+ >+int highlight_string_ex(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name, zend_bool numbered, zend_bool mark_lines, char *line_prefix TSRMLS_DC) > { > zend_lex_state original_lex_state; > zval tmp = *str; >@@ -598,7 +607,11 @@ > if (zend_prepare_string_for_scanning(str, str_name TSRMLS_CC)==FAILURE) { > return FAILURE; > } >- zend_highlight(syntax_highlighter_ini TSRMLS_CC); >+ if (numbered) { >+ zend_highlight_numbered(syntax_highlighter_ini, mark_lines, line_prefix TSRMLS_CC); >+ } else { >+ zend_highlight(syntax_highlighter_ini TSRMLS_CC); >+ } > #ifdef ZEND_MULTIBYTE > if (SCNG(script_org)) { > efree(SCNG(script_org)); >@@ -613,6 +626,11 @@ > zval_dtor(str); > return SUCCESS; > } >+ >+int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC) >+{ >+ return highlight_string_ex(str, syntax_highlighter_ini, str_name, 0, 0, NULL TSRMLS_CC); >+} > END_EXTERN_C() > > #ifdef ZEND_MULTIBYTE >Index: ext/standard/basic_functions.c >=================================================================== >RCS file: /repository/php-src/ext/standard/basic_functions.c,v >retrieving revision 1.705 >diff -u -r1.705 basic_functions.c >--- ext/standard/basic_functions.c 7 Mar 2005 19:37:26 -0000 1.705 >+++ ext/standard/basic_functions.c 12 Mar 2005 14:40:14 -0000 >@@ -2353,15 +2353,19 @@ > syntax_highlighter_ini->highlight_string = INI_STR("highlight.string"); > } > >-/* {{{ proto bool highlight_file(string file_name [, bool return] ) >+/* {{{ proto bool highlight_file(string file_name [, bool return [, bool numbered [, bool mark_lines [, string mark_prefix]]]] ) > Syntax highlight a source file */ > PHP_FUNCTION(highlight_file) > { > zval *filename; > zend_syntax_highlighter_ini syntax_highlighter_ini; > zend_bool i = 0; >+ zend_bool numbered = 0; >+ zend_bool mark_lines = 0; >+ char *line_prefix = NULL; >+ int line_prefix_len = 0; > >- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &filename, &i) == FAILURE) { >+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bbbs", &filename, &i, &numbered, &mark_lines, &line_prefix, &line_prefix_len) == FAILURE) { > RETURN_FALSE; > } > convert_to_string(filename); >@@ -2380,7 +2384,7 @@ > > php_get_highlight_struct(&syntax_highlighter_ini); > >- if (highlight_file(Z_STRVAL_P(filename), &syntax_highlighter_ini TSRMLS_CC) == FAILURE) { >+ if (highlight_file_ex(Z_STRVAL_P(filename), &syntax_highlighter_ini, numbered, mark_lines, line_prefix TSRMLS_CC) == FAILURE) { > RETURN_FALSE; > } > >@@ -2472,7 +2476,7 @@ > } > /* }}} */ > >-/* {{{ proto bool highlight_string(string string [, bool return] ) >+/* {{{ proto bool highlight_string(string string [, bool return [, bool mark_lines [, string mark_prefix]]] ) > Syntax highlight a string or optionally return it */ > PHP_FUNCTION(highlight_string) > { >@@ -2480,9 +2484,13 @@ > zend_syntax_highlighter_ini syntax_highlighter_ini; > char *hicompiled_string_description; > zend_bool i = 0; >+ zend_bool numbered = 0; >+ zend_bool mark_lines = 0; >+ char *line_prefix = NULL; >+ int line_prefix_len = 0; > int old_error_reporting = EG(error_reporting); > >- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &expr, &i) == FAILURE) { >+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bbbs", &expr, &i, &numbered, &mark_lines, &line_prefix, &line_prefix_len) == FAILURE) { > RETURN_FALSE; > } > convert_to_string(expr); >@@ -2497,7 +2505,7 @@ > > hicompiled_string_description = zend_make_compiled_string_description("highlighted code" TSRMLS_CC); > >- if (highlight_string(expr, &syntax_highlighter_ini, hicompiled_string_description TSRMLS_CC) == FAILURE) { >+ if (highlight_string_ex(expr, &syntax_highlighter_ini, hicompiled_string_description, numbered, mark_lines, line_prefix TSRMLS_CC) == FAILURE) { > efree(hicompiled_string_description); > RETURN_FALSE; > } > > >