Skip to content

Commit 3dd9868

Browse files
AlexThivGitHub Enterprise
authored andcommitted
Tutorial framework Update
Fix list indentation to use 2 space instead of 4 when reading the md file Fix anchor logic to refer to the page if it's deeper than the first level anchors Improve Inspector functionality (Browse button, reload page button) Update dynamic reference handling to handle null ref and better UI naming Update telemetry and add new events Fix null ref when pages don't exists Update page generation logic Update package version
1 parent a1840d2 commit 3dd9868

20 files changed

Lines changed: 353 additions & 100 deletions

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public class TutorialConfig : ScriptableObject
2323
public Texture2D NavHeaderImage => m_navHeaderImage;
2424
public Banner BannerConfig => m_bannerConfig;
2525

26+
public string TelemetryContext => Telemetry.TUTORIAL_HUB_CONTEXT;
27+
2628
[Serializable]
2729
public class Banner
2830
{

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialConfigEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public override void OnInspectorGUI()
2020
#endif
2121
if (GUILayout.Button("Open Tutorial Hub"))
2222
{
23-
Telemetry.OnOpenTutorialButton(context.Name);
23+
Telemetry.OnOpenTutorialButton(context.TelemetryContext, context.Name, context.name);
2424
TutorialFrameworkHub.ShowWindow();
2525
}
2626
EditorGUILayout.Space();

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialFeedbackContextEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public override void OnInspectorGUI()
1919
#endif
2020
if (GUILayout.Button("Open Tutorial Hub"))
2121
{
22-
Telemetry.OnOpenTutorialButton($"CONFIG::{context.Title}");
22+
Telemetry.OnOpenTutorialButton(context.TelemetryContext, context.ProjectName, context.Title);
2323
context.ShowDefaultWindow();
2424
}
2525
EditorGUILayout.Space();

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialMarkdownContext.cs

Lines changed: 115 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Meta.Tutorial.Framework.Hub.Pages;
88
using Meta.Tutorial.Framework.Hub.Pages.Markdown;
99
using Meta.Tutorial.Framework.Hub.Parsing;
10+
using Meta.Tutorial.Framework.Hub.Utilities;
1011
using Meta.Tutorial.Framework.Windows;
1112
using UnityEngine;
1213

@@ -30,6 +31,7 @@ public class PageConfig
3031
public string SectionTitleAsAnchorId => Regex.Replace(SectionTitle.Replace(" ", "-"), @"[^a-zA-Z0-9\-]", string.Empty).ToLower();
3132
}
3233

34+
[MDFilePath]
3335
[SerializeField] private string m_markdownPath = "./README.md";
3436
[SerializeField, Tooltip("When all content is a level 1 because the header is level 0 we can bring them to level 0")]
3537
private bool m_reduceTitleLevelBy1 = false;
@@ -84,6 +86,25 @@ private bool AnyAsChildren
8486
}
8587
}
8688

89+
private bool AnyInContext
90+
{
91+
get
92+
{
93+
if (m_pageConfigs == null || m_pageConfigs.Count == 0)
94+
{
95+
return false;
96+
}
97+
foreach (var pageConfig in m_pageConfigs)
98+
{
99+
if (pageConfig.ShowSectionInContext)
100+
{
101+
return true;
102+
}
103+
}
104+
return false;
105+
}
106+
}
107+
87108
public IReadOnlyList<PageConfig> PageConfigs => m_pageConfigs;
88109

