Module: Coradoc::Html::Theme::ModernRenderer::VueTemplates

Defined in:
lib/coradoc/html/theme/modern/vue_template_generator.rb

Overview

Vue component templates for rendering document elements

Class Method Summary collapse

Class Method Details

.admonition_templateString

Admonition component template

Returns:

  • (String)

    Admonition template



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 137

def admonition_template
  <<~VUE
    <div :id="data.id" :class="['admonition', 'admonition-' + data.style.toLowerCase()]">
      <div class="admonition-title font-semibold mb-2 flex items-center gap-2">
        <span class="admonition-icon">{{ admonitionIcon(data.style) }}</span>
        <span>{{ data.title || admonitionTitle(data.style) }}</span>
      </div>
      <div class="admonition-content">
        <template v-for="(item, index) in data.content" :key="item.id || index">
          <component :is="'element-' + item.type" :data="item" />
        </template>
      </div>
    </div>
  VUE
end

.block_templateString

Block component template (listing, literal, example, quote)

Returns:

  • (String)

    Block template



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 194

def block_template
  <<~VUE
    <div :id="data.id" :class="['block', 'block-' + data.block_type.toLowerCase()]">
      <div v-if="data.title" class="block-title font-semibold mb-2">{{ data.title }}</div>

      <div v-if="data.block_type === 'listing' || data.block_type === 'literal'" class="bg-gray-100 dark:bg-gray-800 rounded-lg p-4 overflow-x-auto">
        <pre class="whitespace-pre-wrap">{{ blockContent(data) }}</pre>
        <button
          @click="copyCode(blockContent(data), $event)"
          class="copy-code-button"
        >
          Copy
        </button>
      </div>

      <blockquote v-else-if="data.block_type === 'quote'" class="border-l-4 border-primary-500 pl-4 italic">
        <template v-for="(item, index) in data.content" :key="item.id || index">
          <component :is="'element-' + item.type" :data="item" />
        </template>
      </blockquote>

      <div v-else class="block-content">
        <template v-for="(item, index) in data.content" :key="item.id || index">
          <component :is="'element-' + item.type" :data="item" />
        </template>
      </div>
    </div>
  VUE
end

.cross_reference_templateString

Cross reference component template

Returns:

  • (String)

    Cross reference template



312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 312

def cross_reference_template
  <<~VUE
    <a
      :href="'#' + data.target"
      @click.prevent="scrollToSection(data.target)"
      class="text-primary-600 dark:text-primary-400 hover:text-primary-800 dark:hover:text-primary-300 underline cursor-pointer"
    >
      <template v-for="(item, index) in data.content" :key="item.id || index">
        <component :is="'inline-' + item.type" v-if="item.type" :data="item" />
        <span v-else>{{ item.content || item }}</span>
      </template>
    </a>
  VUE
end

.document_templateString

Document component template

Returns:

  • (String)

    Document template



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 34

def document_template
  <<~VUE
    <div class="document-wrapper">
      <header v-if="document.header" class="document-header mb-8">
        <h1 class="text-4xl font-bold text-gray-900 dark:text-white">
          {{ document.header.title?.text || document.title || 'Untitled Document' }}
        </h1>
        <p v-if="document.header?.author" class="text-gray-600 dark:text-gray-400 mt-2">
          {{ document.header.author }}
        </p>
      </header>

      <div class="toc-toggle mb-4 flex justify-end">
        <button
          @click="tocCollapsed = !tocCollapsed"
          class="px-4 py-2 rounded-lg bg-white dark:bg-gray-800 shadow-md hover:shadow-lg transition-all flex items-center gap-2"
        >
          <svg class="w-5 h-5" :class="{ 'rotate-180': !tocCollapsed }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
          </svg>
          <span>{{ tocCollapsed ? 'Show' : 'Hide' }} Contents</span>
        </button>
      </div>

      <div class="flex gap-8">
        <!-- TOC Sidebar -->
        <aside v-if="showToc" class="toc-sidebar" :class="{ 'collapsed': tocCollapsed }">
          <nav class="toc-nav">
            <h3 class="text-lg font-semibold mb-4 text-gray-900 dark:text-white">Contents</h3>
            <ul class="space-y-1">
              <li
                v-for="item in tocItems"
                :key="item.id"
                @click="scrollToSection(item.id)"
                class="toc-item"
                :class="{ 'active': activeSection === item.id }"
                :style="{ paddingLeft: (item.level * 0.75) + 'rem' }"
              >
                {{ item.title }}
              </li>
            </ul>
          </nav>
        </aside>

        <!-- Main Content -->
        <main class="flex-1 min-w-0">
          <article class="prose prose-lg dark:prose-invert max-w-none">
            <template v-for="(section, index) in document.sections" :key="section.id || index">
              <component :is="'section-' + section.type" :data="section" v-if="section.type === 'section'" />
              <component :is="'element-' + section.type" :data="section" v-else />
            </template>
          </article>
        </main>
      </div>
    </div>
  VUE
