From 328c0b180ae24bc383709255655d2ddb6a6af00b Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Mahunt Date: Sat, 21 Mar 2020 11:51:05 +0530 Subject: [PATCH 1/4] Implemented opening local files by markdown links. --- .../Controls/TextEditor/TextEditor.xaml.cs | 2 +- .../Extensions/IContentPreviewExtension.cs | 2 +- .../Markdown/MarkdownExtensionView.xaml.cs | 18 +++++++++++++++--- src/Notepads/Package.appxmanifest | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs b/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs index c7a387fc1..63677e664 100644 --- a/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs +++ b/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs @@ -589,7 +589,7 @@ public void ShowHideContentPreview() { _contentPreviewExtension = ExtensionProvider?.GetContentPreviewExtension(FileType); if (_contentPreviewExtension == null) return; - _contentPreviewExtension.Bind(TextEditorCore); + _contentPreviewExtension.Bind(TextEditorCore, System.IO.Path.GetDirectoryName(EditingFilePath) + System.IO.Path.DirectorySeparatorChar); } if (SplitPanel == null) LoadSplitView(); diff --git a/src/Notepads/Extensions/IContentPreviewExtension.cs b/src/Notepads/Extensions/IContentPreviewExtension.cs index 86b68ec4a..c56d60d65 100644 --- a/src/Notepads/Extensions/IContentPreviewExtension.cs +++ b/src/Notepads/Extensions/IContentPreviewExtension.cs @@ -4,7 +4,7 @@ public interface IContentPreviewExtension { - void Bind(TextEditorCore editor); + void Bind(TextEditorCore editor, string parentPath); bool IsExtensionEnabled { get; set; } diff --git a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs index 8692b4ebf..1b061990e 100644 --- a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs +++ b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs @@ -17,6 +17,8 @@ public sealed partial class MarkdownExtensionView : UserControl, IContentPreview { private bool _isExtensionEnabled; + private string _parentPath; + public bool IsExtensionEnabled { get => _isExtensionEnabled; @@ -115,7 +117,7 @@ private async Task GetImageAsync(string url) } } - public void Bind(TextEditorCore editorCore) + public void Bind(TextEditorCore editorCore, string parentPath) { if (_editorCore != null) { @@ -128,6 +130,8 @@ public void Bind(TextEditorCore editorCore) _editorCore.TextChanged += OnTextChanged; _editorCore.TextWrappingChanged += OnTextWrappingChanged; _editorCore.FontSizeChanged += OnFontSizeChanged; + + _parentPath = parentPath; } private void OnTextChanged(object sender, RoutedEventArgs e) @@ -195,8 +199,16 @@ private async void MarkdownTextBlock_OnLinkClicked(object sender, LinkClickedEve try { - var uri = new Uri(e.Link); - await Windows.System.Launcher.LaunchUriAsync(uri); + try + { + var uri = new Uri(e.Link); + await Windows.System.Launcher.LaunchUriAsync(uri); + } + catch (Exception) + { + var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(_parentPath + e.Link.Replace('/', Path.DirectorySeparatorChar)); + await Windows.System.Launcher.LaunchFileAsync(file); + } } catch (Exception ex) { diff --git a/src/Notepads/Package.appxmanifest b/src/Notepads/Package.appxmanifest index b22422b2d..df8167491 100644 --- a/src/Notepads/Package.appxmanifest +++ b/src/Notepads/Package.appxmanifest @@ -539,5 +539,6 @@ + From 7c884bea9bed0cf741adf9708821198ae5c61689 Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Mahunt Date: Sat, 21 Mar 2020 15:14:48 +0530 Subject: [PATCH 2/4] Implemented image preview for local image file in markdown. --- .../Markdown/MarkdownExtensionView.xaml.cs | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs index 1b061990e..16d2f8c0e 100644 --- a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs +++ b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs @@ -7,6 +7,7 @@ using Notepads.Controls.TextEditor; using Notepads.Services; using Notepads.Utilities; + using Windows.Storage; using Windows.Storage.Streams; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -19,6 +20,8 @@ public sealed partial class MarkdownExtensionView : UserControl, IContentPreview private string _parentPath; + private readonly char[] ignoredChars = { '?', '#', ' ' }; + public bool IsExtensionEnabled { get => _isExtensionEnabled; @@ -64,18 +67,40 @@ private async void MarkdownTextBlock_ImageResolving(object sender, ImageResolvin try { - var imageUri = new Uri(e.Url); - if (Path.GetExtension(imageUri.AbsolutePath)?.ToLowerInvariant() == ".svg") + try { - // SvgImageSource is not working properly when width and height are not set in uri - // I am disabling Svg parsing here. - // e.Image = await GetImageAsync(e.Url); - e.Handled = true; + var imageUri = new Uri(e.Url); + if (Path.GetExtension(imageUri.AbsolutePath)?.ToLowerInvariant() == ".svg") + { + // SvgImageSource is not working properly when width and height are not set in uri + // I am disabling Svg parsing here. + // e.Image = await GetImageAsync(e.Url); + e.Handled = true; + } + else + { + e.Image = await GetImageAsync(e.Url); + e.Handled = true; + } } - else + catch (Exception) { - e.Image = await GetImageAsync(e.Url); - e.Handled = true; + var ignoreIndex = e.Url.IndexOfAny(ignoredChars); + var imagePath = _parentPath + (ignoreIndex > -1 + ? e.Url.Remove(ignoreIndex).Replace('/', Path.DirectorySeparatorChar) + : e.Url.Replace('/', Path.DirectorySeparatorChar)); + if (Path.GetExtension(imagePath)?.ToLowerInvariant() == ".svg") + { + // SvgImageSource is not working properly when width and height are not set in uri + // I am disabling Svg parsing here. + // e.Image = await GetImageAsync(e.Url); + e.Handled = true; + } + else + { + e.Image = await GetLocalImageAsync(imagePath); + e.Handled = true; + } } } catch (Exception ex) @@ -117,6 +142,27 @@ private async Task GetImageAsync(string url) } } + private async Task GetLocalImageAsync(string imagePath) + { + var imageFile = await StorageFile.GetFileFromPathAsync(imagePath); + + using (var ms = await imageFile.OpenReadAsync()) + { + if (Path.GetExtension(imagePath)?.ToLowerInvariant() == ".svg") + { + var image = new SvgImageSource(); + await image.SetSourceAsync(ms); + return image; + } + else + { + var image = new BitmapImage(); + await image.SetSourceAsync(ms); + return image; + } + } + } + public void Bind(TextEditorCore editorCore, string parentPath) { if (_editorCore != null) @@ -206,7 +252,7 @@ private async void MarkdownTextBlock_OnLinkClicked(object sender, LinkClickedEve } catch (Exception) { - var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(_parentPath + e.Link.Replace('/', Path.DirectorySeparatorChar)); + var file = await StorageFile.GetFileFromPathAsync(_parentPath + e.Link.Replace('/', Path.DirectorySeparatorChar)); await Windows.System.Launcher.LaunchFileAsync(file); } } From 0ee189a39abe3ddfcbe4501bb273e0518ecfc0f9 Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Mahunt Date: Sat, 21 Mar 2020 11:51:05 +0530 Subject: [PATCH 3/4] Implemented opening local files by markdown links. --- .../Controls/TextEditor/TextEditor.xaml.cs | 2 +- .../Extensions/IContentPreviewExtension.cs | 2 +- .../Markdown/MarkdownExtensionView.xaml.cs | 18 +++++++++++++++--- src/Notepads/Package.appxmanifest | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs b/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs index 47011b290..5235ea1d6 100644 --- a/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs +++ b/src/Notepads/Controls/TextEditor/TextEditor.xaml.cs @@ -591,7 +591,7 @@ public void ShowHideContentPreview() { _contentPreviewExtension = ExtensionProvider?.GetContentPreviewExtension(FileType); if (_contentPreviewExtension == null) return; - _contentPreviewExtension.Bind(TextEditorCore); + _contentPreviewExtension.Bind(TextEditorCore, System.IO.Path.GetDirectoryName(EditingFilePath) + System.IO.Path.DirectorySeparatorChar); } if (SplitPanel == null) LoadSplitView(); diff --git a/src/Notepads/Extensions/IContentPreviewExtension.cs b/src/Notepads/Extensions/IContentPreviewExtension.cs index 86b68ec4a..c56d60d65 100644 --- a/src/Notepads/Extensions/IContentPreviewExtension.cs +++ b/src/Notepads/Extensions/IContentPreviewExtension.cs @@ -4,7 +4,7 @@ public interface IContentPreviewExtension { - void Bind(TextEditorCore editor); + void Bind(TextEditorCore editor, string parentPath); bool IsExtensionEnabled { get; set; } diff --git a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs index 8692b4ebf..1b061990e 100644 --- a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs +++ b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs @@ -17,6 +17,8 @@ public sealed partial class MarkdownExtensionView : UserControl, IContentPreview { private bool _isExtensionEnabled; + private string _parentPath; + public bool IsExtensionEnabled { get => _isExtensionEnabled; @@ -115,7 +117,7 @@ private async Task GetImageAsync(string url) } } - public void Bind(TextEditorCore editorCore) + public void Bind(TextEditorCore editorCore, string parentPath) { if (_editorCore != null) { @@ -128,6 +130,8 @@ public void Bind(TextEditorCore editorCore) _editorCore.TextChanged += OnTextChanged; _editorCore.TextWrappingChanged += OnTextWrappingChanged; _editorCore.FontSizeChanged += OnFontSizeChanged; + + _parentPath = parentPath; } private void OnTextChanged(object sender, RoutedEventArgs e) @@ -195,8 +199,16 @@ private async void MarkdownTextBlock_OnLinkClicked(object sender, LinkClickedEve try { - var uri = new Uri(e.Link); - await Windows.System.Launcher.LaunchUriAsync(uri); + try + { + var uri = new Uri(e.Link); + await Windows.System.Launcher.LaunchUriAsync(uri); + } + catch (Exception) + { + var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(_parentPath + e.Link.Replace('/', Path.DirectorySeparatorChar)); + await Windows.System.Launcher.LaunchFileAsync(file); + } } catch (Exception ex) { diff --git a/src/Notepads/Package.appxmanifest b/src/Notepads/Package.appxmanifest index 8a4882889..9d089aeb1 100644 --- a/src/Notepads/Package.appxmanifest +++ b/src/Notepads/Package.appxmanifest @@ -539,5 +539,6 @@ + From f9ab6191cc5bd570bc6674c967247483e14de80e Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Mahunt Date: Sat, 21 Mar 2020 15:14:48 +0530 Subject: [PATCH 4/4] Implemented image preview for local image file in markdown. --- .../Markdown/MarkdownExtensionView.xaml.cs | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs index 1b061990e..16d2f8c0e 100644 --- a/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs +++ b/src/Notepads/Extensions/Markdown/MarkdownExtensionView.xaml.cs @@ -7,6 +7,7 @@ using Notepads.Controls.TextEditor; using Notepads.Services; using Notepads.Utilities; + using Windows.Storage; using Windows.Storage.Streams; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -19,6 +20,8 @@ public sealed partial class MarkdownExtensionView : UserControl, IContentPreview private string _parentPath; + private readonly char[] ignoredChars = { '?', '#', ' ' }; + public bool IsExtensionEnabled { get => _isExtensionEnabled; @@ -64,18 +67,40 @@ private async void MarkdownTextBlock_ImageResolving(object sender, ImageResolvin try { - var imageUri = new Uri(e.Url); - if (Path.GetExtension(imageUri.AbsolutePath)?.ToLowerInvariant() == ".svg") + try { - // SvgImageSource is not working properly when width and height are not set in uri - // I am disabling Svg parsing here. - // e.Image = await GetImageAsync(e.Url); - e.Handled = true; + var imageUri = new Uri(e.Url); + if (Path.GetExtension(imageUri.AbsolutePath)?.ToLowerInvariant() == ".svg") + { + // SvgImageSource is not working properly when width and height are not set in uri + // I am disabling Svg parsing here. + // e.Image = await GetImageAsync(e.Url); + e.Handled = true; + } + else + { + e.Image = await GetImageAsync(e.Url); + e.Handled = true; + } } - else + catch (Exception) { - e.Image = await GetImageAsync(e.Url); - e.Handled = true; + var ignoreIndex = e.Url.IndexOfAny(ignoredChars); + var imagePath = _parentPath + (ignoreIndex > -1 + ? e.Url.Remove(ignoreIndex).Replace('/', Path.DirectorySeparatorChar) + : e.Url.Replace('/', Path.DirectorySeparatorChar)); + if (Path.GetExtension(imagePath)?.ToLowerInvariant() == ".svg") + { + // SvgImageSource is not working properly when width and height are not set in uri + // I am disabling Svg parsing here. + // e.Image = await GetImageAsync(e.Url); + e.Handled = true; + } + else + { + e.Image = await GetLocalImageAsync(imagePath); + e.Handled = true; + } } } catch (Exception ex) @@ -117,6 +142,27 @@ private async Task GetImageAsync(string url) } } + private async Task GetLocalImageAsync(string imagePath) + { + var imageFile = await StorageFile.GetFileFromPathAsync(imagePath); + + using (var ms = await imageFile.OpenReadAsync()) + { + if (Path.GetExtension(imagePath)?.ToLowerInvariant() == ".svg") + { + var image = new SvgImageSource(); + await image.SetSourceAsync(ms); + return image; + } + else + { + var image = new BitmapImage(); + await image.SetSourceAsync(ms); + return image; + } + } + } + public void Bind(TextEditorCore editorCore, string parentPath) { if (_editorCore != null) @@ -206,7 +252,7 @@ private async void MarkdownTextBlock_OnLinkClicked(object sender, LinkClickedEve } catch (Exception) { - var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(_parentPath + e.Link.Replace('/', Path.DirectorySeparatorChar)); + var file = await StorageFile.GetFileFromPathAsync(_parentPath + e.Link.Replace('/', Path.DirectorySeparatorChar)); await Windows.System.Launcher.LaunchFileAsync(file); } }