No markdown resource extraction #1661 #1670

This commit is contained in:
ema
2025-06-24 01:33:07 +08:00
parent 741d9967d1
commit 83ae611af1
8 changed files with 192 additions and 626 deletions

View File

@@ -31,10 +31,10 @@ namespace QuickLook.Plugin.HtmlViewer;
public class WebpagePanel : UserControl public class WebpagePanel : UserControl
{ {
private Uri _currentUri; protected Uri _currentUri;
private string _primaryPath; protected string _primaryPath;
private string _fallbackPath; protected string _fallbackPath;
private WebView2 _webView; protected WebView2 _webView;
public string FallbackPath public string FallbackPath
{ {
@@ -54,11 +54,11 @@ public class WebpagePanel : UserControl
{ {
CreationProperties = new CoreWebView2CreationProperties CreationProperties = new CoreWebView2CreationProperties
{ {
UserDataFolder = Path.Combine(SettingHelper.LocalDataPath, @"WebView2_Data\\"), UserDataFolder = Path.Combine(SettingHelper.LocalDataPath, @"WebView2_Data\"),
}, },
DefaultBackgroundColor = OSThemeHelper.AppsUseDarkTheme() ? Color.FromArgb(255, 32, 32, 32) : Color.White, // Prevent white flash in dark mode DefaultBackgroundColor = OSThemeHelper.AppsUseDarkTheme() ? Color.FromArgb(255, 32, 32, 32) : Color.White, // Prevent white flash in dark mode
}; };
_webView.NavigationStarting += NavigationStarting_CancelNavigation; _webView.NavigationStarting += Webview_NavigationStarting;
_webView.NavigationCompleted += WebView_NavigationCompleted; _webView.NavigationCompleted += WebView_NavigationCompleted;
_webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted; _webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
Content = _webView; Content = _webView;
@@ -97,7 +97,7 @@ public class WebpagePanel : UserControl
.ContinueWith(_ => Dispatcher.Invoke(() => _webView?.NavigateToString(html))); .ContinueWith(_ => Dispatcher.Invoke(() => _webView?.NavigateToString(html)));
} }
private void NavigationStarting_CancelNavigation(object sender, CoreWebView2NavigationStartingEventArgs e) protected virtual void Webview_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
{ {
if (e.Uri.StartsWith("data:")) // when using NavigateToString if (e.Uri.StartsWith("data:")) // when using NavigateToString
return; return;
@@ -163,12 +163,12 @@ public class WebpagePanel : UserControl
} }
} }
private void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e) protected virtual void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{ {
_webView.DefaultBackgroundColor = Color.White; // Reset to white after page load to match expected default behavior _webView.DefaultBackgroundColor = Color.White; // Reset to white after page load to match expected default behavior
} }
private void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) protected virtual void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{ {
if (e.IsSuccess) if (e.IsSuccess)
{ {

View File

@@ -1,54 +0,0 @@
param(
[Parameter(Mandatory=$true)]
[string]$ResourcesDir,
[Parameter(Mandatory=$true)]
[string]$OutputFile
)
# Get all files in the Resources directory
$files = Get-ChildItem -Path $ResourcesDir -Recurse -File | Sort-Object -Property FullName
# Create SHA256 hasher
$sha256 = [System.Security.Cryptography.SHA256]::Create()
# Create memory stream to combine all file contents
$memoryStream = New-Object System.IO.MemoryStream
# Add each file's path and contents to the hash
foreach ($file in $files) {
# Get relative path and convert to lowercase for consistent hashing
$relativePath = $file.FullName.Substring($ResourcesDir.Length + 1).ToLowerInvariant()
$pathBytes = [System.Text.Encoding]::UTF8.GetBytes("QuickLook.Plugin.MarkdownViewer.Resources.$relativePath".Replace("\", "/"))
$memoryStream.Write($pathBytes, 0, $pathBytes.Length)
# Add file contents
$fileBytes = [System.IO.File]::ReadAllBytes($file.FullName)
$memoryStream.Write($fileBytes, 0, $fileBytes.Length)
}
# Calculate final hash
$hashBytes = $sha256.ComputeHash($memoryStream.ToArray())
$hash = [BitConverter]::ToString($hashBytes).Replace("-", "").ToLowerInvariant()
# Generate C# code
$code = @"
// <auto-generated>
// This file was generated during build to indicate changes to embedded resources.
// </auto-generated>
namespace QuickLook.Plugin.MarkdownViewer
{
internal static class EmbeddedResourcesHash
{
internal const string Hash = "$hash";
}
}
"@
# Write to output file
[System.IO.File]::WriteAllText($OutputFile, $code)
# Cleanup
$memoryStream.Dispose()
$sha256.Dispose()

View File

@@ -0,0 +1,172 @@
// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Microsoft.Web.WebView2.Core;
using QuickLook.Plugin.HtmlViewer;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UtfUnknown;
namespace QuickLook.Plugin.MarkdownViewer;
public class MarkdownPanel : WebpagePanel
{
protected const string _resourcePrefix = "QuickLook.Plugin.MarkdownViewer.Resources.";
protected internal static readonly Dictionary<string, byte[]> _resources = [];
protected byte[] _homePage;
static MarkdownPanel()
{
InitializeResources();
}
protected static void InitializeResources()
{
if (_resources.Any()) return;
var assembly = Assembly.GetExecutingAssembly();
foreach (var resourceName in assembly.GetManifestResourceNames())
{
if (!resourceName.StartsWith(_resourcePrefix)) continue;
var relativePath = resourceName.Substring(_resourcePrefix.Length);
if (relativePath.Equals("resources", StringComparison.OrdinalIgnoreCase)) continue;
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null) continue;
var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
_resources.Add($"/{relativePath.Replace('\\', '/')}", memoryStream.ToArray());
}
}
public void PreviewMarkdown(string path)
{
FallbackPath = Path.GetDirectoryName(path);
var html = GenerateMarkdownHtml(path);
byte[] bytes = Encoding.UTF8.GetBytes(html);
_homePage = bytes;
NavigateToUri(new Uri("file://quicklook/"));
}
protected string GenerateMarkdownHtml(string path)
{
var bytes = File.ReadAllBytes(path);
var encoding = CharsetDetector.DetectFromBytes(bytes).Detected?.Encoding ?? Encoding.Default;
var content = encoding.GetString(bytes);
var template = ReadString("/md2html.html");
var html = template.Replace("{{content}}", content);
return html;
}
protected override void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
if (e.IsSuccess)
{
_webView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
_webView.CoreWebView2.WebResourceRequested += (sender, args) =>
{
Debug.WriteLine($"[{args.Request.Method}] {args.Request.Uri}");
try
{
var requestedUri = new Uri(args.Request.Uri);
if (requestedUri.Scheme == "file")
{
if (requestedUri.AbsolutePath == "/")
{
var response = _webView.CoreWebView2.Environment.CreateWebResourceResponse(
new MemoryStream(_homePage), 200, "OK", MimeTypes.GetContentType(".html"));
args.Response = response;
}
else if (ContainsKey(requestedUri.AbsolutePath))
{
var stream = ReadStream(requestedUri.AbsolutePath);
var response = _webView.CoreWebView2.Environment.CreateWebResourceResponse(
stream, 200, "OK", MimeTypes.GetContentType(Path.GetExtension(requestedUri.AbsolutePath)));
args.Response = response;
}
else
{
var localPath = _fallbackPath + requestedUri.AbsolutePath.Replace('/', '\\');
if (File.Exists(localPath))
{
var fileStream = File.OpenRead(localPath);
var response = _webView.CoreWebView2.Environment.CreateWebResourceResponse(
fileStream, 200, "OK", MimeTypes.GetContentType());
args.Response = response;
}
}
}
}
catch (Exception e)
{
// We don't need to feel burdened by any exceptions
Debug.WriteLine(e);
}
};
}
}
public static bool ContainsKey(string key)
{
return _resources.ContainsKey(key);
}
public static Stream ReadStream(string key)
{
byte[] bytes = _resources[key];
return new MemoryStream(bytes);
}
public static string ReadString(string key)
{
using var reader = new StreamReader(ReadStream(key), Encoding.UTF8);
return reader.ReadToEnd();
}
public static class MimeTypes
{
public const string Html = "text/html";
public const string JavaScript = "application/javascript";
public const string Css = "text/css";
public const string Binary = "application/octet-stream";
public static string GetContentType(string extension = null) => $"Content-Type: {GetMimeType(extension)}";
public static string GetMimeType(string extension = null) => extension?.ToLowerInvariant() switch
{
".js" => JavaScript, // Only handle known extensions from resources
".css" => Css,
".html" => Html,
_ => Binary,
};
}
}

View File

@@ -15,25 +15,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using QuickLook.Common.Helpers;
using QuickLook.Common.Plugin; using QuickLook.Common.Plugin;
using QuickLook.Plugin.HtmlViewer;
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Threading;
using UtfUnknown;
namespace QuickLook.Plugin.MarkdownViewer; namespace QuickLook.Plugin.MarkdownViewer;
public class Plugin : IViewer public class Plugin : IViewer
{ {
private bool _isInitialized = false; private MarkdownPanel? _panel;
private WebpagePanel? _panel;
private string? _currentHtmlPath;
/// <summary> /// <summary>
/// Markdown and Markdown-like extensions /// Markdown and Markdown-like extensions
@@ -52,25 +44,10 @@ public class Plugin : IViewer
".mdtxt", ".mdtext", // Less common ".mdtxt", ".mdtext", // Less common
]; ];
private static readonly string _resourcePath = Path.Combine(SettingHelper.LocalDataPath, "QuickLook.Plugin.MarkdownViewer");
private static readonly string _resourcePrefix = "QuickLook.Plugin.MarkdownViewer.Resources.";
private static readonly ResourceManager _resourceManager = new(_resourcePath, _resourcePrefix);
public int Priority => 0; public int Priority => 0;
public void Init() public void Init()
{ {
// Delayed initialization can speed up startup
_isInitialized = false;
}
public void InitializeResources()
{
// Initialize resources and handle versioning
_resourceManager.InitializeResources();
// Clean up any temporary HTML files if QuickLook was forcibly terminated
CleanupTempFiles();
} }
public bool CanHandle(string path) public bool CanHandle(string path)
@@ -85,97 +62,19 @@ public class Plugin : IViewer
public void View(string path, ContextObject context) public void View(string path, ContextObject context)
{ {
if (!_isInitialized) _panel = new MarkdownPanel();
{ _panel.PreviewMarkdown(path);
_isInitialized = true;
InitializeResources();
}
_panel = new WebpagePanel();
context.ViewerContent = _panel; context.ViewerContent = _panel;
context.Title = Path.GetFileName(path); context.Title = Path.GetFileName(path);
context.IsBusy = false;
var htmlPath = GenerateMarkdownHtml(path);
_panel.FallbackPath = Path.GetDirectoryName(path);
_panel.NavigateToFile(htmlPath);
_panel.Dispatcher.Invoke(() => { context.IsBusy = false; }, DispatcherPriority.Loaded);
}
private string GenerateMarkdownHtml(string path)
{
var templatePath = Path.Combine(_resourcePath, "md2html.html");
if (!File.Exists(templatePath))
throw new FileNotFoundException($"Required template file md2html.html not found in extracted resources at {templatePath}");
var bytes = File.ReadAllBytes(path);
var encoding = CharsetDetector.DetectFromBytes(bytes).Detected?.Encoding ?? Encoding.Default;
var content = encoding.GetString(bytes);
var template = File.ReadAllText(templatePath);
var html = template.Replace("{{content}}", content);
// Generate unique filename and ensure it doesn't exist
string outputPath;
do
{
var uniqueId = Guid.NewGuid().ToString("N").Substring(0, 8);
var outputFileName = $"temp_{uniqueId}.html";
outputPath = Path.Combine(_resourcePath, outputFileName);
} while (File.Exists(outputPath));
// Clean up previous file if it exists
CleanupTempHtmlFile();
File.WriteAllText(outputPath, html);
_currentHtmlPath = outputPath;
return outputPath;
}
#region Cleanup
private void CleanupTempHtmlFile()
{
if (!string.IsNullOrEmpty(_currentHtmlPath) && File.Exists(_currentHtmlPath))
{
try
{
File.Delete(_currentHtmlPath);
}
catch (IOException) { } // Ignore deletion errors
}
}
private void CleanupTempFiles()
{
try
{
var tempFiles = Directory.GetFiles(_resourcePath, "temp_*.html");
foreach (var file in tempFiles)
{
try
{
File.Delete(file);
}
catch (IOException) { } // Ignore deletion errors
}
}
catch (Exception ex)
{
Debug.WriteLine($"Failed to clean up temporary HTML files: {ex.Message}");
}
} }
public void Cleanup() public void Cleanup()
{ {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
CleanupTempHtmlFile();
_panel?.Dispose(); _panel?.Dispose();
_panel = null; _panel = null;
} }
#endregion Cleanup
} }

View File

@@ -9,7 +9,6 @@
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
@@ -77,30 +76,18 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3240.44">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\**\*"> <EmbeddedResource Include="Resources\**\*">
<LogicalName>QuickLook.Plugin.MarkdownViewer.Resources.%(RecursiveDir)%(Filename)%(Extension)</LogicalName> <LogicalName>QuickLook.Plugin.MarkdownViewer.Resources.%(RecursiveDir)%(Filename)%(Extension)</LogicalName>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<Target Name="GenerateEmbeddedResourcesHash" BeforeTargets="CoreCompile">
<PropertyGroup>
<HashFileDir>$(IntermediateOutputPath)Generated</HashFileDir>
<HashFilePath>$(HashFileDir)\EmbeddedResourcesHash.cs</HashFilePath>
</PropertyGroup>
<!-- Create the output directory -->
<MakeDir Directories="$(HashFileDir)" />
<!-- Run a script to calculate hash and generate code file -->
<Exec Command="powershell.exe -NoProfile -ExecutionPolicy Bypass -File &quot;$(MSBuildThisFileDirectory)GenerateEmbeddedResourcesHash.ps1&quot; -ResourcesDir &quot;$(MSBuildThisFileDirectory)Resources&quot; -OutputFile &quot;$(HashFilePath)&quot;" />
<!-- Include the generated file in compilation -->
<ItemGroup>
<Compile Include="$(HashFilePath)" />
</ItemGroup>
</Target>
<ItemGroup> <ItemGroup>
<Compile Include="..\..\GitVersion.cs"> <Compile Include="..\..\GitVersion.cs">
<Link>Properties\GitVersion.cs</Link> <Link>Properties\GitVersion.cs</Link>

View File

@@ -1,235 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
namespace QuickLook.Plugin.MarkdownViewer;
internal class ResourceManager
{
private readonly string _resourcePath;
private readonly string _resourcePrefix;
private readonly string _versionFilePath;
private readonly string _noUpdateFilePath;
private readonly string _embeddedHash;
public ResourceManager(string resourcePath, string resourcePrefix)
{
_resourcePath = resourcePath;
_resourcePrefix = resourcePrefix;
_versionFilePath = Path.Combine(_resourcePath, ".version");
_noUpdateFilePath = Path.Combine(_resourcePath, ".noupdate");
_embeddedHash = GetEmbeddedResourcesHash();
}
public void InitializeResources()
{
// Extract resources for the first time
if (!Directory.Exists(_resourcePath))
{
ExtractResources();
return;
}
// Check if updates are disabled
if (File.Exists(_noUpdateFilePath))
return;
// Check if resources need updating by comparing hashes
var versionInfo = ReadVersionFile();
if (versionInfo == null)
{
// No version file exists, create it and extract resources
ExtractResources();
return;
}
// If embedded hash matches stored hash, no update needed
if (_embeddedHash == versionInfo.EmbeddedHash) return;
// Calculate current directory hash
var currentDirectoryHash = CalculateDirectoryHash(_resourcePath);
// If current directory matches the stored extracted hash, user hasn't modified files
if (currentDirectoryHash == versionInfo.ExtractedHash)
{
// Safe to update
ExtractResources();
return;
}
// User has modified files, ask for permission to update
var result = MessageBox.Show(
"The MarkdownViewer resources have been updated. Would you like to update to the newest version?\n\n" +
"Note: Your current resources appear to have been modified. Updating will overwrite your modifications.",
"MarkdownViewer Update Available",
MessageBoxButton.YesNo,
MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
ExtractResources();
}
else
{
// Update the embedded hash in the version file to prevent any more prompts for this version
UpdateVersionFileEmbeddedHash();
}
}
private void ExtractResources()
{
// Delete and recreate directory to ensure clean state
if (Directory.Exists(_resourcePath))
{
try
{
Directory.Delete(_resourcePath, true);
}
catch (Exception ex)
{
Debug.WriteLine($"Failed to delete directory {_resourcePath}: {ex.Message}");
// If we can't delete the directory, we'll try to continue with existing one
}
}
Directory.CreateDirectory(_resourcePath);
var assembly = Assembly.GetExecutingAssembly();
var resourceNames = assembly.GetManifestResourceNames();
foreach (var resourceName in resourceNames)
{
if (!resourceName.StartsWith(_resourcePrefix)) continue;
var relativePath = resourceName.Substring(_resourcePrefix.Length);
if (relativePath.Equals("resources", StringComparison.OrdinalIgnoreCase)) continue; // Skip 'resources' binary file
var targetPath = Path.Combine(_resourcePath, relativePath.Replace('/', Path.DirectorySeparatorChar));
// Create directory if it doesn't exist
var directory = Path.GetDirectoryName(targetPath);
if (directory != null)
Directory.CreateDirectory(directory);
// Extract the resource
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var fileStream = File.Create(targetPath))
{
if (stream == null) continue;
stream.CopyTo(fileStream);
}
}
// Generate version file after extracting all resources
GenerateVersionFile();
// Verify that md2html.html was extracted
var htmlPath = Path.Combine(_resourcePath, "md2html.html");
if (!File.Exists(htmlPath))
{
throw new FileNotFoundException($"Required template file md2html.html not found in resources. Available resources: {string.Join(", ", resourceNames)}");
}
}
private class VersionInfo(string embeddedHash, string extractedHash)
{
public string EmbeddedHash { get; set; } = embeddedHash;
public string ExtractedHash { get; set; } = extractedHash;
}
private static string CalculateDirectoryHash(string directory)
{
var files = Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories)
.Where(f => !f.EndsWith(".version"))
.OrderBy(f => f)
.ToList();
using (var sha256 = SHA256.Create())
{
var combinedBytes = new List<byte>();
foreach (var file in files)
{
var relativePath = file.Substring(directory.Length + 1);
var pathBytes = Encoding.UTF8.GetBytes(relativePath.ToLowerInvariant());
combinedBytes.AddRange(pathBytes);
var contentBytes = File.ReadAllBytes(file);
combinedBytes.AddRange(contentBytes);
}
var hash = sha256.ComputeHash([.. combinedBytes]);
return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
}
}
private string GetEmbeddedResourcesHash()
{
try
{
return EmbeddedResourcesHash.Hash;
}
catch (Exception)
{
Debug.WriteLine("QuickLook.Plugin.MarkdownViewer: Embedded resources hash file not found.");
return CalculateEmbeddedResourcesHash();
}
}
private string CalculateEmbeddedResourcesHash()
{
var assembly = Assembly.GetExecutingAssembly();
using var sha256 = SHA256.Create();
var combinedBytes = new List<byte>();
var resourceNames = assembly.GetManifestResourceNames()
.Where(name => name.StartsWith(_resourcePrefix) &&
!name.EndsWith(".version"))
.OrderBy(name => name)
.ToList();
foreach (var resourceName in resourceNames)
{
var nameBytes = Encoding.UTF8.GetBytes(resourceName.ToLowerInvariant());
combinedBytes.AddRange(nameBytes);
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null) continue;
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
combinedBytes.AddRange(buffer);
}
var hash = sha256.ComputeHash([.. combinedBytes]);
return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
}
private void GenerateVersionFile()
{
var extractedHash = CalculateDirectoryHash(_resourcePath);
var newVersionContent = $"{_embeddedHash}{Environment.NewLine}{extractedHash}";
File.WriteAllText(_versionFilePath, newVersionContent);
}
private void UpdateVersionFileEmbeddedHash()
{
var versionInfo = ReadVersionFile() ?? throw new InvalidOperationException("Cannot update version file: no existing version file found");
var newVersionContent = $"{_embeddedHash}{Environment.NewLine}{versionInfo.ExtractedHash}";
File.WriteAllText(_versionFilePath, newVersionContent);
}
private VersionInfo? ReadVersionFile()
{
if (!File.Exists(_versionFilePath)) return null;
var lines = File.ReadAllLines(_versionFilePath);
if (lines.Length < 2) return null;
return new VersionInfo(lines[0], lines[1]);
}
}

View File

@@ -1,79 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace QuickLook.Plugin.MarkdownViewer {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("QuickLook.Plugin.MarkdownViewer.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to &lt;!DOCTYPE html&gt;
///&lt;html&gt;
/// &lt;head&gt;
/// &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
/// &lt;/head&gt;
/// &lt;body&gt;
/// &lt;textarea id=&quot;text-input&quot; style=&quot;display:none;&quot;&gt;{{content}}&lt;/textarea&gt;
/// &lt;style&gt;&lt;!-- https://github.com/sindresorhus/github-markdown-css --&gt;.markdown-body hr::after,.markdown-body::after{clear:both}@font-face{font-family:octicons-link;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAA [rest of string was truncated]&quot;;.
/// </summary>
internal static string md2html {
get {
return ResourceManager.GetString("md2html", resourceCulture);
}
}
}
}

View File

@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="md2html" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\md2html.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>