1   package org.daisy.pipeline.css.sass.impl;
2   
3   import java.io.IOException;
4   import java.io.StringReader;
5   import java.util.Optional;
6   
7   import org.antlr.runtime.ANTLRReaderStream;
8   import org.antlr.runtime.CommonTokenStream;
9   import org.antlr.runtime.RecognitionException;
10  
11  import org.apache.commons.text.StringEscapeUtils;
12  
13  import org.w3c.dom.Element;
14  
15  class DoxygenComment extends Comment {
16  
17  	final Optional<String> varName;
18  	final Optional<String> type;
19  	final Optional<String> brief;
20  	final String body;
21  	final Optional<Element> typeDef;
22  
23  	DoxygenComment(String varName, String type, String brief, String body, Element typeDef, Comment comment)
24  			throws IllegalArgumentException {
25  
26  		super(comment.text, comment.column);
27  		if (type != null && typeDef != null)
28  			throw new IllegalArgumentException("Can not have both a type specified in a @var command, and a <type> command");
29  		this.varName = Optional.ofNullable(varName);
30  		this.type = Optional.ofNullable(type);
31  		this.brief = Optional.ofNullable(brief);
32  		this.body = processMarkdown(body);
33  		this.typeDef = Optional.ofNullable(typeDef);
34  	}
35  
36  	/**
37  	 * @throw IllegalArgumentException if the provided comment does not have the expected
38  	 *                                 formatting.
39  	 */
40  	static DoxygenComment of(Comment comment) throws IllegalArgumentException {
41  		try {
42  			// pre-processing
43  			if (!comment.text.startsWith("*"))
44  				throw new IllegalArgumentException("Not a Doxygen comment: " + comment);
45  			StringBuilder input = new StringBuilder();
46  			input.append("\n  ");
47  			for (int i = 0; i < comment.column; i++)
48  				input.append(" ");
49  			input.append(comment.text);
50  			input.append("\n");
51  			// parse
52  			DoxygenParser parser = new DoxygenParser(
53  				new CommonTokenStream(
54  					new DoxygenLexer(
55  						new ANTLRReaderStream(
56  							new StringReader(input.toString()))))).init(comment);
57  			return parser.doxygen_comment();
58  		} catch (RecognitionException|IllegalArgumentException e) {
59  			throw new IllegalArgumentException("Not a valid Doxygen comment: " + comment, e);
60  		} catch (IOException e) {
61  			throw new RuntimeException(e); // should not happen
62  		}
63  	}
64  
65  	/**
66  	 * Rendering markdown is currently the responsibility to the client. However for convenience we
67  	 * do a little bit of processing in the engine.
68  	 */
69  	private static String processMarkdown(String markdown) {
70  		// replace HTML character entities
71  		return StringEscapeUtils.unescapeHtml4(markdown);
72  	}
73  }