(* $Id: pxp_lex_content.src,v 1.8 2002/03/13 22:45:45 gerd Exp $
 * ----------------------------------------------------------------------
 *
 *)


{
  open Pxp_types
  open Pxp_lexer_types

#insert open_pxp_lex_aux_*.src
#insert open_pxp_lex_misc_*.src

}

#insert pxp_lex_defs_*.def

rule scan_content = parse
    "<?" pi_string "?>"
      { scan_pi (Lexing.lexeme lexbuf) scan_xml_pi, Content }
  | "<?"
      { raise (WF_error ("Illegal processing instruction")) }
  | "<!--"
      { Comment_begin dummy_entity, Content_comment }
  | '<' '/'? name
      (* One rule for Tag_beg and Tag_end saves transitions. *)
      { let l = Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf in
	if Lexing.lexeme_char lexbuf 1 = '/' then
	  Tag_end (Pxp_lexing.sub_lexeme lexbuf 2 (l-2), dummy_entity), 
	  Within_tag 
	else
	  Tag_beg (Pxp_lexing.sub_lexeme lexbuf 1 (l-1), dummy_entity), 
	  Within_tag 
      }
  | "<![CDATA[" cdata_string "]]>"
      { let l = Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf in
	Cdata (Pxp_lexing.sub_lexeme lexbuf 9 (l-12)), Content }
  | "<!"
      { raise (WF_error "Declaration either malformed or not allowed in this context") 
      }
  | "<"
      { raise (WF_error ("The left angle bracket '<' must be written as '&lt;'"))
      }
  | "&#" ascii_digit+ ";"
      { let l = Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf in
	CRef (int_of_string (Pxp_lexing.sub_lexeme lexbuf 2 (l-3))), Content }
  | "&#x" ascii_hexdigit+ ";"
      { let l = Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf in
	CRef (int_of_string ("0x" ^ Pxp_lexing.sub_lexeme lexbuf 3 (l-4))), Content }
  | "&" name ";"
      { let l = Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf in
	ERef (Pxp_lexing.sub_lexeme lexbuf 1 (l-2)), Content }
  | "&" 
      { raise (WF_error ("The ampersand '&' must be written as '&amp;'"))
      }

  (* LineEnd: Depending on whether we are reading from a primary source
   * (file) or from the replacement text of an internal entity, line endings
   * must be normalized (converted to \n) or not.
   * The entity classes do that. The yacc parser will never see LineEnd;
   * this token is always converted to the appropriate CharData token.
   *)

  | '\013' '\010'
      { tok_LineEndCRLF__Content }
  | '\013'
      { tok_LineEndCR__Content }
  | '\010'
      { tok_LineEndLF__Content }
  | eof
      { tok_Eof__Content }
  | "]]>" 
      { raise (WF_error ("The sequence ']]>' must be written as ']]&gt;'"))
      }
  | "]"
      { tok_CharDataRBRACKET__Content }
  | normal_character+
      { let s = Lexing.lexeme lexbuf in
	CharData s, Content 
      }
  | _
      { raise Netconversion.Malformed_code }


(* ======================================================================
 * History:
 * 
 * $Log: pxp_lex_content.src,v $
 * Revision 1.8  2002/03/13 22:45:45  gerd
 * 	Improved Pxp_lexing.
 *
 * Revision 1.7  2001/06/28 22:42:32  gerd
 * 	Comment tokens have entity_id
 *
 * Revision 1.6  2001/06/14 14:25:56  gerd
 * 	Removed insertion of pxp_lex_aux.src
 *
 * Revision 1.5  2000/10/01 19:51:33  gerd
 * 	Optimizations.
 *
 * Revision 1.4  2000/08/18 20:19:59  gerd
 * 	Comments return different comment tokens.
 *
 * Revision 1.3  2000/08/14 22:18:34  gerd
 * 	Bad_character_stream -> Netconversion.Malformed_code
 *
 * Revision 1.2  2000/05/29 23:53:12  gerd
 * 	Updated because Markup_* modules have been renamed to Pxp_*.
 *
 * Revision 1.1  2000/05/20 20:33:25  gerd
 * 	Initial revision.
 *
 * 
 *)