89110
private string ReadTextFromFile(string path)
@@ -92,99 +113,123 @@ private string ReadTextFromFile(string path)
92113
public override PageReference[] CreatePageReferences(bool forceCreate = false)
93114
{
94115
var rootPath = System.IO.Path.GetDirectoryName(m_markdownPath) + '/';
116+
var allPages = new List<PageReference>();
95117
var pageAssetPath = GetRootPageAssetPath();
96-
var isInstance = CreateOrLoadInstance<MetaHubMarkdownPage>(pageAssetPath, out var markdownPage, forceCreate);
97-
if (isInstance)
98-
{
99-
markdownPage.OverrideMarkdownText(ReadTextFromFile(m_markdownPath), rootPath, m_reduceTitleLevelBy1);
100-
markdownPage.OverrideContext(this);
101-
}
102118

103-
if (markdownPage == null)
119+
if (AnyInContext)
104120
{
105-
GenerateParsedMarkdown();
106-
}
107-
else
108-
{
109-
m_parsedMarkdown = markdownPage.ParsedMarkdown;
110-
}
111-
112-
if (IncludeAllInContext || (markdownPage && !isInstance && !AnyAsChildren))
113-
{
114-
markdownPage = InstanceToAsset(markdownPage, pageAssetPath);
115-
var soPage = new ScriptableObjectPage(markdownPage, TutorialName, markdownPage.HierarchyName, markdownPage.Priority, ShowBanner ? Banner : null);
116-
return new[]
121+
var createdInstance = CreateOrLoadInstance<MetaHubMarkdownPage>(pageAssetPath, out var markdownPage, forceCreate);
122+
// if the instance is created we regenerate the page
123+
if (createdInstance)
117124
{
118-
new PageReference()
125+
if (IncludeAllInContext)
119126
{
120-
Page = soPage,
121-
Info = soPage
127+
markdownPage.OverrideMarkdownText(ReadTextFromFile(m_markdownPath), rootPath, m_reduceTitleLevelBy1);
122128
}
123-
};
124-
}
125-
else
126-
{
127-
ParsedMD.Section aggregator = null;
128-
var level0Indices = m_parsedMarkdown.Level0SectionIndices;
129-
if (isInstance)
130-
{
131-
var processingParsedMarkdown = markdownPage.ParsedMarkdown;
132-
for (var i = 0; i < level0Indices.Length; i++)
129+
else
133130
{
134-
if (m_pageConfigs[i].ShowSectionInContext)
135-
{
136-
var content = processingParsedMarkdown.GetCollapsedSection0(i, m_pageConfigs[i].HideTitle);
137-
if (aggregator == null)
138-
{
139-
aggregator = content;
140-
}
141-
else
142-
{
143-
aggregator.Append(content);
144-
}
145-
}
131+
GenerateMainPageWithSubsections(ref markdownPage, rootPath, pageAssetPath);
146132
}
147-
}
148133

149-
var ret = new List<PageReference>();
150-
if (aggregator != null)
151-
{
152-
markdownPage.OverrideMarkdownText(aggregator.ToString(), rootPath, m_reduceTitleLevelBy1, false); // the aggregator was already stripped of xml
153-
markdownPage = InstanceToAsset(markdownPage, pageAssetPath);
154-
155-
var soPage = new ScriptableObjectPage(markdownPage, TutorialName, markdownPage.HierarchyName, markdownPage.Priority, ShowBanner ? Banner : null);
156-
ret.Add(new PageReference()
134+
if (AnyAsChildren)
135+
{
136+
markdownPage.OverrideContext(this, prefixHierarchyName: $"{Title}/");
137+
}
138+
else
157139
{
158-
Page = soPage,
159-
Info = soPage
160-
});
140+
markdownPage.OverrideContext(this);
141+
}
142+
143+
markdownPage = InstanceToAsset(markdownPage, pageAssetPath);
144+
}
145+
if (markdownPage != null)
146+
{
147+
var soPage = new ScriptableObjectPage(
148+
markdownPage, TutorialName, markdownPage.HierarchyName, markdownPage.Priority,
149+
ShowBanner ? Banner : null);
150+
allPages.Add(new PageReference() { Page = soPage, Info = soPage });
161151
}
152+
}
162153