end

.generic_templateString

Generic component template (fallback)

Returns:

  • (String)

    Generic template



330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 330

def generic_template
  <<~VUE
    <div :id="data.id" :class="['element', 'element-' + data.type]">
      <template v-if="data.content">
        <template v-for="(item, index) in data.content" :key="item.id || index">
          <component :is="'element-' + item.type" :data="item" v-if="item.type" />
          <span v-else>{{ item.content || item }}</span>
        </template>
      </template>
      <span v-else>{{ data.content || data }}</span>
    </div>
  VUE
end

.image_templateString

Image component template

Returns:

  • (String)

    Image template



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 272

def image_template
  <<~VUE
    <figure :id="data.id" :class="data.inline ? 'inline-image' : 'block-image'" class="my-4">
      <img
        :src="data.src"
        :alt="data.alt || ''"
        :title="data.title"
        :width="data.width"
        :height="data.height"
        :class="data.inline ? 'inline max-h-6 align-middle' : 'w-full rounded-lg shadow-lg'"
      />
      <figcaption v-if="data.title" class="text-center text-sm text-gray-600 dark:text-gray-400 mt-2">
        {{ data.title }}
      </figcaption>
    </figure>
  VUE
end

Link component template

Returns:

  • (String)

    Link template



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 293

def link_template
  <<~VUE
    <a
      :href="data.href"
      :target="data.target || '_blank'"
      :rel="data.target === '_blank' ? 'noopener noreferrer' : null"
      class="text-primary-600 dark:text-primary-400 hover:text-primary-800 dark:hover:text-primary-300 underline"
    >
      <template v-for="(item, index) in data.content" :key="item.id || index">
        <component :is="'inline-' + item.type" v-if="item.type" :data="item" />
        <span v-else>{{ item.content || item }}</span>
      </template>
    </a>
  VUE
end

.list_templateString

List component template

Returns:

  • (String)

    List template



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 156

def list_template
  <<~VUE
    <div :id="data.id" class="list-wrapper">
      <ul v-if="data.list_type === 'unordered'" class="list-disc list-inside space-y-1">
        <li v-for="(item, index) in data.items" :key="item.id || index" class="list-item">
          <template v-for="(content, idx) in item.content" :key="content.id || idx">
            <component :is="'element-' + content.type" :data="content" />
          </template>
        </li>
      </ul>

      <ol v-else-if="data.list_type === 'ordered'" class="list-decimal list-inside space-y-1">
        <li v-for="(item, index) in data.items" :key="item.id || index" class="list-item">
          <template v-for="(content, idx) in item.content" :key="content.id || idx">
            <component :is="'element-' + content.type" :data="content" />
          </template>
        </li>
      </ol>

      <dl v-else-if="data.list_type === 'definition'" class="space-y-2">
        <template v-for="(item, index) in data.items" :key="item.id || index">
          <div class="definition-item">
            <dt class="font-semibold">{{ item.terms?.join(', ') }}</dt>
            <dd class="ml-4">
              <template v-for="(content, idx) in item.content" :key="content.id || idx">
                <component :is="'element-' + content.type" :data="content" />
              </template>
            </dd>
          </div>
        </template>
      </dl>
    </div>
  VUE
