How to ensure that the same file will not be included after including other files multiple times

  1. l have a fle to include all fles, like A.typ will include A.1.typ, A.2.typ, andA.1.typ will include A.1/A.2.1.typ, A.1/A.2.2.typ
  2. the fles may link to each other too, A.2/A.2.1.typ will include A.1/A.1.1.typ. To slove this problem, l think the only way is to include A.1/A.1.1.typ in A.2/A.2.1.typ`
  3. Make in A.typ, the order of the files is always A.1.typ, A.1/A.1.1.typ, A.2.typ, A.2.1.typ. In A.2.typ the order is A.2/A.2.1.typ, A.1/A.1.1.typ(An order can contrl by myself, and files that would not otherwise be included but are linked to will be included last)

In this example, the A.typ will include A.2/A.2.1.typ twice, and two same lables.

Now i try to use this code to do it(Don’t mind changing it, I don’t hink it works well):

// Check is a file has been included
#let check_included(label) = {query(label) != ()}

#let check_link(label, description) = {
    if check_included(label) {
// check lable
      link(label, description)
    } else [
      #description
  ]
}

#let check_path(path) = {
  // Don't care it
  let path_list = path.split("/")
  let output=(path_list.at(0), )
  for i in range(1, path_list.len()) {
    if path_list.at(i) == ".."{
      let temp = output.pop()
    } else if path_list.at(i) == "."{
    } else {
      output.push(path_list.at(i))
    }
  }
  output.join("/")
}

#let creat_link(file: "", description: "", label_in: "", need_include: ("", ), include_list: ("", ), root: "") = {
// the function I use to creat link(Maybe it can be deleted)
  if file == ""  and label_in == ""{
    panic("No file, No lable. What do you want to do?")
  }
  let real_path = check_path(root + file)
  if real_path in include_list {
    // include_list = move_item(include_list, real_path)
  } else {
    need_include = ((real_path, ) + need_include)
  }
  let output = context {check_link(label(real_path), description)}
  if label_in != "" {
    output = context {check_link(label(label_in), description)}
  }
  if file == "" {
    output
  } else {
    (output, need_include)
  }
}

#let include_item(include_list) = {
// I want to use check_include here to make sure there is no document included twice.
  for i in include_list [
    #if i != "" [
      #[]#label(i)
      #include i
    ]
  ]
}

#let append_include(include_list, doc) = [
// append the files are included
  #doc
  #include_item(include_list)
]

You mention that sub files will link to other sub files (point #2 in your list). Will these sub files ever be compiled to produce documents that need to look good? If they will not be published, it may be enough to make a function that tries to create the link and if the label does not exist (because that file is not included), then instead of a link it will say something like “Link to <xyz>”.
In psuedo-code:

#let link-safe(label-to-link) = {
  if label-not-found {
    //Place holder text
    return [Link to #label-to-link]
  } else {
    //An actual link to the label
    return link(label-to-link)
  }
}

This way sub files don’t need to include other sub files, and there is no need to keep track of what files have already been included.

If these sub files will also be compiled and will stand on their own, then this option won’t satisfy your requirements.