1
0
Fork 0

초기 커밋: Phase 1 — 레지스트리 기반 컨텍스트 메뉴 + 핵심 변환 파이프라인

- Provider 추상화(IConverterProvider + ProviderCapability) — Available/RequiresExternal/ComingSoon 1급 시민
- 변환 구현: Magick(이미지·RAW·GIF·TIFF), HEIC/HEIF(libheif decode→Magick encode), PDF(PDFium), DOCX(Word COM 또는 LibreOffice 자동 감지)
- ComingSoon 스텁: HTML, HWP/HWPX (UI 노출, 컨텍스트 메뉴 등록 자동 제외)
- WPF + WPF-UI 4.3 Fluent 2 UI: 메인 창(드래그&드롭, Provider 카드), 변환 창(썸네일·옵션·진행률), 빠른 변환 진행 창, 진단 창
- 단일 EXE에 verb 라우팅: quick / dialog / register / unregister / diagnose / help
- HKCU SystemFileAssociations 기반 컨텍스트 메뉴 등록 (Win11 "추가 옵션 표시"에 노출)
- README, packaging/ Phase 2 placeholder 포함

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yun Chan 2026-05-06 12:50:35 +09:00
commit 8fa4a613d7
37 changed files with 2727 additions and 0 deletions

View file

@ -0,0 +1,49 @@
namespace EverythingToJpeg.Core;
internal static class OutputPathHelper
{
public static string ResolveOutputPath(
string outputDirectory,
string baseName,
string? pageSuffix,
NameCollision collision)
{
var safe = SanitizeFileName(baseName);
var fileName = string.IsNullOrEmpty(pageSuffix) ? $"{safe}.jpg" : $"{safe}{pageSuffix}.jpg";
var fullPath = Path.Combine(outputDirectory, fileName);
if (!File.Exists(fullPath)) return fullPath;
switch (collision)
{
case NameCollision.Overwrite:
return fullPath;
case NameCollision.Skip:
return fullPath;
case NameCollision.AppendNumber:
default:
for (var i = 1; i < 10000; i++)
{
var candidate = string.IsNullOrEmpty(pageSuffix)
? Path.Combine(outputDirectory, $"{safe} ({i}).jpg")
: Path.Combine(outputDirectory, $"{safe}{pageSuffix} ({i}).jpg");
if (!File.Exists(candidate)) return candidate;
}
return fullPath;
}
}
public static bool ShouldSkip(string finalPath, NameCollision collision)
=> collision == NameCollision.Skip && File.Exists(finalPath);
private static string SanitizeFileName(string name)
{
var invalid = Path.GetInvalidFileNameChars();
Span<char> buffer = stackalloc char[name.Length];
for (var i = 0; i < name.Length; i++)
{
buffer[i] = Array.IndexOf(invalid, name[i]) >= 0 ? '_' : name[i];
}
return new string(buffer);
}
}