mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	xmldocs: Add support for an <example> tag in the Asterisk XML Documentation
This patch adds support for an <example /> tag in the XML documentation schema.
For CLI help, this doesn't change the formatting too much:
 - Preceeding white space is removed
 - Unlike with para elements, new lines are preserved
However, having an <example /> tag in the XML schema allows for the wiki
documentation generation script to surround the documentation with {code} or
{noformat} tags, generating much better content for the wiki - and allowing us
to put dialplan examples (and other code snippets, if desired) into the
documentation for an application/function/AMI command/etc.
Review: https://reviewboard.asterisk.org/r/3807/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419822 65c4cc65-6c06-0410-ace0-fbb531ad65f3
			
			
This commit is contained in:
		| @@ -92,7 +92,7 @@ | ||||
|   <!ELEMENT configOptionToEnum (configOption|xi:include)*> | ||||
|   <!ATTLIST configOptionToEnum prefix CDATA ""> | ||||
|  | ||||
|   <!ELEMENT description (para|note|warning|variablelist|enumlist|info|xi:include)*> | ||||
|   <!ELEMENT description (para|note|warning|variablelist|enumlist|info|example|xi:include)*> | ||||
|  | ||||
|   <!ELEMENT parameter (optionlist|enumlist|argument|para|note|warning|parameter|info|xi:include)*> | ||||
|   <!ATTLIST parameter name CDATA ""> | ||||
| @@ -129,6 +129,10 @@ | ||||
|   <!ELEMENT directory (#PCDATA)> | ||||
|   <!ELEMENT astcli (#PCDATA)> | ||||
|  | ||||
|   <!ELEMENT example (#PCDATA|xi:include)*> | ||||
|   <!ATTLIST example title CDATA ""> | ||||
|   <!ATTLIST example language CDATA "" > | ||||
|  | ||||
|   <!ELEMENT note (para+|xi:include*)> | ||||
|   <!ELEMENT warning (para+|xi:include*)> | ||||
|  | ||||
|   | ||||
| @@ -66,13 +66,25 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| 			<para>target_extra: Defaults to 40ms</para> | ||||
| 			<para>This option only affects the adaptive jitterbuffer. It represents the amount time in milliseconds by which the new jitter buffer will pad its size.</para> | ||||
| 			<para> </para> | ||||
| 			<para>Examples:</para> | ||||
| 			<para>exten => 1,1,Set(JITTERBUFFER(fixed)=default);Fixed with defaults. </para> | ||||
| 			<para>exten => 1,1,Set(JITTERBUFFER(fixed)=200);Fixed with max size 200ms, default resync threshold and target extra. </para> | ||||
| 			<para>exten => 1,1,Set(JITTERBUFFER(fixed)=200,1500);Fixed with max size 200ms resync threshold 1500. </para> | ||||
| 			<para>exten => 1,1,Set(JITTERBUFFER(adaptive)=default);Adaptive with defaults. </para> | ||||
| 			<para>exten => 1,1,Set(JITTERBUFFER(adaptive)=200,,60);Adaptive with max size 200ms, default resync threshold and 40ms target extra. </para> | ||||
| 			<para>exten => 1,n,Set(JITTERBUFFER(disabled)=);Remove previously applied jitterbuffer </para> | ||||
| 			<example title="Fixed with defaults" language="text"> | ||||
| 			exten => 1,1,Set(JITTERBUFFER(fixed)=default) | ||||
| 			</example> | ||||
| 			<example title="Fixed with 200ms max size" language="text"> | ||||
| 			exten => 1,1,Set(JITTERBUFFER(fixed)=200) | ||||
| 			</example> | ||||
| 			<example title="Fixed with 200ms max size, resync threshold 1500" language="text"> | ||||
| 			exten => 1,1,Set(JITTERBUFFER(fixed)=200,1500) | ||||
| 			</example> | ||||
| 			<example title="Adaptive with defaults" language="text"> | ||||
| 			exten => 1,1,Set(JITTERBUFFER(adaptive)=default) | ||||
| 			</example> | ||||
| 			<example title="Adaptive with 200ms max size, 60ms target extra" language="text"> | ||||
| 			exten => 1,1,Set(JITTERBUFFER(adaptive)=200,,60) | ||||
| 			</example> | ||||
| 			<example title="Set a fixed jitterbuffer with defaults; then remove it" language="text"> | ||||
| 			exten => 1,1,Set(JITTERBUFFER(fixed)=default) | ||||
| 			exten => 1,n,Set(JITTERBUFFER(disabled)=) | ||||
| 			</example> | ||||
| 			<note><para>If a channel specifies a jitterbuffer due to channel driver configuration and | ||||
| 			the JITTERBUFFER function has set a jitterbuffer for that channel, the jitterbuffer set by | ||||
| 			the JITTERBUFFER function will take priority and the jitterbuffer set by the channel | ||||
|   | ||||
| @@ -104,7 +104,9 @@ static const struct strcolorized_tags { | ||||
|  | ||||
| 	/* Special tags */ | ||||
| 	{ "", "", COLOR_YELLOW, "<note>",   "</note>" }, | ||||
| 	{ "", "", COLOR_RED,   "<warning>", "</warning>" } | ||||
| 	{ "", "", COLOR_RED,   "<warning>", "</warning>" }, | ||||
| 	{ "", "", COLOR_WHITE, "<example>", "</example>" }, | ||||
| 	{ "", "", COLOR_GRAY, "<exampletext>", "</exampletext>"}, | ||||
| }; | ||||
|  | ||||
| static const struct strspecial_tags { | ||||
| @@ -113,7 +115,8 @@ static const struct strspecial_tags { | ||||
| 	const char *end;		/*!< Print this at the end. */ | ||||
| } special_tags[] = { | ||||
| 	{ "note",    "<note>NOTE:</note> ",             "" }, | ||||
| 	{ "warning", "<warning>WARNING!!!:</warning> ", "" } | ||||
| 	{ "warning", "<warning>WARNING!!!:</warning> ", "" }, | ||||
| 	{ "example", "<example>Example:</example> ", "" }, | ||||
| }; | ||||
|  | ||||
| /*! | ||||
| @@ -453,8 +456,9 @@ char *ast_xmldoc_printable(const char *bwinput, int withcolors) | ||||
|  * \param text String to be cleaned up. | ||||
|  * \param output buffer (not already allocated). | ||||
|  * \param lastspaces Remove last spaces in the string. | ||||
|  * \param maintain_newlines Preserve new line characters (\n \r) discovered in the string | ||||
|  */ | ||||
| static void xmldoc_string_cleanup(const char *text, struct ast_str **output, int lastspaces) | ||||
| static void xmldoc_string_cleanup(const char *text, struct ast_str **output, int lastspaces, int maintain_newlines) | ||||
| { | ||||
| 	int i; | ||||
| 	size_t textlen; | ||||
| @@ -474,6 +478,9 @@ static void xmldoc_string_cleanup(const char *text, struct ast_str **output, int | ||||
|  | ||||
| 	for (i = 0; i < textlen; i++) { | ||||
| 		if (text[i] == '\n' || text[i] == '\r') { | ||||
| 			if (maintain_newlines) { | ||||
| 				ast_str_append(output, 0, "%c", text[i]); | ||||
| 			} | ||||
| 			/* remove spaces/tabs/\n after a \n. */ | ||||
| 			while (text[i + 1] == '\t' || text[i + 1] == '\r' || text[i + 1] == '\n') { | ||||
| 				i++; | ||||
| @@ -1417,7 +1424,7 @@ static int xmldoc_parse_para(struct ast_xml_node *node, const char *tabs, const | ||||
| 		tmptext = ast_xml_get_text(tmp); | ||||
| 		if (tmptext) { | ||||
| 			/* Strip \n etc. */ | ||||
| 			xmldoc_string_cleanup(tmptext, &tmpstr, 0); | ||||
| 			xmldoc_string_cleanup(tmptext, &tmpstr, 0, 0); | ||||
| 			ast_xml_free_text(tmptext); | ||||
| 			if (tmpstr) { | ||||
| 				if (strcasecmp(ast_xml_node_get_name(tmp), "text")) { | ||||
| @@ -1437,6 +1444,57 @@ static int xmldoc_parse_para(struct ast_xml_node *node, const char *tabs, const | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Parse an <example> node. | ||||
|  * \since 13.0.0 | ||||
|  * | ||||
|  * \param fixnode An ast xml pointer to the <example> node. | ||||
|  * \param buffer The output buffer. | ||||
|  * | ||||
|  * \retval 0 if no example node is parsed. | ||||
|  * \retval 1 if an example node is parsed. | ||||
|  */ | ||||
| static int xmldoc_parse_example(struct ast_xml_node *fixnode, struct ast_str **buffer) | ||||
| { | ||||
| 	struct ast_xml_node *node = fixnode; | ||||
| 	const char *tmptext; | ||||
| 	const char *title; | ||||
| 	struct ast_str *stripped_text; | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	if (!node || !ast_xml_node_get_children(node)) { | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	if (strcasecmp(ast_xml_node_get_name(node), "example")) { | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	ret = 1; | ||||
|  | ||||
| 	title = ast_xml_get_attribute(node, "title"); | ||||
| 	if (title) { | ||||
| 		ast_str_append(buffer, 0, "%s", title); | ||||
| 		ast_xml_free_attr(title); | ||||
| 	} | ||||
| 	ast_str_append(buffer, 0, "\n"); | ||||
|  | ||||
| 	for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) { | ||||
| 		tmptext = ast_xml_get_text(node); | ||||
| 		if (tmptext) { | ||||
| 			xmldoc_string_cleanup(tmptext, &stripped_text, 0, 1); | ||||
| 			if (stripped_text) { | ||||
| 				ast_str_append(buffer, 0, "<exampletext>%s</exampletext>\n", ast_str_buffer(stripped_text)); | ||||
| 				ast_xml_free_text(tmptext); | ||||
| 				ast_free(stripped_text); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| /*! | ||||
|  * \internal | ||||
|  * \brief Parse special elements defined in 'struct special_tags' special elements must have a <para> element inside them. | ||||
| @@ -1472,6 +1530,11 @@ static int xmldoc_parse_specialtags(struct ast_xml_node *fixnode, const char *ta | ||||
| 			ast_str_append(buffer, 0, "%s%s", tabs, special_tags[i].init); | ||||
| 		} | ||||
|  | ||||
| 		if (xmldoc_parse_example(node, buffer)) { | ||||
| 			ret = 1; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		/* parse <para> elements inside special tags. */ | ||||
| 		for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) { | ||||
| 			/* first <para> just print it without tabs at the begining. */ | ||||
| @@ -1585,7 +1648,7 @@ static int xmldoc_parse_variable(struct ast_xml_node *node, const char *tabs, st | ||||
| 		/* Check inside this node for any explanation about its meaning. */ | ||||
| 		if (tmptext) { | ||||
| 			/* Cleanup text. */ | ||||
| 			xmldoc_string_cleanup(tmptext, &cleanstr, 1); | ||||
| 			xmldoc_string_cleanup(tmptext, &cleanstr, 1, 0); | ||||
| 			ast_xml_free_text(tmptext); | ||||
| 			if (cleanstr && ast_str_strlen(cleanstr) > 0) { | ||||
| 				ast_str_append(buffer, 0, ":%s", ast_str_buffer(cleanstr)); | ||||
| @@ -2147,18 +2210,24 @@ static struct ast_str *xmldoc_get_formatted(struct ast_xml_node *node, int raw_o | ||||
| 		/* xmldoc_string_cleanup will allocate the ret object */ | ||||
| 		notcleanret = ast_xml_get_text(node); | ||||
| 		tmpstr = notcleanret; | ||||
| 		xmldoc_string_cleanup(ast_skip_blanks(notcleanret), &ret, 0); | ||||
| 		xmldoc_string_cleanup(ast_skip_blanks(notcleanret), &ret, 0, 0); | ||||
| 		ast_xml_free_text(tmpstr); | ||||
| 	} else { | ||||
| 		ret = ast_str_create(128); | ||||
| 		for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) { | ||||
| 			/* if found, parse a <para> element. */ | ||||
| 			/* if found, parse children elements. */ | ||||
| 			if (xmldoc_parse_common_elements(tmp, "", "\n", &ret)) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			/* if found, parse a <variablelist> element. */ | ||||
| 			xmldoc_parse_variablelist(tmp, "", &ret); | ||||
| 			xmldoc_parse_enumlist(tmp, "    ", &ret); | ||||
| 			if (xmldoc_parse_variablelist(tmp, "", &ret)) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (xmldoc_parse_enumlist(tmp, "    ", &ret)) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (xmldoc_parse_specialtags(tmp, "", "", &ret)) { | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 		/* remove last '\n' */ | ||||
| 		/* XXX Don't modify ast_str internals manually */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user