163-
// now create pages and references for the children
164-
for (var i = 0; i < level0Indices.Length; i++)
154+
if (AnyAsChildren)
155+
{
156+
for (var i = 0; i < m_pageConfigs.Count; i++)
165157
{
166-
if (m_pageConfigs[i].ShowSectionAsChild)
158+
var pageConfig = m_pageConfigs[i];
159+
if (pageConfig.ShowSectionAsChild)
167160
{
168-
pageAssetPath = GetChildPageAssetPath(m_pageConfigs[i].SectionTitle);
169-
isInstance = CreateOrLoadInstance<MetaHubMarkdownPage>(pageAssetPath, out var childPage, forceCreate);
170-
if (isInstance)
161+
pageAssetPath = GetChildPageAssetPath(pageConfig.SectionTitle);
162+
var createdInstance = CreateOrLoadInstance<MetaHubMarkdownPage>(
163+
pageAssetPath, out var childPage, forceCreate);
164+
if (createdInstance)
171165
{
172-
childPage.OverrideMarkdownText(m_parsedMarkdown.GetCollapsedSection0(i, m_pageConfigs[i].HideTitle).ToString(), rootPath, m_reduceTitleLevelBy1, false); // xml is already stripped
173-
childPage.OverrideContext(this, prefixHierarchyName: $"{markdownPage.HierarchyName}/", displayName: m_pageConfigs[i].SectionTitle);
166+
childPage.OverrideMarkdownText(
167+
GetParsedMarkDown().GetCollapsedSection0(i, m_pageConfigs[i].HideTitle).ToString(),
168+
rootPath, m_reduceTitleLevelBy1, false); // xml is already stripped
169+
childPage.OverrideContext(
170+
this, prefixHierarchyName: $"{Title}/",
171+
displayName: m_pageConfigs[i].SectionTitle, overridePriority: Priority + i);
174172
childPage = InstanceToAsset(childPage, pageAssetPath);
175173
}
176174

177-
var childSoPage = new ScriptableObjectPage(childPage, TutorialName, childPage.HierarchyName, childPage.Priority);
178-
ret.Add(new PageReference()
175+
if (childPage != null)
179176
{
180-
Page = childSoPage,
181-
Info = childSoPage
182-
});
177+
var childSoPage = new ScriptableObjectPage(
178+
childPage, TutorialName, childPage.HierarchyName, childPage.Priority);
179+
allPages.Add(new PageReference() { Page = childSoPage, Info = childSoPage });
180+
}
183181
}
184182
}
183+
}
185184

186-
return ret.ToArray();
185+
return allPages.ToArray();
186+
}
187+
188+
private ParsedMD GetParsedMarkDown()
189+
{
190+
if (m_parsedMarkdown == null)
191+
{
192+
GenerateParsedMarkdown();
187193
}
194+
195+
return m_parsedMarkdown;
196+
}
197+
198+
private void GenerateMainPageWithSubsections(ref MetaHubMarkdownPage markdownPage, string rootPath, string pageAssetPath)
199+
{
200+
if (markdownPage == null)
201+
{
202+
return;
203+
}
204+
ParsedMD.Section aggregator = null;
205+
for (var i = 0; i < m_pageConfigs.Count; i++)
206+
{
207+
if (m_pageConfigs[i].ShowSectionInContext)
208+
{
209+
var content = GetParsedMarkDown().GetCollapsedSection0(i, m_pageConfigs[i].HideTitle);
210+
if (aggregator == null)
211+
{
212+
aggregator = content;
213+
}
214+
else
215+
{
216+
aggregator.Append(content);
217+
}
218+
}
219+
}
220+
221+
if (aggregator != null)
222+
{
223+
// the aggregator was already stripped of xml
224+
markdownPage.OverrideMarkdownText(aggregator.ToString(), rootPath, m_reduceTitleLevelBy1, false);
225+
}
226+
}
227+
228+
public void ReloadPage()
229+
{
230+
// clear last loaded path so that it reloads the file
231+
m_lastLoadedPath = null;
232+
OnValidate();
188233
}
189234

190235
private void OnValidate()

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialMarkdownContextEditor.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
using UnityEditor;
55
using UnityEngine;
66

