attachments.typ 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // ==========================================
  2. // DOMAIN: ПРИЛОЖЕНИЯ
  3. // ==========================================
  4. #import "document.typ": fail
  5. #let attachment(
  6. id,
  7. title,
  8. body,
  9. subtitle: none,
  10. number: auto,
  11. outlined: true,
  12. ) = {
  13. if type(id) != str or id.trim() == "" {
  14. fail("attachment.id", "нужна непустая строка")
  15. }
  16. if type(title) not in (str, content) {
  17. fail("attachment.title", "ожидались str или content")
  18. }
  19. if type(body) not in (content, function) {
  20. fail("attachment.body", "ожидались content или function")
  21. }
  22. if subtitle != none and type(subtitle) not in (str, content) {
  23. fail("attachment.subtitle", "ожидались none, str или content")
  24. }
  25. (
  26. kind: "attachment",
  27. id: id,
  28. title: title,
  29. subtitle: subtitle,
  30. body: body,
  31. number: number,
  32. outlined: outlined,
  33. )
  34. }
  35. #let attachment-set(items: (), numbering: "arabic", start: 1) = {
  36. if type(items) != array {
  37. fail("attachments.items", "ожидался array")
  38. }
  39. if numbering not in ("arabic", "cyrillic", "none") {
  40. fail("attachments.numbering", "допустимы arabic, cyrillic, none")
  41. }
  42. if type(start) != int or start < 1 {
  43. fail("attachments.start", "нужно положительное целое число")
  44. }
  45. let seen = ()
  46. for item in items {
  47. if type(item) != dictionary or item.at("kind", default: none) != "attachment" {
  48. fail("attachments.items", "каждый элемент должен быть attachment")
  49. }
  50. if item.id in seen {
  51. fail("attachments.items", "повторяющийся id " + repr(item.id))
  52. }
  53. seen.push(item.id)
  54. }
  55. (
  56. kind: "attachment-set",
  57. items: items,
  58. numbering: numbering,
  59. start: start,
  60. )
  61. }
  62. #let validate-attachment-set(value) = {
  63. if type(value) == array {
  64. attachment-set(items: value)
  65. } else if type(value) != dictionary or value.at("kind", default: none) != "attachment-set" {
  66. fail("attachments", "ожидались array или attachment-set")
  67. } else {
  68. attachment-set(
  69. items: value.at("items", default: ()),
  70. numbering: value.at("numbering", default: "arabic"),
  71. start: value.at("start", default: 1),
  72. )
  73. }
  74. }