Add DemoMarker() function to formalize access for other demos than imgui_demo.cpp (#9261, #3689)
diff --git a/imgui.cpp b/imgui.cpp
index e9dcd67..fddbff7 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -4293,6 +4293,7 @@
     SettingsLoaded = false;
     SettingsDirtyTimer = 0.0f;
     HookIdNext = 0;
+    DemoMarkerCallback = NULL;
 
     memset(LocalizationTable, 0, sizeof(LocalizationTable));
 
@@ -5062,6 +5063,13 @@
     return (*GImAllocatorFreeFunc)(ptr, GImAllocatorUserData);
 }
 
+void ImGui::DemoMarker(const char* file, int line, const char* section)
+{
+    ImGuiContext& g = *GImGui;
+    if (g.DemoMarkerCallback != NULL)
+        g.DemoMarkerCallback(file, line, section);
+}
+
 // We record the number of allocation in recent frames, as a way to audit/sanitize our guiding principles of "no allocations on idle/repeating frames"
 void ImGui::DebugAllocHook(ImGuiDebugAllocInfo* info, int frame_count, void* ptr, size_t size)
 {
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index f16cad0..130e5f7 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -283,12 +283,10 @@
 }
 
 // Helper to wire demo markers located in code to an interactive browser (e.g. imgui_manual)
-typedef void (*ImGuiDemoMarkerCallback)(const char* file, int line, const char* section, void* user_data);
-extern ImGuiDemoMarkerCallback      GImGuiDemoMarkerCallback;
-extern void*                        GImGuiDemoMarkerCallbackUserData;
-ImGuiDemoMarkerCallback             GImGuiDemoMarkerCallback = NULL;
-void*                               GImGuiDemoMarkerCallbackUserData = NULL;
-#define IMGUI_DEMO_MARKER(section)  do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback("imgui_demo.cpp", __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0)
+#if IMGUI_VERSION_NUM >= 19263
+namespace ImGui { extern IMGUI_API void DemoMarker(const char* file, int line, const char* section); };
+#define IMGUI_DEMO_MARKER(section)  do { ImGui::DemoMarker("imgui_demo.cpp", __LINE__, section); } while (0)
+#endif
 
 // Sneakily forward declare functions which aren't worth putting in public API yet
 namespace ImGui
diff --git a/imgui_internal.h b/imgui_internal.h
index f91461e..78457fb 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -2182,6 +2182,8 @@
     ImGuiContextHook()          { memset((void*)this, 0, sizeof(*this)); }
 };
 
+typedef void (*ImGuiDemoMarkerCallback)(const char* file, int line, const char* section);
+
 //-----------------------------------------------------------------------------
 // [SECTION] ImGuiContext (main Dear ImGui context)
 //-----------------------------------------------------------------------------
@@ -2504,8 +2506,11 @@
     ImVector<ImGuiSettingsHandler>      SettingsHandlers;       // List of .ini settings handlers
     ImChunkStream<ImGuiWindowSettings>  SettingsWindows;        // ImGuiWindow .ini settings entries
     ImChunkStream<ImGuiTableSettings>   SettingsTables;         // ImGuiTable .ini settings entries
+
+    // Hooks
     ImVector<ImGuiContextHook>          Hooks;                  // Hooks for extensions (e.g. test engine)
     ImGuiID                             HookIdNext;             // Next available HookId
+    ImGuiDemoMarkerCallback             DemoMarkerCallback;
 
     // Localization
     const char*             LocalizationTable[ImGuiLocKey_COUNT];
@@ -3711,6 +3716,9 @@
     IMGUI_API bool          BeginErrorTooltip();
     IMGUI_API void          EndErrorTooltip();
 
+    // Demo Doc Marker for e.g. imgui_manual
+    IMGUI_API void          DemoMarker(const char* file, int line, const char* section);
+
     // Debug Tools
     IMGUI_API void          DebugAllocHook(ImGuiDebugAllocInfo* info, int frame_count, void* ptr, size_t size); // size >= 0 : alloc, size = -1 : free
     IMGUI_API void          DebugDrawCursorPos(ImU32 col = IM_COL32(255, 0, 0, 255));