7+
#if META_EDIT_TUTORIALS
8+
using System.Linq;
9+
using Meta.Tutorial.Framework.Hub.Pages.Markdown;
10+
#endif
11+
712
namespace Meta.Tutorial.Framework.Hub.Contexts
813
{
914

@@ -16,28 +21,50 @@ public override void OnInspectorGUI()
1621
#if META_EDIT_TUTORIALS
1722
base.OnInspectorGUI();
1823

24+
EditorGUILayout.Space();
25+
if (GUILayout.Button(new GUIContent("Reload Page",
26+
"Reload the content of the page after modifying the .md file")))
27+
{
28+
context.ReloadPage();
29+
}
30+
1931
// layout the buttons horizontally
2032
EditorGUILayout.Space();
2133
EditorGUILayout.BeginHorizontal();
2234
if (GUILayout.Button("Toggle in context"))
2335
{
2436
context.ToggleAllPageConfigsToAppearInContext();
37+
EditorUtility.SetDirty(context);
38+
AssetDatabase.SaveAssetIfDirty(context);
2539
}
2640
if (GUILayout.Button("Toggle as children"))
2741
{
2842
context.ToggleAllPageConfigsToAppearAsChildren();
43+
EditorUtility.SetDirty(context);
44+
AssetDatabase.SaveAssetIfDirty(context);
2945
}
3046
EditorGUILayout.EndHorizontal();
3147
EditorGUILayout.Space();
3248
if (GUILayout.Button("Generate"))
3349
{
50+
// Remove all previous pages related to this context
51+
var allPages = Resources.FindObjectsOfTypeAll(typeof(MetaHubMarkdownPage));
52+
var pagesForContext = allPages.Where(page => (page as MetaHubMarkdownPage)?.ContextRef == context);
53+
foreach (var page in pagesForContext)
54+
{
55+
var path = AssetDatabase.GetAssetPath(page);
56+
if (!string.IsNullOrEmpty(path))
57+
{
58+
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(page));
59+
}
60+
}
3461
context.CreatePageReferences(true);
3562
}
3663
EditorGUILayout.Space();
3764
#endif
3865
if (GUILayout.Button("Open Tutorial Hub"))
3966
{
40-
Telemetry.OnOpenTutorialButton($"CONFIG::{context.Title}");
67+
Telemetry.OnOpenTutorialButton(context.TelemetryContext, context.ProjectName, context.Title);
4168
context.ShowDefaultWindow();
4269
}
4370
EditorGUILayout.Space();

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialReferencesContext.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) Meta Platforms, Inc. and affiliates.
22

3+
using System;
34
using Meta.Tutorial.Framework.Hub.Attributes;
45
using Meta.Tutorial.Framework.Hub.Pages;
56
using Meta.Tutorial.Framework.Hub.Utilities;
@@ -14,7 +15,7 @@ namespace Meta.Tutorial.Framework.Hub.Contexts
1415
#endif
1516
public class TutorialReferencesContext : BaseTutorialHubContext
1617
{
17-
[System.Serializable]
18+
[Serializable]
1819
public struct DynamicReferenceEntry
1920
{
2021
public string Header;
@@ -28,6 +29,10 @@ public override PageReference[] CreatePageReferences(bool forceCreate = false)
2829
{
2930
var pageAssetPath = GetRootPageAssetPath();
3031
_ = CreateOrLoadInstance<MetaHubWalkthroughPage>(pageAssetPath, out var walkthroughPage, forceCreate);
32+
if (walkthroughPage == null)
33+
{
34+
walkthroughPage = CreateInstance<MetaHubWalkthroughPage>();
35+
}
3136
walkthroughPage.Name = Title;
3237
walkthroughPage.References = new DynamicReferenceEntry[m_references.Length];
3338
for (var i = 0; i < m_references.Length; i++) // Copy references

com.meta.tutorial.framework/Editor/Scripts/Contexts/TutorialReferencesContextEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public override void OnInspectorGUI()
2323
#endif
2424
if (GUILayout.Button("Open Tutorial Hub"))
2525
{
26-
Telemetry.OnOpenTutorialButton(context.Title);
26+
Telemetry.OnOpenTutorialButton(context.TelemetryContext, context.ProjectName, context.Title);
2727
context.ShowDefaultWindow();
2828
}
2929
EditorGUILayout.Space();

com.meta.tutorial.framework/Editor/Scripts/Pages/Markdown/MetaHubMarkdownPage.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class MetaHubMarkdownPage : ScriptableObject, IPageInfo, IComparable<IPag
4848

4949
public string TelemetryContext => m_context.TelemetryContext;
5050

51+
public MetaHubContext ContextRef => m_context;
52+
5153
/// <summary>
5254
/// The Markdown file to display.
5355
/// </summary>

com.meta.tutorial.framework/Editor/Scripts/Pages/Markdown/MetaHubMarkdownPageEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ private void ProcessSegment(string input)
545545
listPrefix = string.IsNullOrEmpty(listPrefix) ? "•" : listPrefix; // Normalize '-' and '*' to '•'
546546
processedLine = listMatch.Groups[3].Value;
547547

548-
newListLevel = Mathf.FloorToInt(indentRaw.Length / 4f) + 1;
548+
newListLevel = Mathf.FloorToInt(indentRaw.Length / 2f) + 1;
549549
var matches = m_orderedCount.Matches(listPrefix);
550550
if (matches.Count > 0)
551551
{

0 commit comments

Comments
 (0)