diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.MoreMenu.cs b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.MoreMenu.cs
new file mode 100644
index 0000000..379e19b
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.MoreMenu.cs
@@ -0,0 +1,43 @@
+// Copyright © 2017-2026 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 .
+
+using QuickLook.Common.Commands;
+using QuickLook.Common.Controls;
+using QuickLook.Common.Helpers;
+using QuickLook.Common.Plugin;
+using QuickLook.Common.Plugin.MoreMenu;
+using System.Collections.Generic;
+using System.IO;
+
+namespace QuickLook.Plugin.CsvViewer;
+
+public sealed partial class Plugin : IViewer, IMoreMenu
+{
+ public IEnumerable MenuItems => GetMenuItems();
+
+ public IEnumerable GetMenuItems()
+ {
+ string translationFile = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Translations.config");
+
+ yield return new MoreMenuItem()
+ {
+ Icon = FontSymbols.Code,
+ Header = TranslationHelper.Get("MW_ReopenAsTextPreview", translationFile),
+ Command = new RelayCommand(() => PluginHelper.InvokePluginPreview("QuickLook.Plugin.TextViewer", _currentPath)),
+ };
+ }
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs
index 152ca29..75aa51b 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Plugin.cs
@@ -16,15 +16,17 @@
// along with this program. If not, see .
using QuickLook.Common.Plugin;
+using QuickLook.Common.Plugin.MoreMenu;
using System;
using System.IO;
using System.Windows;
namespace QuickLook.Plugin.CsvViewer;
-public sealed class Plugin : IViewer
+public sealed partial class Plugin : IViewer, IMoreMenu
{
private CsvViewerPanel _panel;
+ private string _currentPath;
public int Priority => 0;
@@ -49,6 +51,8 @@ public sealed class Plugin : IViewer
public void View(string path, ContextObject context)
{
+ _currentPath = path;
+
_panel = new CsvViewerPanel();
context.ViewerContent = _panel;
diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj
index 8b8c53e..fa49e7d 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj
+++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/QuickLook.Plugin.CsvViewer.csproj
@@ -83,6 +83,12 @@
+
+
+ PreserveNewest
+
+
+
Properties\GitVersion.cs
diff --git a/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Translations.config b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Translations.config
new file mode 100644
index 0000000..4be7791
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.CsvViewer/Translations.config
@@ -0,0 +1,91 @@
+
+
+
+
+ إعادة فتح كمعاينة نص
+
+
+ Torna a obrir com a previsualització de text
+
+
+ Als Text-Vorschau erneut öffnen
+
+
+ Reopen as text preview
+
+
+ Reabrir como vista previa de texto
+
+
+ Rouvrir en aperçu texte
+
+
+ Riapri come anteprima testo
+
+
+ テキストとして再度開く
+
+
+ 텍스트 미리보기로 다시 열기
+
+
+ Åpne på nytt som tekst-forhåndsvisning
+
+
+ Opnieuw openen als tekst-voorbeeld
+
+
+ Otwórz ponownie jako podgląd tekstu
+
+
+ Reabrir como visualização de texto
+
+
+ Reabrir como pré-visualização de texto
+
+
+ Redeschideți ca previzualizare text
+
+
+ Переоткрыть как предварительный просмотр текста
+
+
+ Metin önizlemesi olarak yeniden aç
+
+
+ Перевідкрити як попередній перегляд тексту
+
+
+ Mở lại dưới dạng xem trước văn bản
+
+
+ 重新作为文本预览打开
+
+
+ 重新作為文本預覽開啟
+
+
+ पुनः टेक्स्ट पूर्वावलोकन म्हणून उघडा
+
+
+ टेक्स्ट पूर्वावलोकन के रूप में फिर से खोलें
+
+
+ פתח מחדש כתצוגת טקסט
+
+
+ Újranyitás szöveg előnézetként
+
+
+ Buka ulang sebagai pratinjau teks
+
+
+ Znova otvoriť ako náhľad textu
+
+
+ Επανανοίξτε ως προεπισκόπηση κειμένου
+
+
+ Öppna på nytt som textförhandsgranskning
+
+
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs
index 358349f..5eee342 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Plugin.MoreMenu.cs
@@ -19,6 +19,7 @@ using QuickLook.Common.Commands;
using QuickLook.Common.Controls;
using QuickLook.Common.Helpers;
using QuickLook.Common.Plugin.MoreMenu;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
@@ -30,14 +31,16 @@ public sealed partial class Plugin
public IEnumerable GetMenuItems()
{
string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config");
- string extension = "";
+ string extension = string.Empty;
+
try
{
+ // Get the file extension in lowercase for comparison
extension = Path.GetExtension(_currentPath).ToLower();
- } catch (System.Exception)
- {
}
-
+ catch (Exception)
+ {
+ }
var reopen = extension switch
{
@@ -58,6 +61,14 @@ public sealed partial class Plugin
Header = TranslationHelper.Get("MW_ReopenAsImagePreview", translationFile),
Command = new RelayCommand(() => PluginHelper.InvokePluginPreview("QuickLook.Plugin.ImageViewer", _currentPath)),
},
+
+ // CSV, TSV, PSV <=> CSV viewer
+ ".csv" or ".tsv" or ".psv" => new MoreMenuItem()
+ {
+ Icon = FontSymbols.Code,
+ Header = TranslationHelper.Get("MW_ReopenAsCsvPreview", translationFile),
+ Command = new RelayCommand(() => PluginHelper.InvokePluginPreview("QuickLook.Plugin.CsvViewer", _currentPath)),
+ },
_ => null,
};
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/CSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/CSVHighlightingDefinition.cs
new file mode 100644
index 0000000..1f9e903
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/CSVHighlightingDefinition.cs
@@ -0,0 +1,94 @@
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Rendering;
+using System.Windows.Media;
+
+namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark;
+
+///
+/// Rainbow CSV Highlighting Definition
+///
+public class CSVHighlightingDefinition : DarkHighlightingDefinition
+{
+ public override string Name => "CSV";
+
+ public override string Extension => ".csv";
+
+ public override DocumentColorizingTransformer[] LineTransformers { get; } = [new RainbowTransformer(',')];
+
+ public class RainbowTransformer(char sep) : DocumentColorizingTransformer
+ {
+ private readonly char _sep = sep;
+
+ private readonly Brush[] _brushes =
+ [
+ Colors.OrangeRed.ToBrush(),
+ Colors.CornflowerBlue.ToBrush(),
+ Colors.LimeGreen.ToBrush(),
+ Colors.MediumVioletRed.ToBrush(),
+ Colors.Peru.ToBrush(),
+ Colors.CadetBlue.ToBrush(),
+ Colors.Khaki.ToBrush(),
+ Colors.MediumSlateBlue.ToBrush(),
+ ];
+
+ protected override void ColorizeLine(DocumentLine line)
+ {
+ var text = CurrentContext.Document.GetText(line);
+ if (string.IsNullOrEmpty(text))
+ return;
+
+ int offset = line.Offset;
+ int i = 0;
+ int col = 0;
+ int len = text.Length;
+
+ while (i < len)
+ {
+ int contentStart = i;
+ int contentEnd = i;
+
+ if (text[i] == '"')
+ {
+ contentStart = i + 1;
+ i++;
+ while (i < len)
+ {
+ if (text[i] == '"')
+ {
+ if (i + 1 < len && text[i + 1] == '"')
+ {
+ i += 2;
+ continue;
+ }
+ else
+ {
+ contentEnd = i;
+ i++;
+ break;
+ }
+ }
+ i++;
+ }
+ while (i < len && text[i] != _sep) i++;
+ }
+ else
+ {
+ contentStart = i;
+ while (i < len && text[i] != _sep) i++;
+ contentEnd = i;
+ }
+
+ if (contentEnd > contentStart)
+ {
+ int a = offset + contentStart;
+ int b = offset + contentEnd;
+ var brush = _brushes[col % _brushes.Length];
+ ChangeLinePart(a, b, el => el.TextRunProperties.SetForegroundBrush(brush));
+ }
+
+ if (i < len && text[i] == _sep) i++;
+ col++;
+ }
+ }
+ }
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PSVHighlightingDefinition.cs
new file mode 100644
index 0000000..88b71d5
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PSVHighlightingDefinition.cs
@@ -0,0 +1,15 @@
+using ICSharpCode.AvalonEdit.Rendering;
+
+namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark;
+
+///
+/// Rainbow PSV Highlighting Definition
+///
+public class PSVHighlightingDefinition : DarkHighlightingDefinition
+{
+ public override string Name => "PSV";
+
+ public override string Extension => ".psv";
+
+ public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('|')];
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/TSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/TSVHighlightingDefinition.cs
new file mode 100644
index 0000000..a645c91
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/TSVHighlightingDefinition.cs
@@ -0,0 +1,15 @@
+using ICSharpCode.AvalonEdit.Rendering;
+
+namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark;
+
+///
+/// Rainbow TSV Highlighting Definition
+///
+public class TSVHighlightingDefinition : DarkHighlightingDefinition
+{
+ public override string Name => "TSV";
+
+ public override string Extension => ".tsv";
+
+ public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('\t')];
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/CSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/CSVHighlightingDefinition.cs
new file mode 100644
index 0000000..e91b960
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/CSVHighlightingDefinition.cs
@@ -0,0 +1,102 @@
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Rendering;
+using System.Windows.Media;
+
+namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light;
+
+///
+/// Rainbow CSV Highlighting Definition
+///
+public class CSVHighlightingDefinition : LightHighlightingDefinition
+{
+ public override string Name => "CSV";
+
+ public override string Extension => ".csv";
+
+ public override DocumentColorizingTransformer[] LineTransformers { get; } = [new RainbowTransformer(',')];
+
+ public class RainbowTransformer(char sep) : DocumentColorizingTransformer
+ {
+ private readonly char _sep = sep;
+
+ private readonly Brush[] _brushes =
+ [
+ Colors.DarkRed.ToBrush(),
+ Colors.DarkBlue.ToBrush(),
+ Colors.DarkGreen.ToBrush(),
+ Colors.DarkMagenta.ToBrush(),
+ Colors.SaddleBrown.ToBrush(),
+ Colors.Teal.ToBrush(),
+ Colors.Olive.ToBrush(),
+ Colors.SlateBlue.ToBrush(),
+ ];
+
+ protected override void ColorizeLine(DocumentLine line)
+ {
+ var text = CurrentContext.Document.GetText(line);
+ if (string.IsNullOrEmpty(text))
+ return;
+
+ int offset = line.Offset;
+ int i = 0;
+ int col = 0;
+ int len = text.Length;
+
+ while (i < len)
+ {
+ int fieldStart = i;
+ int contentStart = i;
+ int contentEnd = i;
+
+ if (text[i] == '"')
+ {
+ // quoted field
+ contentStart = i + 1;
+ i++;
+ while (i < len)
+ {
+ if (text[i] == '"')
+ {
+ if (i + 1 < len && text[i + 1] == '"')
+ {
+ // escaped quote
+ i += 2;
+ continue;
+ }
+ else
+ {
+ // end quote
+ contentEnd = i;
+ i++;
+ break;
+ }
+ }
+ i++;
+ }
+ // skip to separator
+ while (i < len && text[i] != _sep) i++;
+ }
+ else
+ {
+ // unquoted
+ contentStart = i;
+ while (i < len && text[i] != _sep) i++;
+ contentEnd = i;
+ }
+
+ // color content [contentStart, contentEnd)
+ if (contentEnd > contentStart)
+ {
+ int a = offset + contentStart;
+ int b = offset + contentEnd;
+ var brush = _brushes[col % _brushes.Length];
+ ChangeLinePart(a, b, el => el.TextRunProperties.SetForegroundBrush(brush));
+ }
+
+ // advance past separator
+ if (i < len && text[i] == _sep) i++;
+ col++;
+ }
+ }
+ }
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PSVHighlightingDefinition.cs
new file mode 100644
index 0000000..1d0f270
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PSVHighlightingDefinition.cs
@@ -0,0 +1,15 @@
+using ICSharpCode.AvalonEdit.Rendering;
+
+namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light;
+
+///
+/// Rainbow PSV Highlighting Definition
+///
+public class PSVHighlightingDefinition : LightHighlightingDefinition
+{
+ public override string Name => "PSV";
+
+ public override string Extension => ".psv";
+
+ public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('|')];
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/TSVHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/TSVHighlightingDefinition.cs
new file mode 100644
index 0000000..6f7ed97
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/TSVHighlightingDefinition.cs
@@ -0,0 +1,15 @@
+using ICSharpCode.AvalonEdit.Rendering;
+
+namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light;
+
+///
+/// Rainbow TSV Highlighting Definition
+///
+public class TSVHighlightingDefinition : LightHighlightingDefinition
+{
+ public override string Name => "TSV";
+
+ public override string Extension => ".tsv";
+
+ public override DocumentColorizingTransformer[] LineTransformers { get; } = [new CSVHighlightingDefinition.RainbowTransformer('\t')];
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config
index 52a95a7..71bbc18 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config
+++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Translations.config
@@ -7,6 +7,7 @@
حدد الكل
إعادة فتح كمعاينة HTML
إعادة فتح كمعاينة صورة
+ إعادة فتح كمعاينة CSV
Consolas
@@ -14,6 +15,7 @@
Selecciona-ho tot
Torna a obrir com a previsualització HTML
Torna a obrir com a previsualització d'imatge
+ Torna a obrir com a previsualització CSV
Consolas
@@ -21,6 +23,7 @@
Alles markieren
Als HTML-Vorschau erneut öffnen
Als Bildvorschau erneut öffnen
+ Als CSV-Vorschau erneut öffnen
Consolas
@@ -28,6 +31,7 @@
Select All
Reopen as HTML preview
Reopen as image preview
+ Reopen as CSV preview
Consolas
@@ -35,6 +39,7 @@
Seleccionar Todo
Reabrir como vista previa HTML
Reabrir como vista previa de imagen
+ Reabrir como vista previa CSV
Consolas
@@ -42,6 +47,7 @@
Tout sélectionner
Rouvrir en aperçu HTML
Rouvrir en aperçu d'image
+ Rouvrir en aperçu CSV
Consolas
@@ -49,6 +55,7 @@
Seleziona tutto
Riapri come anteprima HTML
Riapri come anteprima immagine
+ Riapri come anteprima CSV
Consolas,Meiryo UI,MS UI Gothic,MS Gothic
@@ -56,6 +63,7 @@
すべて選択
HTML プレビューとして再度開く
画像プレビューとして再度開く
+ CSV プレビューとして再度開く
Consolas,Malgun Gothic,Gulim
@@ -63,6 +71,7 @@
모두 선택
HTML 미리보기로 다시 열기
이미지 미리보기로 다시 열기
+ CSV 미리보기로 다시 열기
Consolas
@@ -70,6 +79,7 @@
Merk alt
Åpne på nytt som HTML-forhåndsvisning
Åpne på nytt som bilde-forhåndsvisning
+ Åpne på nytt som CSV-forhåndsvisning
Consolas
@@ -77,6 +87,7 @@
Alles selecteren
Opnieuw openen als HTML-voorbeeld
Opnieuw openen als afbeelding-voorbeeld
+ Opnieuw openen als CSV-voorbeeld
Consolas
@@ -84,6 +95,7 @@
Zaznacz wszystko
Otwórz ponownie jako podgląd HTML
Otwórz ponownie jako podgląd obrazu
+ Otwórz ponownie jako podgląd CSV
Consolas
@@ -91,6 +103,7 @@
Selecionar tudo
Reabrir como visualização HTML
Reabrir como visualização de imagem
+ Reabrir como visualização CSV
Consolas
@@ -98,6 +111,7 @@
Selecionar tudo
Reabrir como pré-visualização HTML
Reabrir como pré-visualização de imagem
+ Reabrir como pré-visualização CSV
Consolas
@@ -105,6 +119,7 @@
Selectați tot
Redeschideți ca previzualizare HTML
Redeschideți ca previzualizare imagine
+ Redeschideți ca previzualizare CSV
Consolas
@@ -112,6 +127,7 @@
Выделить всё
Переоткрыть как предварительный просмотр HTML
Переоткрыть как предварительный просмотр изображения
+ Переоткрыть как предварительный просмотр CSV
Consolas
@@ -119,6 +135,7 @@
Tümünü seç
HTML önizlemesi olarak yeniden aç
Resim önizlemesi olarak yeniden aç
+ CSV önizlemesi olarak yeniden aç
Consolas
@@ -126,6 +143,7 @@
Виділити Все
Перевідкрити як попередній перегляд HTML
Перевідкрити як попередній перегляд зображення
+ Перевідкрити як попередній перегляд CSV
Consolas
@@ -133,6 +151,7 @@
Chọn tất cả
Mở lại dưới dạng xem trước HTML
Mở lại dưới dạng xem trước hình ảnh
+ Mở lại dưới dạng xem trước CSV
Consolas,Microsoft Yahei UI,Microsoft Yahei,SimSun
@@ -140,6 +159,7 @@
全选
重新作为 HTML 预览打开
重新作为图像预览打开
+ 重新作为 CSV 预览打开
Consolas,Microsoft JhengHei UI,Microsoft JhengHei,MingLiU