├── Documentation ├── Screenshot.png ├── Screenshot_dark.png ├── Screenshot_light.png └── wiki │ ├── youtube_preview.png │ └── link_actionsheet.png ├── .github └── FUNDING.yml ├── Sources ├── iOS │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Entitlements.plist │ ├── Main.cs │ ├── AppDelegate.cs │ ├── LaunchScreen.storyboard │ ├── Info.plist │ ├── packages.config │ └── Markdown.Samples.iOS.csproj ├── Droid │ ├── Resources │ │ ├── drawable │ │ │ └── icon.png │ │ ├── drawable-hdpi │ │ │ └── icon.png │ │ ├── drawable-xhdpi │ │ │ └── icon.png │ │ ├── drawable-xxhdpi │ │ │ └── icon.png │ │ ├── layout │ │ │ ├── Toolbar.axml │ │ │ └── Tabbar.axml │ │ ├── values │ │ │ └── styles.xml │ │ └── AboutResources.txt │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Assets │ │ └── AboutAssets.txt │ ├── MainActivity.cs │ ├── packages.config │ └── Markdown.Samples.Droid.csproj ├── Markdown.Samples │ ├── FodyWeavers.xml │ ├── App.xaml │ ├── packages.config │ ├── Controls │ │ ├── SettingsCard.xaml.cs │ │ └── SettingsCard.xaml │ ├── ViewModels │ │ ├── BaseViewModel.cs │ │ ├── SettingsCardViewModel.cs │ │ ├── SettingsItemViewModel.cs │ │ └── SamplePageViewModel.cs │ ├── App.xaml.cs │ ├── Utils │ │ └── LayoutOptionsWrapper.cs │ ├── Views │ │ ├── SamplesPage.xaml.cs │ │ └── SamplesPage.xaml │ ├── Selectors │ │ └── SettingsItemSelector.cs │ ├── Markdown.Samples.csproj │ └── FodyWeavers.xsd ├── Markdown.Portable │ ├── VideoPreviewDescriptor.cs │ ├── packages.config │ ├── Xam.Forms.Markdown.nuspec │ ├── MarkdownStyle.cs │ ├── Extensions │ │ ├── GithubExtensions.cs │ │ └── ImageExtensions.cs │ ├── LinkStyle.cs │ ├── ListStyle.cs │ ├── Xam.Forms.Markdown.csproj │ ├── MarkdownTheme.cs │ └── MarkdownView.cs ├── Settings.XamlStyler ├── .editorconfig └── MarkdownView.sln ├── LICENSE ├── README.md ├── CHANGELOG.md └── .gitignore /Documentation/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Documentation/Screenshot.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: https://www.buymeacoffee.com/bares43 4 | -------------------------------------------------------------------------------- /Documentation/Screenshot_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Documentation/Screenshot_dark.png -------------------------------------------------------------------------------- /Sources/iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Documentation/Screenshot_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Documentation/Screenshot_light.png -------------------------------------------------------------------------------- /Documentation/wiki/youtube_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Documentation/wiki/youtube_preview.png -------------------------------------------------------------------------------- /Documentation/wiki/link_actionsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Documentation/wiki/link_actionsheet.png -------------------------------------------------------------------------------- /Sources/Droid/Resources/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Sources/Droid/Resources/drawable/icon.png -------------------------------------------------------------------------------- /Sources/Droid/Resources/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Sources/Droid/Resources/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /Sources/Droid/Resources/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Sources/Droid/Resources/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /Sources/Droid/Resources/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bares43/MarkdownView/HEAD/Sources/Droid/Resources/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /Sources/Markdown.Samples/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/VideoPreviewDescriptor.cs: -------------------------------------------------------------------------------- 1 | namespace Xam.Forms.Markdown 2 | { 3 | public class VideoPreviewDescriptor 4 | { 5 | public string Code { get; set; } 6 | public string VideoUrl { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/App.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sources/Droid/Resources/layout/Toolbar.axml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Sources/Droid/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Sources/iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using UIKit; 2 | 3 | namespace MarkdownView.Samples.iOS 4 | { 5 | public class Application 6 | { 7 | // This is the main entry point of the application. 8 | static void Main(string[] args) 9 | { 10 | // if you want to use a different Application Delegate class from "AppDelegate" 11 | // you can specify it here. 12 | UIApplication.Main(args, null, "AppDelegate"); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Markdown.Samples/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sources/Droid/Resources/layout/Tabbar.axml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/Controls/SettingsCard.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace Markdown.Samples.Controls 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class SettingsCard : ContentView 14 | { 15 | public SettingsCard() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Markdown.Samples/ViewModels/BaseViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Text; 5 | 6 | namespace Markdown.Samples.ViewModels 7 | { 8 | public class BaseViewModel : INotifyPropertyChanged 9 | { 10 | public event PropertyChangedEventHandler PropertyChanged; 11 | 12 | public void RaisePropertyChanged(string propertyName) 13 | { 14 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using UIKit; 3 | 4 | namespace MarkdownView.Samples.iOS 5 | { 6 | [Register("AppDelegate")] 7 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 8 | { 9 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 10 | { 11 | global::Xamarin.Forms.Forms.Init(); 12 | 13 | LoadApplication(new App()); 14 | 15 | return base.FinishedLaunching(app, options); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/Droid/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Markdown.Samples.Views; 2 | using Xamarin.Forms; 3 | 4 | namespace MarkdownView.Samples 5 | { 6 | public partial class App : Application 7 | { 8 | public App() 9 | { 10 | InitializeComponent(); 11 | 12 | MainPage = new SamplesPage(); 13 | } 14 | 15 | protected override void OnStart() 16 | { 17 | // Handle when your app starts 18 | } 19 | 20 | protected override void OnSleep() 21 | { 22 | // Handle when your app sleeps 23 | } 24 | 25 | protected override void OnResume() 26 | { 27 | // Handle when your app resumes 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/Xam.Forms.Markdown.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Xam.Forms.Markdown 5 | 1.5.2 6 | Xam.Forms.Markdown 7 | bares43 8 | bares43 9 | https://github.com/bares43/MarkdownView 10 | false 11 | Actively developed (2021) native markdown rendering for Xamarin.Forms. 12 | 13 | https://github.com/bares43/MarkdownView/blob/dev/CHANGELOG.md 14 | 15 | Copyright 2021 16 | xamarin ios android md markdown native xamarin.forms 17 | 18 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/Utils/LayoutOptionsWrapper.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Markdown.Samples.Utils 4 | { 5 | public class LayoutOptionsWrapper 6 | { 7 | public LayoutOptions LayoutOptions { get; } 8 | 9 | public LayoutOptionsWrapper(LayoutOptions layoutOptions) 10 | { 11 | LayoutOptions = layoutOptions; 12 | } 13 | public override string ToString() 14 | { 15 | var name = LayoutOptions.Alignment.ToString(); 16 | 17 | if (LayoutOptions.Expands) 18 | { 19 | name += "AndExpand"; 20 | } 21 | 22 | return name; 23 | } 24 | 25 | public override bool Equals(object obj) => LayoutOptions.Equals((obj as LayoutOptionsWrapper).LayoutOptions); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/Droid/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace MarkdownView.Samples.Droid 6 | { 7 | [Activity(Label = "MarkdownView.Samples.Droid", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 8 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 9 | { 10 | protected override void OnCreate(Bundle bundle) 11 | { 12 | TabLayoutResource = Resource.Layout.Tabbar; 13 | ToolbarResource = Resource.Layout.Toolbar; 14 | 15 | base.OnCreate(bundle); 16 | 17 | global::Xamarin.Forms.Forms.Init(this, bundle); 18 | 19 | LoadApplication(new App()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/ViewModels/SettingsCardViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Text; 5 | using System.Windows.Input; 6 | using Xamarin.Forms; 7 | 8 | namespace Markdown.Samples.ViewModels 9 | { 10 | public class SettingsCardViewModel : BaseViewModel 11 | { 12 | public string Name { get; set; } 13 | public bool IsOpened { get; set; } 14 | public ICommand ToggleCommand { get; set; } 15 | public ObservableCollection Items { get; set; } = new ObservableCollection(); 16 | 17 | public SettingsCardViewModel(string name) 18 | { 19 | Name = name; 20 | ToggleCommand = new Command(() => 21 | { 22 | IsOpened = !IsOpened; 23 | }); 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/MarkdownStyle.cs: -------------------------------------------------------------------------------- 1 | namespace Xam.Forms.Markdown 2 | { 3 | using Xamarin.Forms; 4 | 5 | public class MarkdownStyle 6 | { 7 | public FontAttributes Attributes { get; set; } = FontAttributes.None; 8 | 9 | public float FontSize { get; set; } = 12; 10 | 11 | public float LineHeight { get; set; } = -1; 12 | 13 | public Color ForegroundColor { get; set; } = Color.Black; 14 | 15 | public Color BackgroundColor { get; set; } = Color.Transparent; 16 | 17 | public Color BorderColor { get; set; } 18 | 19 | public float BorderSize { get; set; } 20 | 21 | public string FontFamily { get; set; } 22 | 23 | public TextAlignment HorizontalTextAlignment { get; set; } = TextAlignment.Start; 24 | public TextAlignment VerticalTextAlignment { get; set; } = TextAlignment.Center; 25 | 26 | public TextDecorations TextDecorations { get; set; } = TextDecorations.None; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/Droid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // Information about this assembly is defined by the following attributes. 4 | // Change them to the values specific to your project. 5 | 6 | [assembly: AssemblyTitle("MarkdownView.Samples.Droid")] 7 | [assembly: AssemblyDescription("")] 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("")] 11 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyCulture("")] 14 | 15 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 16 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 17 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 18 | 19 | [assembly: AssemblyVersion("1.0.0")] 20 | 21 | // The following attributes are used to specify the signing key for the assembly, 22 | // if desired. See the Mono documentation for more information about signing. 23 | 24 | //[assembly: AssemblyDelaySign(false)] 25 | //[assembly: AssemblyKeyFile("")] 26 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/Views/SamplesPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Xaml; 9 | 10 | namespace Markdown.Samples.Views 11 | { 12 | [XamlCompilation(XamlCompilationOptions.Compile)] 13 | public partial class SamplesPage : ContentPage 14 | { 15 | public SamplesPage() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | private void SettingsButton_Clicked(object sender, EventArgs e) 21 | { 22 | Device.BeginInvokeOnMainThread(async () => 23 | { 24 | await scrollView.ScrollToAsync(settings, ScrollToPosition.Start, true); 25 | }); 26 | } 27 | 28 | private void SourceButton_Clicked(object sender, EventArgs e) 29 | { 30 | Device.BeginInvokeOnMainThread(async () => 31 | { 32 | await scrollView.ScrollToAsync(source, ScrollToPosition.Start, true); 33 | }); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Aloïs Deniel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/Extensions/GithubExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Xam.Forms.Markdown 2 | { 3 | using System.Text.RegularExpressions; 4 | 5 | /// 6 | /// A set o helper extensions for parsing Github common urls. 7 | /// 8 | public static class GithubExtensions 9 | { 10 | static readonly Regex githubRepoRegex = new Regex("http(s)?:\\/\\/github.com\\/([a-zA-Z0-9_-]+)\\/([a-zA-Z0-9_-]+)\\/((blob|tree)\\/([a-zA-Z0-9_-]+))?"); 11 | 12 | const string githubReadmeUrl = "https://raw.githubusercontent.com/{0}/{1}/{2}/README.md"; 13 | 14 | public static bool TryExtractGithubRawMarkdownUrl(string url, out string readmeUrl) 15 | { 16 | var match = githubRepoRegex.Match(url); 17 | if (match.Success) 18 | { 19 | var user = match.Groups[2].Value; 20 | var repo = match.Groups[3].Value; 21 | var branch = match.Groups.Count > 6 ? match.Groups[6].Value : "master"; 22 | readmeUrl = string.Format(githubReadmeUrl, user, repo, branch); 23 | return true; 24 | } 25 | 26 | readmeUrl = null; 27 | return false; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/LinkStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Xamarin.Forms; 5 | 6 | namespace Xam.Forms.Markdown 7 | { 8 | public class LinkStyle : MarkdownStyle 9 | { 10 | public string OpenLinkSheetTitle { get; set; } = "Open link"; 11 | public string OpenLinkSheetCancel { get; set; } = "Cancel"; 12 | public Action> CustomTapHandler { get; set; } 13 | public List ExternalProtocols = new List { "http://", "https://", "mailto:", "tel:" }; 14 | public bool LoadYouTubePreview { get; set; } 15 | public YouTubePreview YouTubePreview { get; set; } 16 | public bool UseAutolinksExtension { get; set; } 17 | } 18 | 19 | public class LinkData 20 | { 21 | public string Text { get; set; } 22 | public string Link { get; set; } 23 | } 24 | 25 | public class YouTubePreview 26 | { 27 | public Func GenerateLoadImageUrl { get; set; } 28 | public Func CustomLoadImage { get; set; } 29 | public Func TransformView { get; set; } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/ListStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Markdig.Syntax; 3 | using Xamarin.Forms; 4 | 5 | namespace Xam.Forms.Markdown 6 | { 7 | public class ListStyle 8 | { 9 | public float Indentation { get; set; } = 10; 10 | public float? Spacing { get; set; } 11 | public float ItemsVerticalSpacing { get; set; } = 10; 12 | public Thickness ListMargin { get; set; } = new Thickness(0); 13 | public ListStyleType BulletStyleType { get; set; } 14 | public int BulletSize { get; set; } = 4; 15 | public float? BulletFontSize { get; set; } 16 | public float? BulletLineHeight { get; set; } 17 | public Color? BulletColor { get; set; } 18 | public FontAttributes BulletFontAttributes { get; set; } = FontAttributes.None; 19 | public LayoutOptions BulletVerticalOptions { get; set; } 20 | public LayoutOptions ItemVerticalOptions { get; set; } 21 | public string Symbol { get; set; } 22 | public Func CustomCallback { get; set; } 23 | } 24 | 25 | public enum ListStyleType 26 | { 27 | Square, 28 | Circle, 29 | None, 30 | Symbol, 31 | Decimal, 32 | Custom 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/Selectors/SettingsItemSelector.cs: -------------------------------------------------------------------------------- 1 | using Markdown.Samples.ViewModels; 2 | using Xamarin.Forms; 3 | 4 | namespace Markdown.Samples.Selectors 5 | { 6 | public class SettingsItemSelector : DataTemplateSelector 7 | { 8 | protected override DataTemplate OnSelectTemplate(object item, BindableObject container) 9 | { 10 | var list = (StackLayout)container; 11 | 12 | if (item is SwitchSettingsItemViewModel) 13 | { 14 | return (DataTemplate)list.Resources["Switch"]; 15 | } 16 | 17 | if (item is EntrySettingsItemViewModel) 18 | { 19 | return (DataTemplate)list.Resources["Entry"]; 20 | } 21 | 22 | if (item is StepperSettingsItemViewModel) 23 | { 24 | return (DataTemplate)list.Resources["Stepper"]; 25 | } 26 | 27 | if (item is PickerSettingsViewModel) 28 | { 29 | return (DataTemplate)list.Resources["Picker"]; 30 | } 31 | 32 | if (item is EditorSettingsItemViewModel) 33 | { 34 | return (DataTemplate)list.Resources["Editor"]; 35 | } 36 | 37 | return null; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/Droid/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /Sources/iOS/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Sources/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | MarkdownView 7 | CFBundleName 8 | MarkdownView 9 | CFBundleIdentifier 10 | com.MarkdownView 11 | CFBundleShortVersionString 12 | 1.0 13 | CFBundleVersion 14 | 1.0 15 | LSRequiresIPhoneOS 16 | 17 | MinimumOSVersion 18 | 8.0 19 | UIDeviceFamily 20 | 21 | 1 22 | 2 23 | 24 | UILaunchStoryboardName 25 | LaunchScreen 26 | UIRequiredDeviceCapabilities 27 | 28 | armv7 29 | 30 | UISupportedInterfaceOrientations 31 | 32 | UIInterfaceOrientationPortrait 33 | UIInterfaceOrientationLandscapeLeft 34 | UIInterfaceOrientationLandscapeRight 35 | 36 | UISupportedInterfaceOrientations~ipad 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationPortraitUpsideDown 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | XSAppIconAssets 44 | Assets.xcassets/AppIcon.appiconset 45 | 46 | 47 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/Markdown.Samples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netstandard2.0 6 | 7 | 8 | 9 | 10 | all 11 | runtime; build; native; contentfiles; analyzers; buildtransitive 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | App.xaml 25 | 26 | 27 | SamplesPage.xaml 28 | 29 | 30 | 31 | 32 | 33 | MSBuild:UpdateDesignTimeXaml 34 | 35 | 36 | MSBuild:UpdateDesignTimeXaml 37 | 38 | 39 | MSBuild:UpdateDesignTimeXaml 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/Xam.Forms.Markdown.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netstandard2.0 6 | 7 | 8 | 9 | 0.0.0.0 10 | 0.0.0.0 11 | 1.0.0.0 12 | 0.0.0.0 13 | $(AssemblyName) ($(TargetFramework)) 14 | bares43 15 | Xam.Forms.Markdown 16 | MarkdownView for Xamarin.Forms 17 | Native markdown rendering for Xamarin.Forms. 18 | Native markdown rendering for Xamarin.Forms. 19 | xamarin, ios, android, md, markdown, native, xamarin.forms 20 | Aloïs Deniel 21 | true 22 | en 23 | https://raw.githubusercontent.com/aloisdeniel/MarkdownView/master/Documentation/Logo.png 24 | https://github.com/aloisdeniel/MarkdownView/blob/master/LICENSE 25 | https://github.com/bares43/MarkdownView 26 | Xam.Forms.Markdown 27 | Xam.Forms.Markdown 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Sources/Droid/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /Sources/Markdown.Portable/Extensions/ImageExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Xam.Forms.Markdown.Extensions 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Net; 7 | using SkiaSharp; 8 | using Xamarin.Forms; 9 | 10 | public static class ImageExtensions 11 | { 12 | public static void RenderSvg(this Image view, string uri) 13 | { 14 | try 15 | { 16 | var req = (HttpWebRequest)WebRequest.Create(uri); 17 | 18 | var svg = new SkiaSharp.Extended.Svg.SKSvg(); 19 | req.BeginGetResponse((ar) => 20 | { 21 | var res = (ar.AsyncState as HttpWebRequest).EndGetResponse(ar) as HttpWebResponse; 22 | using (var stream = res.GetResponseStream()) 23 | { 24 | if (stream != null) 25 | { 26 | var picture = svg.Load(stream); 27 | 28 | using (var image = SKImage.FromPicture(picture, picture.CullRect.Size.ToSizeI())) 29 | using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 80)) 30 | { 31 | var ms = new MemoryStream(); 32 | 33 | if (data != null && !data.IsEmpty) 34 | { 35 | data.SaveTo(ms); 36 | ms.Seek(0, SeekOrigin.Begin); 37 | ms.Position = 0; 38 | view.Source = ImageSource.FromStream(() => ms); 39 | } 40 | } 41 | } 42 | } 43 | }, req); 44 | 45 | } 46 | catch (Exception ex) 47 | { 48 | Debug.WriteLine($"Failed to render svg: {ex}"); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/Settings.XamlStyler: -------------------------------------------------------------------------------- 1 | { 2 | "AttributesTolerance": 2, 3 | "KeepFirstAttributeOnSameLine": false, 4 | "MaxAttributeCharactersPerLine": 0, 5 | "MaxAttributesPerLine": 1, 6 | "NewlineExemptionElements": "RadialGradientBrush, GradientStop, LinearGradientBrush, ScaleTransform, SkewTransform, RotateTransform, TranslateTransform, Trigger, Condition, Setter", 7 | "SeparateByGroups": false, 8 | "AttributeIndentation": 0, 9 | "AttributeIndentationStyle": 1, 10 | "RemoveDesignTimeReferences": false, 11 | "EnableAttributeReordering": true, 12 | "AttributeOrderingRuleGroups": [ 13 | "x:Class", 14 | "xmlns, xmlns:x, xmlns:d, xmlns:mc, mc:Ignorable", 15 | "xmlns:*", 16 | "prism:*", 17 | "x:Key, Key, x:Name, Name, x:Uid, Uid, Title, ControlTemplate", 18 | "Grid.Row, Grid.RowSpan, Grid.Column, Grid.ColumnSpan, RowSpacing, ColumnSpacing, Spacing, AbsoluteLayout.LayoutFlags, AbsoluteLayout.LayoutBounds", 19 | "BindingContext", 20 | "Text, Command, CommandParameter", 21 | "IsRefreshing, RefreshColor", 22 | "BindableLayout.ItemsSource, BindableLayout.ItemTemplateSelector", 23 | "IsVisible, WidthRequest, HeightRequest, MinimumWidthRequest, MinimumHeightRequest", 24 | "Margin, Padding, HorizontalOptions, VerticalOptions, HorizontalTextAlignment, VerticalTextAlignment", 25 | "FontSize, TextColor, BackgroundColor, CornerRadius", 26 | "*:*, *" 27 | ], 28 | "FirstLineAttributes": "x:Name, AutomationId", 29 | "OrderAttributesByName": true, 30 | "PutEndingBracketOnNewLine": false, 31 | "RemoveEndingTagOfEmptyElement": true, 32 | "SpaceBeforeClosingSlash": true, 33 | "RootElementLineBreakRule": 0, 34 | "ReorderVSM": 2, 35 | "ReorderGridChildren": true, 36 | "ReorderCanvasChildren": false, 37 | "ReorderSetters": 0, 38 | "FormatMarkupExtension": true, 39 | "NoNewLineMarkupExtensions": "x:Bind, Binding", 40 | "ThicknessSeparator": 2, 41 | "ThicknessAttributes": "Margin, Padding, BorderThickness, ThumbnailClipMargin", 42 | "FormatOnSave": true, 43 | "CommentPadding": 2, 44 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Markdown *for Xamarin.Forms* 2 | 3 | [![NuGet](https://img.shields.io/nuget/v/Xam.Forms.Markdown.svg?label=NuGet)](https://www.nuget.org/packages/Xam.Forms.Markdown/) [![Donate](https://img.shields.io/badge/donate-Buy%20Me%20a%20Coffe-%235F7FFF)](https://www.buymeacoffee.com/bares43)
4 | You can also support author of original package here [![Donate](https://img.shields.io/badge/donate-paypal-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ZJZKXPPGBKKAY&lc=US&item_name=GitHub&item_number=0000001¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted) 5 | 6 | A native Xamarin.Forms Markdown renderer. 7 | 8 | Fork of original repository https://github.com/dotnet-ad/MarkdownView with some improvements. 9 | 10 | ## Gallery 11 | 12 | ![Light theme](Documentation/Screenshot.png) 13 | 14 | ## Introduction 15 | 16 | Compared to a majority of solutions, MarkdownView will render every component as **a native Xamarin.Forms view instead of via an HTML backend.** The Markdown is directly translated from a syntax tree to a hierarchy of Xamarin.Forms views, : no HTML is being produced at all (hurray)! 17 | 18 | This will produce a more reactive user interface, at the cost of rendering functionalities *(at the moment though!)*. 19 | 20 | ## Install 21 | 22 | Available on [NuGet](https://www.nuget.org/packages/Xam.Forms.Markdown/). 23 | 24 | ## Quickstart 25 | 26 | See [documentation](https://github.com/bares43/MarkdownView/wiki#basic-usage). 27 | 28 | ## Thanks 29 | 30 | * [dotnet-ad/MarkdownView](https://github.com/dotnet-ad/MarkdownView) : original package 31 | * [lunet-io/markdig](https://github.com/lunet-io/markdig) : used for Markdown parsing 32 | * [mono/SkiaSharp](https://github.com/mono/SkiaSharp) : used for SVG rendering 33 | 34 | ## Contributions 35 | 36 | Contributions are welcome! If you find a bug please report it and if you want a feature please report it. 37 | 38 | If you want to contribute code please file an issue and create a branch off of the current dev branch and file a pull request. 39 | 40 | ## License 41 | 42 | MIT © [bares43](https://janbares.cz/en/), [Aloïs Deniel](http://aloisdeniel.github.io) 43 | -------------------------------------------------------------------------------- /Sources/Markdown.Samples/Views/SamplesPage.xaml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 |