feat: Improve export self-containment and link handling
- Use absolute paths for path_relative calculations - Validate links before export to populate page.links - Copy cross-collection referenced pages for self-contained export - Update export_link_path to generate local links for self-contained exports - Remove page from visited map to allow re-inclusion in other contexts
This commit is contained in:
@@ -53,7 +53,10 @@ fn (mut c Collection) add_page(mut path pathlib.Path) ! {
|
||||
if name in c.pages {
|
||||
return error('Page ${name} already exists in collection ${c.name}')
|
||||
}
|
||||
relativepath := path.path_relative(c.path()!.path)!
|
||||
// Use absolute paths for path_relative to work correctly
|
||||
mut col_path := pathlib.get(c.path)
|
||||
mut page_abs_path := pathlib.get(path.absolute())
|
||||
relativepath := page_abs_path.path_relative(col_path.absolute())!
|
||||
|
||||
mut p_new := Page{
|
||||
name: name
|
||||
@@ -71,7 +74,10 @@ fn (mut c Collection) add_file(mut p pathlib.Path) ! {
|
||||
if name in c.files {
|
||||
return error('Page ${name} already exists in collection ${c.name}')
|
||||
}
|
||||
relativepath := p.path_relative(c.path()!.path)!
|
||||
// Use absolute paths for path_relative to work correctly
|
||||
mut col_path := pathlib.get(c.path)
|
||||
mut file_abs_path := pathlib.get(p.absolute())
|
||||
relativepath := file_abs_path.path_relative(col_path.absolute())!
|
||||
|
||||
mut file_new := File{
|
||||
name: name
|
||||
|
||||
@@ -22,8 +22,8 @@ pub fn (mut a Atlas) export(args ExportArgs) ! {
|
||||
dest.empty()!
|
||||
}
|
||||
|
||||
// Validate links before export
|
||||
// a.validate_links()!
|
||||
// Validate links before export to populate page.links
|
||||
a.validate_links()!
|
||||
|
||||
for _, mut col in a.collections {
|
||||
col.export(
|
||||
@@ -67,6 +67,10 @@ pub fn (mut c Collection) export(args CollectionExportArgs) ! {
|
||||
)!
|
||||
json_file.write(meta)!
|
||||
|
||||
// Track cross-collection pages that need to be copied for self-contained export
|
||||
mut cross_collection_pages := map[string]&Page{} // key: page.name, value: &Page
|
||||
|
||||
// First pass: export all pages in this collection and collect cross-collection references
|
||||
for _, mut page in c.pages {
|
||||
// Get content with includes processed and links transformed for export
|
||||
content := page.content_with_fixed_links(
|
||||
@@ -78,6 +82,19 @@ pub fn (mut c Collection) export(args CollectionExportArgs) ! {
|
||||
mut dest_file := pathlib.get_file(path: '${col_dir.path}/${page.name}.md', create: true)!
|
||||
dest_file.write(content)!
|
||||
|
||||
// Collect cross-collection page references for copying
|
||||
// IMPORTANT: Use cached links from validation (before transformation) to preserve collection info
|
||||
for mut link in page.links {
|
||||
// Only process valid page links (not files/images) from other collections
|
||||
if link.status == .found && !link.is_file_link && !link.is_local_in_collection() {
|
||||
mut target_page := link.target_page() or { continue }
|
||||
// Use page name as key to avoid duplicates
|
||||
if target_page.name !in cross_collection_pages {
|
||||
cross_collection_pages[target_page.name] = target_page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Redis operations...
|
||||
if args.redis {
|
||||
mut context := base.context()!
|
||||
@@ -86,23 +103,17 @@ pub fn (mut c Collection) export(args CollectionExportArgs) ! {
|
||||
}
|
||||
}
|
||||
|
||||
// // Export files
|
||||
// if c.files.len > 0 {
|
||||
// files_dir := pathlib.get_dir(
|
||||
// path: '${col_dir.path}/files'
|
||||
// create: true
|
||||
// )!
|
||||
// Second pass: copy cross-collection referenced pages to make collection self-contained
|
||||
for _, mut ref_page in cross_collection_pages {
|
||||
// Get the referenced page content with includes processed
|
||||
ref_content := ref_page.content_with_fixed_links(
|
||||
include: args.include
|
||||
cross_collection: true
|
||||
export_mode: true
|
||||
)!
|
||||
|
||||
// for _, mut file in c.files {
|
||||
// dest_path := '${files_dir.path}/${file.file_name()}'
|
||||
// mut p2 := file.path()!
|
||||
// p2.copy(dest: col_dir.path)!
|
||||
|
||||
// if args.redis {
|
||||
// mut context := base.context()!
|
||||
// mut redis := context.redis()!
|
||||
// redis.hset('atlas:${c.name}', file.file_name(), file.path()!.path)!
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Write the referenced page to this collection's directory
|
||||
mut dest_file := pathlib.get_file(path: '${col_dir.path}/${ref_page.name}.md', create: true)!
|
||||
dest_file.write(ref_content)!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,27 +242,20 @@ fn (mut p Page) calculate_link_path(mut link Link, args FixLinksArgs) !string {
|
||||
return p.filesystem_link_path(mut link)!
|
||||
}
|
||||
|
||||
// export_link_path calculates path for export (flat structure: collection/file.md)
|
||||
// export_link_path calculates path for export (self-contained: all references are local)
|
||||
fn (mut p Page) export_link_path(mut link Link) !string {
|
||||
mut target_collection := ''
|
||||
mut target_filename := ''
|
||||
|
||||
if link.is_file_link {
|
||||
mut tf := link.target_file()!
|
||||
target_collection = tf.collection.name
|
||||
target_filename = tf.name
|
||||
} else {
|
||||
mut tp := link.target_page()!
|
||||
target_collection = tp.collection.name
|
||||
target_filename = '${tp.name}.md'
|
||||
}
|
||||
|
||||
// Same collection: just filename, different collection: ../collection/filename
|
||||
return if link.is_local_in_collection() {
|
||||
target_filename
|
||||
} else {
|
||||
'../${target_collection}/${target_filename}'
|
||||
}
|
||||
// For self-contained exports, all links are local (cross-collection pages are copied)
|
||||
return target_filename
|
||||
}
|
||||
|
||||
// filesystem_link_path calculates path using actual filesystem paths
|
||||
|
||||
@@ -128,6 +128,10 @@ fn (mut p Page) process_includes(content string, mut visited map[string]bool) !s
|
||||
}
|
||||
}
|
||||
|
||||
// Remove this page from visited map to allow it to be included again in other contexts
|
||||
// This prevents false positives when a page is included multiple times (which is valid)
|
||||
visited.delete(page_key)
|
||||
|
||||
return processed_lines.join_lines()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user