Skip to content

Commit

Permalink
fix path generation for nested entities
Browse files Browse the repository at this point in the history
  • Loading branch information
vanyauhalin committed Dec 27, 2024
1 parent 2d8d97d commit 5c20c03
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 98 deletions.
148 changes: 50 additions & 98 deletions site/generations/library-next.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import {type SitemapData, SitemapDatum} from "@onlyoffice/eleventy-sitemap"
import {type Data} from "@onlyoffice/eleventy-types"
import {type Entity} from "@onlyoffice/library-declaration/next.js"
import {cutSuffix} from "@onlyoffice/strings"
import {LibraryDatum} from "../internal/library.tsx"
import {Sitemap} from "../internal/sitemap.ts"
import {Pather} from "../internal/url.ts"

export interface Resource {
list(): Entity[]
retrieve(id: number): Entity | undefined
}

export function data(r: Resource): Data {
const sp = new SpecificPather()
const vp = new VirtualPather()
const sp = new Pather()
const vp = new Pather()

const sr: Record<string, SitemapData> = {}

Expand Down Expand Up @@ -50,17 +50,62 @@ export function data(r: Resource): Data {
if (!data.pagination || !data.pagination.items) {
throw new Error("No pagination")
}

const [e]: Entity[] = data.pagination.items
const p = vp.path(r, e)

let a: string[] = []
let b: number[] = []

let c: Entity | undefined = e

while (c) {
if (c.type === "group") {
a.push(c.group.name)
b.push(c.id)
}

if (c.type === "declaration") {
a.push(c.declaration.name)
b.push(c.id)
}

c = r.retrieve(c.parentId)
}

a = a.reverse()
b = b.reverse()

const p = vp.pathify(a, b)

return `${p}/index.html`
},

specificPath(data) {
if (!data.pagination || !data.pagination.items) {
throw new Error("No pagination")
}

const [e]: Entity[] = data.pagination.items
const p = sp.path(r, e)

let a: string[] = []
let b: number[] = []

let c: Entity | undefined = e

while (c) {
if (c.type === "declaration") {
a.push(c.declaration.name)
b.push(c.id)
}

c = r.retrieve(c.parentId)
}

a = a.reverse()
b = b.reverse()

const p = sp.pathify(a, b)

return `${p}/index.html`
},

Expand Down Expand Up @@ -151,96 +196,3 @@ export function data(r: Resource): Data {
},
}
}

class VirtualPather implements Pather {
#m = new Map<string, number>()

path(r: Resource, e: Entity): string {
let s = ""
let i = 0

let c: Entity | undefined = e

while (c) {
if (c.type === "group") {
const n = sanitizeName(c.group.name)
s = `${n}/${s}`
}

if (c.type === "declaration") {
const n = sanitizeName(c.declaration.name)
s = `${n}/${s}`
}

c = r.retrieve(c.parentId)
}

[s] = cutSuffix(s, "/")

while (true) {
const id = this.#m.get(s)

if (!id) {
this.#m.set(s, e.id)
break
}

if (id === e.id) {
break
}

i += 1
s = `${s}-${i}`
}

return s
}
}

class SpecificPather implements Pather {
#m = new Map<string, number>()

path(r: Resource, e: Entity): string {
let s = ""
let i = 0

let c: Entity | undefined = e

while (c) {
if (c.type === "declaration") {
const n = sanitizeName(c.declaration.name)
s = `${n}/${s}`
}

c = r.retrieve(c.parentId)
}

[s] = cutSuffix(s, "/")

while (true) {
const id = this.#m.get(s)

if (!id) {
this.#m.set(s, e.id)
break
}

if (id === e.id) {
break
}

i += 1
s = `${s}-${i}`
}

return s
}
}

interface Pather {
path(r: Resource, e: Entity): string
}

function sanitizeName(t: string): string {
return t.replaceAll("/", " ")
}
73 changes: 73 additions & 0 deletions site/internal/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,76 @@ function defaultPath(p: Page): string {
const c = posix.dirname(p.filePathStem)
return posix.join(c, b)
}

export class Pather {
/**
* The index where the key is a path and the value is a unique identifier.
*/
#x = new Map<string, number>()

/**
* The index where the key is a path, and the value is a number of duplicates.
*/
#y = new Map<string, number>()

/**
* @param a A list of path segments.
* @param b A corresponding list of unique identifiers.
* @returns A unique path.
*/
pathify(a: string[], b: number[]): string {
const a0: string[] = []

for (let s of a) {
s = s.replaceAll("/", " ")
a0.push(s)
}

const b0 = [...b]

for (let i = 0; i < a0.length; i += 1) {
const c = a0.slice(0, i + 1)
const s = c[c.length - 1]

let x0 = b0[i]
let y0 = 0

let k = ""

while (true) {
if (y0 !== 0) {
c[c.length - 1] = `${s}-${y0}`
}

k = c.join("/")

const x1 = this.#x.get(k)
if (x1 === undefined) {
break
}

const y1 = this.#y.get(k)
if (y1 === undefined) {
break
}

if (x1 === x0) {
break
}

x0 = x1
y0 = y1 + 1
}

this.#x.set(k, x0)
this.#y.set(k, y0)

a0[i] = c[c.length - 1]
b0[i] = x0
}

const p = a0.join("/")

return p
}
}

0 comments on commit 5c20c03

Please sign in to comment.