end

.paragraph_templateString

Paragraph component template

Returns:

  • (String)

    Paragraph template



123
124
125
126
127
128
129
130
131
132
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 123

def paragraph_template
  <<~VUE
    <p :id="data.id" class="paragraph leading-relaxed">
      <template v-for="(item, index) in data.content" :key="item.id || index">
        <component :is="'inline-' + item.type" v-if="item.type" :data="item" />
        <span v-else>{{ item.content || item }}</span>
      </template>
    </p>
  VUE
end

.section_templateString

Section component template

Returns:

  • (String)

    Section template



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 95

def section_template
  <<~VUE
    <section :id="data.id" class="section scroll-mt-20">
      <h1 v-if="data.level === 1" class="section-title text-3xl font-bold mb-4">{{ data.title?.text || data.title }}</h1>
      <h2 v-else-if="data.level === 2" class="section-title text-2xl font-semibold mb-3">{{ data.title?.text || data.title }}</h2>
      <h3 v-else-if="data.level === 3" class="section-title text-xl font-semibold mb-2">{{ data.title?.text || data.title }}</h3>
      <h4 v-else-if="data.level === 4" class="section-title text-lg font-semibold mb-2">{{ data.title?.text || data.title }}</h4>
      <h5 v-else-if="data.level === 5" class="section-title text-base font-semibold mb-1">{{ data.title?.text || data.title }}</h5>
      <h2 v-else class="section-title text-2xl font-semibold mb-3">{{ data.title?.text || data.title }}</h2>

      <div class="section-content">
        <template v-for="(item, index) in data.content" :key="item.id || index">
          <component :is="'element-' + item.type" :data="item" />
        </template>

        <template v-if="data.sections && data.sections.length > 0">
          <template v-for="(subsection, index) in data.sections" :key="subsection.id || index">
            <component :is="'section-section'" :data="subsection" />
          </template>
        </template>
      </div>
    </section>
  VUE
end

.table_templateString

Table component template

Returns:

  • (String)

    Table template



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 227

def table_template
  <<~VUE
    <div :id="data.id" class="table-wrapper overflow-x-auto my-4">
      <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
        <caption v-if="data.caption" class="caption-bottom text-sm text-gray-600 dark:text-gray-400 py-2">
          {{ data.caption }}
        </caption>

        <thead v-if="data.header && data.header.length > 0" class="bg-gray-50 dark:bg-gray-800">
          <tr>
            <th
              v-for="(cell, index) in data.header[0].cells"
              :key="cell.id || index"
              class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider"
              :colspan="cell.colspan"
              :rowspan="cell.rowspan"
            >
              {{ cellContent(cell) }}
            </th>
          </tr>
        </thead>

        <tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
          <tr v-for="(row, rowIndex) in data.body" :key="row.id || rowIndex" class="hover:bg-gray-50 dark:hover:bg-gray-800">
            <td
              v-for="(cell, cellIndex) in row.cells"
              :key="cell.id || cellIndex"
              class="px-4 py-2 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100"
              :colspan="cell.colspan"
              :rowspan="cell.rowspan"
            >
              <template v-for="(item, index) in cell.content" :key="item.id || index">
                <component :is="'element-' + item.type" :data="item" />
              </template>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  VUE
end

.template_for(type) ⇒ String

Generate Vue component template for a given element type

Parameters:

  • type (String)

    Element type

Returns:

  • (String)

    Vue component template



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/coradoc/html/theme/modern/vue_template_generator.rb', line 14

def template_for(type)
  case type
  when 'document' then document_template
  when 'section' then section_template
  when 'paragraph' then paragraph_template
  when 'admonition' then admonition_template
  when 'list' then list_template
  when 'block' then block_template
  when 'table' then table_template
  when 'image' then image_template
  when 'link' then link_template
  when 'xref' then cross_reference_template
  else
    generic_template
  end
end