diff options
Diffstat (limited to 'lib/erl_docgen')
-rw-r--r-- | lib/erl_docgen/priv/xsl/db_html.xsl | 69 | ||||
-rw-r--r-- | lib/erl_docgen/src/docgen_otp_specs.erl | 32 |
2 files changed, 89 insertions, 12 deletions
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl index 75399992f2..fe6c7d3c28 100644 --- a/lib/erl_docgen/priv/xsl/db_html.xsl +++ b/lib/erl_docgen/priv/xsl/db_html.xsl @@ -24,11 +24,76 @@ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" - extension-element-prefixes="exsl" + xmlns:func="http://exslt.org/functions" + xmlns:erl="http://erlang.org" + extension-element-prefixes="exsl func" xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> <xsl:include href="db_html_params.xsl"/> + <func:function name="erl:flip_first_char"> + <xsl:param name="in"/> + + <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> + <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/> + + <xsl:variable name="first-char" select="substring($in, 1, 1)"/> + + <xsl:variable name="result"> + <xsl:choose> + <xsl:when test="contains($uppercase, $first-char)"> + <xsl:value-of select="concat(translate($first-char, $uppercase, $lowercase), substring($in, 2))"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="concat(translate($first-char, $lowercase, $uppercase), substring($in, 2))"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <func:result select="$result"/> + </func:function> + + <!-- Used from template menu.funcs to sort a module's functions for the lefthand index list, + from the module's .xml file. Returns a value on which to sort the entity in question + (a <name> element). + + Some functions are listed with the name as an attribute, as in string.xml: + <name name="join" arity="2"/> + + Others use the element value for the name, as in gen_server.xml: + <name>start_link(Module, Args, Options) -> Result</name> + + Additionally, callbacks may be included, as in gen_server.xml: + <name>Module:handle_call(Request, From, State) -> Result</name> + + So first, get the name from either the attribute or the element value. + Then, reverse the case of the first character. This is because xsltproc, used for processing, + orders uppercase before lowercase (even when the 'case-order="lower-first"' option + is given). But we want the Module callback functions listed after a module's regular + functions, as they are now. This doesn't affect the actual value used in the output, but + just the value used as a sort key. To then ensure that uppercase is indeed sorted before + lower, as we now want it to be, the 'case-order="upper-first"' option is used. + + This processing only affect the lefthand index list- the body of the doc page is not + affected. + --> + <func:function name="erl:get_sort_field"> + <xsl:param name="elem"/> + + <xsl:variable name="base"> + <xsl:choose> + <xsl:when test="string-length($elem/@name) > 0"> + <xsl:value-of select="$elem/@name"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$elem"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <func:result select="erl:flip_first_char($base)"/> + </func:function> + <!-- Start of Dialyzer type/spec tags. See also the templates matching "name" and "seealso" as well as the template "menu.funcs" @@ -1486,6 +1551,8 @@ <xsl:param name="cval"/> <xsl:for-each select="$entries"> + <!-- Sort on function name, so the index list in lefthand frame is ordered. --> + <xsl:sort select="erl:get_sort_field(.)" data-type="text" case-order="upper-first"/> <xsl:choose> <xsl:when test="ancestor::cref"> diff --git a/lib/erl_docgen/src/docgen_otp_specs.erl b/lib/erl_docgen/src/docgen_otp_specs.erl index e154323f07..6c41147e27 100644 --- a/lib/erl_docgen/src/docgen_otp_specs.erl +++ b/lib/erl_docgen/src/docgen_otp_specs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2015. All Rights Reserved. +%% Copyright Ericsson AB 1996-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -389,10 +389,10 @@ t_type([#xmlElement{name = list, content = Es}]) -> t_list(Es); t_type([#xmlElement{name = nonempty_list, content = Es}]) -> t_nonempty_list(Es); -t_type([#xmlElement{name = tuple, content = Es}]) -> - t_tuple(Es); t_type([#xmlElement{name = map, content = Es}]) -> t_map(Es); +t_type([#xmlElement{name = tuple, content = Es}]) -> + t_tuple(Es); t_type([#xmlElement{name = 'fun', content = Es}]) -> ["fun("] ++ t_fun(Es) ++ [")"]; t_type([E = #xmlElement{name = record, content = Es}]) -> @@ -435,16 +435,22 @@ t_nonempty_list(Es) -> t_tuple(Es) -> ["{"] ++ seq(fun t_utype_elem/1, Es, ["}"]). +t_fun(Es) -> + ["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es), + [") -> "] ++ t_utype(get_elem(type, Es))). + t_map(Es) -> Fs = get_elem(map_field, Es), ["#{"] ++ seq(fun t_map_field/1, Fs, ["}"]). -t_map_field(#xmlElement{content = [K,V]}) -> - [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)]. - -t_fun(Es) -> - ["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es), - [") -> "] ++ t_utype(get_elem(type, Es))). +t_map_field(#xmlElement{content = [K,V]}=E) -> + KElem = t_utype_elem(K), + VElem = t_utype_elem(V), + AS = case get_attrval(assoc_type, E) of + "assoc" -> " => "; + "exact" -> " := " + end, + KElem ++ [AS] ++ VElem. t_record(E, Es) -> Name = ["#"] ++ t_type(get_elem(atom, Es)), @@ -618,8 +624,12 @@ ot_tuple(Es) -> ot_map(Es) -> {type,0,map,[ot_map_field(E) || E <- get_elem(map_field,Es)]}. -ot_map_field(#xmlElement{content=[K,V]}) -> - {type,0,map_field_assoc,[ot_utype_elem(K),ot_utype_elem(V)]}. +ot_map_field(#xmlElement{content=[K,V]}=E) -> + A = case get_attrval(assoc_type, E) of + "assoc" -> map_field_assoc; + "exact" -> map_field_exact + end, + {type,0,A,[ot_utype_elem(K), ot_utype_elem(V)]}. ot_fun(Es) -> Range = ot_utype(get_elem(type, Es)), |