From 663ebf7e3e5265ae57ceba9ea93479591826f86f Mon Sep 17 00:00:00 2001 From: Benjamin Mayrargue Date: Thu, 18 Jan 2024 17:47:44 +0100 Subject: [PATCH] fix code blocks --- .../JsonData/AboutThis.full.children.json | 158 +++++++++++++++++- .../JsonData/AboutThis.full.json | 2 +- NotionSharp.ApiClient.Tests/TestNotionBase.cs | 2 +- NotionSharp.ApiClient.Tests/TestNotionHtml.cs | 50 ++++++ .../Lib/HtmlRendering/HtmlRenderer.cs | 6 +- .../NotionSharp.ApiClient.csproj | 2 +- 6 files changed, 210 insertions(+), 10 deletions(-) diff --git a/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.children.json b/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.children.json index f12d9f5..3075b81 100644 --- a/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.children.json +++ b/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.children.json @@ -530,8 +530,8 @@ "has_children": false, "image": { "file": { - "url": "https://prod-files-secure.s3.us-west-2.amazonaws.com/da89a8e0-9c55-4c13-9966-796e0f0c1bac/04e5e722-c051-4268-b73d-5ddb4b9c69d4/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\u0026X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240112%2Fus-west-2%2Fs3%2Faws4_request\u0026X-Amz-Date=20240112T191654Z\u0026X-Amz-Expires=3600\u0026X-Amz-Signature=23d76bc0c356a8218af7797966f0758077c8709ef0d68085d99e9ff408ae2e75\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", - "expiry_time": "2024-01-12T20:16:54.526Z" + "url": "https://prod-files-secure.s3.us-west-2.amazonaws.com/da89a8e0-9c55-4c13-9966-796e0f0c1bac/04e5e722-c051-4268-b73d-5ddb4b9c69d4/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\u0026X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240118%2Fus-west-2%2Fs3%2Faws4_request\u0026X-Amz-Date=20240118T152212Z\u0026X-Amz-Expires=3600\u0026X-Amz-Signature=fe6173bf7b81d984da4d995e01cad0bd79d7292491097a0abf8e440f5cc1c04b\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "expiry_time": "2024-01-18T16:22:12.557Z" }, "type": "file" }, @@ -900,7 +900,155 @@ "id": "ab9257e1-d027-4494-8792-71d90b63dd35", "object": "user" }, - "last_edited_time": "2023-11-26T16:04:00+00:00", + "last_edited_time": "2024-01-18T14:58:00+00:00", + "last_edited_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "archived": false, + "has_children": false, + "paragraph": { + "rich_text": [] + }, + "object": "block" + }, + { + "id": "6323662a-8cfc-47a3-bde4-02404cee3b49", + "parent": { + "type": "page_id", + "page_id": "c7b44455-3d31-4a5b-b82c-b7e3d85ba585" + }, + "type": "code", + "created_time": "2024-01-18T14:58:00+00:00", + "created_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "last_edited_time": "2024-01-18T14:59:00+00:00", + "last_edited_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "archived": false, + "has_children": false, + "code": { + "language": "c#", + "caption": [], + "rich_text": [ + { + "type": "text", + "plain_text": "\u003Csvg:SvgImage Svg=\u0022res:images.logo\u0022 HeighRequest=\u002232\u0022 /\u003E\n\nXamSvg.Shared.Config.ResourceAssemblies = new [] { typeof(App).Assembly };", + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "text": { + "content": "\u003Csvg:SvgImage Svg=\u0022res:images.logo\u0022 HeighRequest=\u002232\u0022 /\u003E\n\nXamSvg.Shared.Config.ResourceAssemblies = new [] { typeof(App).Assembly };" + } + } + ] + }, + "object": "block" + }, + { + "id": "dbcfd8db-c1f1-442b-b81c-ffe094ac2571", + "parent": { + "type": "page_id", + "page_id": "c7b44455-3d31-4a5b-b82c-b7e3d85ba585" + }, + "type": "paragraph", + "created_time": "2023-11-26T16:03:00+00:00", + "created_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "last_edited_time": "2024-01-18T14:58:00+00:00", + "last_edited_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "archived": false, + "has_children": false, + "paragraph": { + "rich_text": [] + }, + "object": "block" + }, + { + "id": "d5ec5890-c2d9-458e-9bc2-e0e1eb6dc586", + "parent": { + "type": "page_id", + "page_id": "c7b44455-3d31-4a5b-b82c-b7e3d85ba585" + }, + "type": "code", + "created_time": "2023-11-26T16:03:00+00:00", + "created_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "last_edited_time": "2024-01-18T14:58:00+00:00", + "last_edited_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "archived": false, + "has_children": false, + "code": { + "language": "c#", + "caption": [ + { + "type": "text", + "plain_text": "Code that does nothing interesting.", + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "text": { + "content": "Code that does nothing interesting." + } + } + ], + "rich_text": [ + { + "type": "text", + "plain_text": "public partial class Commander\u003CT\u003E : ICommander where T:class\n{\n public async Task\u003CT\u003E Open(params string[] items)\n {\n\t\t\t\tawait File.ReadAllText(items[0]).ConfigureAwait(false);\n\t\t\t\treturn default;\n }\n}", + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "text": { + "content": "public partial class Commander\u003CT\u003E : ICommander where T:class\n{\n public async Task\u003CT\u003E Open(params string[] items)\n {\n\t\t\t\tawait File.ReadAllText(items[0]).ConfigureAwait(false);\n\t\t\t\treturn default;\n }\n}" + } + } + ] + }, + "object": "block" + }, + { + "id": "69833d85-09e3-41e0-beca-52005785a1de", + "parent": { + "type": "page_id", + "page_id": "c7b44455-3d31-4a5b-b82c-b7e3d85ba585" + }, + "type": "paragraph", + "created_time": "2024-01-18T09:28:00+00:00", + "created_by": { + "id": "ab9257e1-d027-4494-8792-71d90b63dd35", + "object": "user" + }, + "last_edited_time": "2024-01-18T09:28:00+00:00", "last_edited_by": { "id": "ab9257e1-d027-4494-8792-71d90b63dd35", "object": "user" @@ -1076,8 +1224,8 @@ "has_children": false, "image": { "file": { - "url": "https://prod-files-secure.s3.us-west-2.amazonaws.com/da89a8e0-9c55-4c13-9966-796e0f0c1bac/3b632032-656f-4e87-87b7-b95bcb786f9d/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\u0026X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240112%2Fus-west-2%2Fs3%2Faws4_request\u0026X-Amz-Date=20240112T191656Z\u0026X-Amz-Expires=3600\u0026X-Amz-Signature=bda2b0e78f76744f276eef9714cf94d987685fe7a0d218cce21f2b514a915e01\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", - "expiry_time": "2024-01-12T20:16:56.810Z" + "url": "https://prod-files-secure.s3.us-west-2.amazonaws.com/da89a8e0-9c55-4c13-9966-796e0f0c1bac/3b632032-656f-4e87-87b7-b95bcb786f9d/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\u0026X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240118%2Fus-west-2%2Fs3%2Faws4_request\u0026X-Amz-Date=20240118T152215Z\u0026X-Amz-Expires=3600\u0026X-Amz-Signature=91f0728351d7105f547890472dcbb2077b2cca5389e2a1619a84887cf80ed37e\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "expiry_time": "2024-01-18T16:22:15.758Z" }, "type": "file" }, diff --git a/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.json b/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.json index eb14c66..e2cf35c 100644 --- a/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.json +++ b/NotionSharp.ApiClient.Tests/JsonData/AboutThis.full.json @@ -1,7 +1,7 @@ { "id": "c7b44455-3d31-4a5b-b82c-b7e3d85ba585", "created_time": "2020-04-30T13:37:00+00:00", - "last_edited_time": "2024-01-12T19:15:00+00:00", + "last_edited_time": "2024-01-18T14:59:00+00:00", "archived": false, "created_by": { "id": "ab9257e1-d027-4494-8792-71d90b63dd35", diff --git a/NotionSharp.ApiClient.Tests/TestNotionBase.cs b/NotionSharp.ApiClient.Tests/TestNotionBase.cs index f1dae18..47c601d 100644 --- a/NotionSharp.ApiClient.Tests/TestNotionBase.cs +++ b/NotionSharp.ApiClient.Tests/TestNotionBase.cs @@ -261,7 +261,7 @@ public async Task TestPageAndChildrenDeserialization() } [TestMethod] - //[Ignore("Run this manually to create the json files")] + [Ignore("Run this manually to create the json files")] public async Task TestPageAndChildrenSerialization() { var session = new NotionSession(TestUtils.CreateOfficialNotionSessionInfo()); diff --git a/NotionSharp.ApiClient.Tests/TestNotionHtml.cs b/NotionSharp.ApiClient.Tests/TestNotionHtml.cs index 15a0de0..827539d 100644 --- a/NotionSharp.ApiClient.Tests/TestNotionHtml.cs +++ b/NotionSharp.ApiClient.Tests/TestNotionHtml.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Text.Json; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -129,6 +130,55 @@ public async Task TestGetHtml_Bullet_Levels2() Assert.AreEqual(expectedHtml, html); } + /// + /// Test Code blocks + /// + /// + /// AppendLine appends \r\n on windows, \r on linux + /// + [TestMethod] + public async Task TestGetHtml_Code() + { + var blocksJson = await File.ReadAllTextAsync(Path.Combine(Environment.CurrentDirectory, "JsonData", "AboutThis.full.children.json")); + var blocks = JsonSerializer.Deserialize>(blocksJson, HttpNotionSession.NotionJsonFullSerializationOptions); + + var block = blocks.Where(b => b.Type == "code").Take(1).ToList(); + Assert.AreEqual(1, block.Count); + + var html = new HtmlRenderer().GetHtml(block).Replace("\r", ""); + var expectedHtml = """ +
+<svg:SvgImage Svg="res:images.logo" HeighRequest="32" /> + +XamSvg.Shared.Config.ResourceAssemblies = new [] { typeof(App).Assembly }; + +
+ +""".Replace("\r", ""); + + var i = FindDifferingIndex(expectedHtml, html); + Assert.AreEqual(-1, i); + + Assert.AreEqual(expectedHtml, html); + } + + static int FindDifferingIndex(string str1, string str2) + { + var minLength = Math.Min(str1.Length, str2.Length); + + for (var i = 0; i < minLength; i++) + { + if (str1[i] != str2[i]) + return i; // Found the differing index + } + + // If the loop completes, check if one string is longer than the other + if (str1.Length != str2.Length) + return minLength; // Strings are different in length + + return -1; // Strings are identical + } + // [TestMethod] // public void TestGetHtml_SubBullets() // { diff --git a/NotionSharp.ApiClient/Lib/HtmlRendering/HtmlRenderer.cs b/NotionSharp.ApiClient/Lib/HtmlRendering/HtmlRenderer.cs index f66c86e..2fa881b 100644 --- a/NotionSharp.ApiClient/Lib/HtmlRendering/HtmlRenderer.cs +++ b/NotionSharp.ApiClient/Lib/HtmlRendering/HtmlRenderer.cs @@ -150,8 +150,10 @@ protected virtual void TransformCode(Block block, StringBuilder sb) sb.Append("""
"""); - sb.Append($""""""); - Append(code.RichText, sb); + sb.AppendLine($""""""); + var sb1 = new StringBuilder(code.RichText.FirstOrDefault()?.Text?.Content) + .Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("\"", """).Replace("\r", ""); + sb.Append(sb1).AppendLine(); sb.AppendLine(""); if (code.Caption?.Count > 0) diff --git a/NotionSharp.ApiClient/NotionSharp.ApiClient.csproj b/NotionSharp.ApiClient/NotionSharp.ApiClient.csproj index 1e47cdf..9f55701 100644 --- a/NotionSharp.ApiClient/NotionSharp.ApiClient.csproj +++ b/NotionSharp.ApiClient/NotionSharp.ApiClient.csproj @@ -19,7 +19,7 @@ 2.0.1 - -pre2 + -pre3 $(DefineConstants);