anchor.diff:              halt(1)
       end.
   
  -validate_type(_Line, "seeerl","erlref") ->
  -    ok;
  -validate_type(_Line, "seemfa","erlref") ->
  -    ok;
  -validate_type(_Line, "seetype","erlref") ->
  -    ok;
  -validate_type(_Line, "seeguide","chapter") ->
  -    ok;
  -validate_type(_Line, "seeguide","index") ->
  -    ok;
  -validate_type(_Line, "seefile","fileref") ->
  -    ok;
  -validate_type(_Line, "seeapp","appref") ->
  -    ok;
  -validate_type(_Line, "seeapp","index") ->
  -    ok;
  -validate_type(_Line, "seecom","comref") ->
  -    ok;
  -validate_type(_Line, "seecref","cref") ->
  -    ok;
  -validate_type(Line, From, To) ->
  +validate_type(_Line, "seeerl",#{ type := "erlref" }) ->
  +    ok;
  +validate_type(_Line, "seemfa", #{ type := "erlref"}) ->
  +    ok;
  +validate_type(_Line, "seetype", #{ type := "erlref"}) ->
  +    ok;
  +validate_type(_Line, "seeguide", #{ type := "chapter"}) ->
  +    ok;
  +validate_type(_Line, "seeguide", #{ type := "index"}) ->
  +    ok;
  +validate_type(_Line, "seefile", #{ type := "fileref"}) ->
  +    ok;
  +validate_type(_Line, "seeapp", #{ type := "appref"}) ->
  +    ok;
  +validate_type(_Line, "seeapp", #{ type := "index"}) ->
  +    ok;
  +validate_type(_Line, "seecom", #{ type := "comref"}) ->
  +    ok;
  +validate_type(_Line, "seecref", #{ type := "cref"}) ->
  +    ok;
  +validate_type(Line, From, #{ type := To }) ->
       fail(Line, "Invalid <~s> pointing to a <~s> file",[From,To]).
  +
  +validate_marker(_Line, {_,_,[]}, _) ->
  +    ok;
  +validate_marker(Line, {_,_,Marker}, #{ filename := {App,Name}, markers := Markers }) ->
  +    case lists:any(fun(M) -> string:equal(Marker,M,true) end,Markers) of
  +        true ->
  +            ok;
  +        false ->
  +            StringMarkers = lists:join(", ",Markers),
  +            fail(Line, "Could not find marker <~s> in ~s:~s~n  Available: ~s",
  +                 [Marker,App,Name,StringMarkers])
  +    end.
   
   path2app(Path) ->
       case lists:reverse(string:lexemes(Path,"/")) of
  
positive.code:     maps:put(filename,{path2app(Path),ModuleName}, State);
  
  %% Get the see* attributes
  event({startElement, "see" ++ _ = What, Attr}, Line, State, _) ->
      maps:put(What, [{Line,Attr}|maps:get(What, State, [])], State);
  
  %% Get all the marker attributes
  event({startElement, "marker", [{"id",Id}]}, Line, State, _) ->
      maps:put(marker, [{Line,Id}|maps:get(marker, State, [])], State);
  
  %% Get all func->name markers in erlref
  event({startElement, "name", Attr}, _Line, #{ type := "erlref" } = State, ["func" | _]) ->
      case {proplists:get_value("name",Attr),proplists:get_value("arity",Attr)} of
          {undefined,undefined} ->
              %% We parse the function name from the content,
              %% so have to capture characters
              error = maps:find(characters,State),
              maps:put(characters,[],State);
          {Func,Arity} when Func =/= undefined, Arity =/= undefined ->
              maps:put(funcs, [{Func,Arity}|maps:get(funcs,State,[])], State)
      end;
  event({endElement,"name"}, _Line, #{ characters := Chars} = State, ["func"|_]) ->
      FAs = docgen_xml_to_chunk:func_to_tuple(Chars),
  
negative.code:     {App,Mod,Marker}.
  
  read_link(_Line, {_App,"index",_}, _Cache) ->
      #{type => "index", markers => [] };
  read_link(Line, {App,Mod,_}, Cache) ->
      case maps:find({App,Mod}, Cache) of
          {ok, Info } ->
              Info;
          error ->
              %% fail(Line, "Could not find: ~p~p~n~p~n",
              %%   [App,Mod,lists:sort(maps:keys(Cache))]),
  