refs-context.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. const GRID_DEFAULT_TRACK_WIDTH = 64;
  2. const GRID_AVAILABLE_OPTIONS_LIST = [
  3. 'autofill',
  4. 'autofill-xs',
  5. 'autofill-sm',
  6. 'autofill-md',
  7. 'autofill-lg',
  8. 'autofill-xl',
  9. 'col-2',
  10. 'col-3',
  11. 'col-4',
  12. 'col-5',
  13. 'col-6',
  14. ];
  15. type tags = 'ref' | 'refs' | 'refimg' | 'refsimg';
  16. /**
  17. * Context Object class for $ref() and $refimg()
  18. */
  19. export class RefsContext {
  20. tag: tags;
  21. pagePath: string;
  22. options?: Record<string, string | undefined>;
  23. constructor(
  24. tag: tags,
  25. pagePath: string,
  26. options: Record<string, string | undefined>,
  27. ) {
  28. this.tag = tag;
  29. this.pagePath = pagePath;
  30. // remove undefined keys
  31. Object.keys(options).forEach(
  32. (key) => options[key] === undefined && delete options[key],
  33. );
  34. this.options = options;
  35. }
  36. getStringifiedAttributes(separator = ', '): string {
  37. const attributeStrs = [`page=${this.pagePath}`];
  38. if (this.options != null) {
  39. const optionEntries = Object.entries(this.options).sort();
  40. attributeStrs.push(
  41. ...optionEntries.map(([key, val]) => `${key}=${val || 'true'}`),
  42. );
  43. }
  44. return attributeStrs.join(separator);
  45. }
  46. /**
  47. * for printing errors
  48. * @returns
  49. */
  50. toString(): string {
  51. return `$${this.tag}(${this.getStringifiedAttributes()})`;
  52. }
  53. get isSingle(): boolean {
  54. return this.tag === 'ref' || this.tag === 'refimg';
  55. }
  56. get isExtractImage(): boolean {
  57. return this.tag === 'refimg' || this.tag === 'refsimg';
  58. }
  59. getOptGrid(): string | undefined {
  60. return GRID_AVAILABLE_OPTIONS_LIST.find(
  61. (item) => item === this.options?.grid,
  62. );
  63. }
  64. isOptGridColumnEnabled(): boolean {
  65. const optGrid = this.getOptGrid();
  66. return optGrid != null && optGrid.startsWith('col-');
  67. }
  68. /**
  69. * return auto-calculated grid width
  70. * rules:
  71. * 1. when column mode (e.g. col-6, col5, ...), the width specification is disabled
  72. * 2. when width option is set, return it
  73. * 3. otherwise, the mode should be autofill and the width will be calculated according to the size
  74. */
  75. getOptGridWidth(): string | undefined {
  76. const grid = this.getOptGrid();
  77. const width = this.options?.width;
  78. // when Grid column mode
  79. if (this.isOptGridColumnEnabled()) {
  80. // not specify and ignore width
  81. return undefined;
  82. }
  83. // when width is specified
  84. if (width != null) {
  85. return width;
  86. }
  87. // when Grid autofill mode
  88. let autofillMagnification = 1;
  89. switch (grid) {
  90. case 'autofill-xl':
  91. autofillMagnification = 3;
  92. break;
  93. case 'autofill-lg':
  94. autofillMagnification = 2;
  95. break;
  96. case 'autofill-sm':
  97. autofillMagnification = 0.75;
  98. break;
  99. case 'autofill-xs':
  100. autofillMagnification = 0.5;
  101. break;
  102. case 'autofill':
  103. case 'autofill-md':
  104. break;
  105. }
  106. return `${GRID_DEFAULT_TRACK_WIDTH * autofillMagnification}px`;
  107. }
  108. /**
  109. * return auto-calculated grid height
  110. * rules:
  111. * 1. when height option is set, return it
  112. * 2. otherwise, the same value to the width will be returned
  113. */
  114. getOptGridHeight(): string | undefined {
  115. const height = this.options?.height;
  116. // when height is specified
  117. if (height != null) {
  118. return height;
  119. }
  120. // return the value which is same to width
  121. return this.getOptGridWidth();
  122. }
  123. getOptGridColumnsNum(): number | null {
  124. let columnsNum: number | null = null;
  125. switch (this.options?.grid) {
  126. case 'col-2':
  127. columnsNum = 2;
  128. break;
  129. case 'col-3':
  130. columnsNum = 3;
  131. break;
  132. case 'col-4':
  133. columnsNum = 4;
  134. break;
  135. case 'col-5':
  136. columnsNum = 5;
  137. break;
  138. case 'col-6':
  139. columnsNum = 6;
  140. break;
  141. }
  142. return columnsNum;
  143. }
  144. }