anchor.diff:  %% finished (some dumb functions require to be ran from a particular dir)
   -spec tmp_cd(list(), fun()) -> term().
   tmp_cd (Dir, Fun) ->
  -
       {ok, OldDir} = file:get_cwd(),
  -
       ok = filelib:ensure_dir(Dir),
       ok = file:set_cwd(Dir),
  -
       try
           Result = Fun(),
           ok = file:set_cwd(OldDir),
  
positive.code:     {Type, _Attr, Content} = read_xml(Conf, File),
  
      TypeSpecsFile = filename:join([dest(Conf), ".xml", "specs_" ++ bname(File)]),
      TypeSpecs = case read_xml(Conf, TypeSpecsFile) of
          {error, _, _} -> [];
          {module, _, Specs} -> strip_whitespace(Specs)
      end,
  
      case lists:member(Type, buildable()) of
  
negative.code: atos ({Name, Val})             -> atom_to_list(Name) ++ "=\""++Val++"\"".
  
  %% convert ascii into html characters
  htmlchars (List) -> htmlchars(List, []).
  htmlchars ([], Acc) -> lists:flatten(lists:reverse(Acc));
  htmlchars ([$<  |Rest], Acc) -> htmlchars(Rest, ["&lt;"  |Acc]);
  htmlchars ([$>  |Rest], Acc) -> htmlchars(Rest, ["&gt;"  |Acc]);
  htmlchars ([$   |Rest], Acc) -> htmlchars(Rest, ["&nbsp;"|Acc]);
  htmlchars ([Else|Rest], Acc) -> htmlchars(Rest, [Else    |Acc]).
  
  %% @doc parse xml file against otp's dtd, need to cd into the
  %% source directory because files are addressed relative to it
  -spec read_xml(list(), list()) -> tuple().
  read_xml (_Conf, XmlFile) ->
      log("Reading XML for ~p\n", [XmlFile]),
      DocgenDir = code:priv_dir(erl_docgen),
      Opts = [ {fetch_path, [ filename:join(DocgenDir, "dtd")
                            , filename:join(DocgenDir, "dtd_html_entities") ]}
             , {encoding, "latin1"} ],
      {Xml, _}  = xmerl_scan:file(XmlFile, Opts),
      xmerl_lib:simplify_element(Xml).
  
  