📄 parser.java
字号:
( getTokenAhead(1).kind == END || (getTokenAhead(1).kind == WS && getTokenAhead(2).kind == END) ) ) { buffer.append(t.getImage().substring(0, t.getImage().length() - 2)); /* Skip the closing > that we have already checked. */ last = mustBe(t.kind); break comment; } else append(t); mustBe(t.kind); } hTag = new Token(start, last); handleComment(); } /** * Read a script. The text, returned without any changes, * is terminated only by the closing tag SCRIPT. */ protected void Script() throws ParseException { Token name; Token start = hTag = mustBe(BEGIN); optional(WS); name = mustBe(SCRIPT); optional(WS); restOfTag(false, name, start); buffer.setLength(0); script: while (!SCRIPT_CLOSE.matches(this)) { append(getNextToken()); } consume(SCRIPT_CLOSE); _handleText(); endTag(false); _handleEndTag(makeTagElement(name.getImage(), false)); } /** * Process SGML insertion that is not a comment. */ protected void Sgml() throws ParseException { if (COMMENT_OPEN.matches(this)) Comment(); else // skip till ">" { Token start = hTag = mustBe(BEGIN); optional(WS); mustBe(EXCLAMATION); buffer.setLength(0); read: while (true) { t = getNextToken(); if (t.kind == Constants.ENTITY) { resolveAndAppendEntity(t); } else if (t.kind == EOF) { error("unexpected eof", t); break read; } else if (t.kind == END) break read; else append(t); } try { parseMarkupDeclarations(buffer); } catch (IOException ex) { error("Unable to parse SGML insertion: '" + buffer + "'", new Token(start, t) ); } } } /** * Read a style definition. The text, returned without any changes, * is terminated only by the closing tag STYLE. */ protected void Style() throws ParseException { Token name; Token start = hTag = mustBe(BEGIN); optional(WS); name = mustBe(STYLE); optional(WS); restOfTag(false, name, start); buffer.setLength(0); style: while (!STYLE_CLOSE.matches(this)) { append(getNextToken()); } consume(STYLE_CLOSE); _handleText(); endTag(false); _handleEndTag(makeTagElement(name.getImage(), false)); } /** * Read a html tag. */ protected void Tag() throws ParseException { mark(true); boolean closing = false; Token name; Token start = hTag = mustBe(BEGIN); optional(WS); name = getNextToken(); optional(WS); if (name.kind == SLASH) { closing = true; name = getNextToken(); } restOfTag(closing, name, start); } /** * A hook, for operations, preceeding call to handleText. * Handle text in a string buffer. * In non - preformatted mode, all line breaks immediately following the * start tag and immediately before an end tag is discarded, * \r, \n and \t are replaced by spaces, multiple space are replaced * by the single one and the result is moved into array, * passing it to handleText(). */ protected void _handleText() { char[] text; if (preformatted > 0) text = textProcessor.preprocessPreformatted(buffer); else text = textProcessor.preprocess(buffer); if (text != null && text.length > 0) { TagElement pcdata = new TagElement(dtd.getElement("#pcdata")); attributes = htmlAttributeSet.EMPTY_HTML_ATTRIBUTE_SET; _handleEmptyTag(pcdata); handleText(text); if (titleOpen) title.append(text); } } /** * Add the image of this token to the buffer. * @param t A token to append. */ protected final void append(Token t) { if (t.kind != EOF) t.appendTo(buffer); } /** * Consume pattern that must match. * @param p A pattern to consume. */ protected final void consume(pattern p) { node n; for (int i = 0; i < p.nodes.length; i++) { n = p.nodes [ i ]; if (n.optional) optional(n.kind); else mustBe(n.kind); } } /** * The method is called when the HTML end (closing) tag is found or if * the parser concludes that the one should be present in the * current position. The method is called immediatly * before calling the handleEndTag(). * @param omitted True if the tag is no actually present in the document, * but is supposed by the parser (like </html> at the end of the * document). */ protected void endTag(boolean omitted) { } /** * Handle HTML comment. The default method returns without action. * @param comment */ protected void handleComment(char[] comment) { } /** * This is additionally called in when the HTML content terminates * without closing the HTML comment. This can only happen if the * HTML document contains errors (for example, the closing --;gt is * missing. */ protected void handleEOFInComment() { error("Unclosed comment"); } /** * Handle the tag with no content, like <br>. The method is * called for the elements that, in accordance with the current DTD, * has an empty content. * @param The tag being handled. * @throws javax.swing.text.ChangedCharSetException */ protected void handleEmptyTag(TagElement tag) throws javax.swing.text.ChangedCharSetException { } /** * The method is called when the HTML closing tag ((like </table>) * is found or if the parser concludes that the one should be present * in the current position. * @param The tag */ protected void handleEndTag(TagElement tag) { } /* Handle error that has occured in the given line. */ protected void handleError(int line, String message) { } /** * The method is called when the HTML opening tag ((like <table>) * is found or if the parser concludes that the one should be present * in the current position. * @param The tag */ protected void handleStartTag(TagElement tag) { } /** * Handle the text section. * <p> For non-preformatted section, the parser replaces * \t, \r and \n by spaces and then multiple spaces * by a single space. Additionaly, all whitespace around * tags is discarded. * </p> * <p> For pre-formatted text (inside TEXAREA and PRE), the parser preserves * all tabs and spaces, but removes <b>one</b> bounding \r, \n or \r\n, * if it is present. Additionally, it replaces each occurence of \r or \r\n * by a single \n.</p> * * @param text A section text. */ protected void handleText(char[] text) { } /** * Handle HTML <title> tag. This method is invoked when * both title starting and closing tags are already behind. * The passed argument contains the concatenation of all * title text sections. * @param The title text. */ protected void handleTitle(char[] title) { } /** * Constructs the tag from the given element. In this implementation, * this is defined, but never called. * @return the tag */ protected TagElement makeTag(Element element) { return makeTag(element, false); } /** * Constructs the tag from the given element. * @param the tag base {@link javax.swing.text.html.parser.Element} * @param isSupposed true if the tag is not actually present in the * html input, but the parser supposes that it should to occur in * the current location. * @return the tag */ protected TagElement makeTag(Element element, boolean isSupposed) { return new TagElement(element, isSupposed); } /** * This is called when the tag, representing the given element, * occurs first time in the document. * @param element */ protected void markFirstTime(Element element) { } /** * Consume the token that was checked before and hence MUST be present. * @param kind The kind of token to consume. */ protected Token mustBe(int kind) { if (getTokenAhead().kind == kind) return getNextToken(); else { String ei = ""; if (kind < 1000) ei = " ('" + (char) kind + "') "; throw new AssertionError("The token of kind " + kind + ei + " MUST be here," ); } } /** * Handle attribute without value. The default method uses * the only allowed attribute value from DTD. * If the attribute is unknown or allows several values, * the HTML.NULL_ATTRIBUTE_VALUE is used. The attribute with * this value is added to the attribute set. * @param element The name of element. * @param attribute The name of attribute without value. */ protected void noValueAttribute(String element, String attribute) { Object value = HTML.NULL_ATTRIBUTE_VALUE; Element e = (Element) dtd.elementHash.get(element.toLowerCase()); if (e != null) { AttributeList attr = e.getAttribute(attribute); if (attr != null) { Vector values = attr.values; if (values != null && values.size() == 1) value = values.get(0); } } attributes.addAttribute(attribute, value); } /** * Consume the optional token, if present. * @param kind The kind of token to consume. */ protected Token optional(int kind) { if (getTokenAhead().kind == kind) return getNextToken(); else return null; } /** Parse the html document. */ protected void parseDocument() throws ParseException { while (getTokenAhead().kind != EOF) { advanced = false; if (TAG.matches(this)) Tag(); else if (COMMENT_OPEN.matches(this)) Comment(); else if (STYLE_OPEN.matches(this)) Style(); else if (SCRIPT_OPEN.matches(this)) Script(); else if (SGML.matches(this)) Sgml(); else CDATA(true); // Surely HTML error, treat as a text. if (!advanced) { Token wrong = getNextToken(); error("unexpected '" + wrong.getImage() + "'", wrong); buffer.setLength(0); buffer.append(wrong.getImage()); _handleText(); } } } /** * Read the element attributes, adding them into attribute set. * @param element The element name (needed to access attribute * information in dtd). */ protected void readAttributes(String element) { Token name; Token value; Token next; String attrValue; attributes = new htmlAttributeSet(); optional(WS); attributeReading: while (getTokenAhead().kind == NUMTOKEN) { name = getNextToken(); optional(WS); next = getTokenAhead(); if (next.kind == EQ) { mustBe(EQ); optional(WS); next = getNextToken(); switch (next.kind) { case QUOT : // read "quoted" attribute. buffer.setLength(0); readTillTokenE(QUOT); attrValue = buffer.toString(); break; case AP : // read 'quoted' attribute. buffer.setLength(0); readTillTokenE(AP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -