Immagini: percorsi relativi cercati nelle cartelle superiori (radice della wiki)

Il motore scrive i percorsi relativi alla radice del progetto (es. la wiki
cyber-tesi con l'exe in una sottocartella): ora si cercano nella cartella
dell'exe e poi in quelle superiori, vince la più vicina. Il catalogo JSON
delle figure resta del motore; l'app mostra solo le immagini citate.
Test MD-28…MD-30, ADR-0006, README, MVP e AGENT.md aggiornati.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5.5 committed 2026-10-15 16:00:25 +02:00
1 parent b3223fb579
commit 51993dd0c8
8 files changed
+109 -24

No files matched your search

@@ -31,9 +31,10 @@ public sealed class MarkdownImageTests : IDisposable
return path;
}
static (Window Window, MarkdownView View) Show(string markdown, double width = 500)
static (Window Window, MarkdownView View) Show(string markdown, double width = 500, string? baseDir = null)
{
var view = new MarkdownView();
if (baseDir is not null) view.BaseDirectory = baseDir;
var window = new Window { Width = width, Height = 800, Content = view };
window.Show();
view.Source = markdown;
@@ -205,4 +206,60 @@ public sealed class MarkdownImageTests : IDisposable
Assert.Empty(Images(view));
Assert.Contains("[guasta]", Text(view));
}
// Struttura tipo wiki: <radice>/raw/immagini.json, <radice>/raw/immagini/<file>, exe in <radice>/agent-wiki-ui/
string Wiki(string name, params string[] files)
{
var root = Path.Combine(dir, name);
Directory.CreateDirectory(Path.Combine(root, "raw", "immagini"));
Directory.CreateDirectory(Path.Combine(root, "agent-wiki-ui"));
foreach (var f in files) File.WriteAllBytes(Path.Combine(root, "raw", "immagini", f), PngFactory.Create(24, 12));
File.WriteAllText(Path.Combine(root, "raw", "immagini.json"), "{\"figures\":[]}");
return root;
}
[AvaloniaFact]
public void Immagine_percorso_relativo_alla_radice()
{
var root = Wiki("wiki-a", "fig1.png");
var (_, view) = Show("![Figura 1](raw/immagini/fig1.png)", baseDir: Path.Combine(root, "agent-wiki-ui"));
Assert.Single(Images(view));
Assert.DoesNotContain("[Figura 1]", Text(view));
}
[AvaloniaFact]
public void Immagine_cartella_piu_vicina()
{
var root = Wiki("wiki-b");
File.WriteAllBytes(Path.Combine(root, "raw", "immagini", "x.png"), PngFactory.Create(30, 30));
var exeDir = Path.Combine(root, "agent-wiki-ui");
Directory.CreateDirectory(Path.Combine(exeDir, "raw", "immagini"));
File.WriteAllBytes(Path.Combine(exeDir, "raw", "immagini", "x.png"), PngFactory.Create(10, 10));
var (_, view) = Show("![x](raw/immagini/x.png)", baseDir: exeDir);
var bmp = Assert.IsAssignableFrom<Bitmap>(Assert.Single(Images(view)).Source);
Assert.Equal(new PixelSize(10, 10), bmp.PixelSize); // vince la cartella più vicina all'exe
var (_, nowhere) = Show("![y](raw/immagini/non-esiste.png)", baseDir: exeDir);
Assert.Empty(Images(nowhere));
Assert.Contains("[y]", Text(nowhere));
}
[AvaloniaFact]
public void Immagine_risposta_stile_wiki()
{
var root = Wiki("wiki-c", "455dd3d0.png");
var risposta = """
La struttura generica è in Figura 1.
![Figura 1](raw/immagini/455dd3d0.png)
Figura 1 - struttura generica di un dichetopirrolopirrolo · §1.1 r.73 · [[fig-001]]
""";
var (_, view) = Show(risposta, baseDir: Path.Combine(root, "agent-wiki-ui"));
Assert.Single(Images(view));
var text = Text(view);
Assert.Contains("Figura 1 - struttura generica", text);
Assert.Contains("[[fig-001]]", text); // il link alla nota resta testo: l'app non legge il catalogo JSON
}
}