hdoc-tools 0.8.23 → 0.8.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/hdoc-build-pdf.js +169 -0
  2. package/hdoc-build.js +38 -8
  3. package/hdoc-init.js +0 -1
  4. package/hdoc-validate.js +0 -2
  5. package/hdoc.js +1 -1
  6. package/package.json +4 -2
  7. package/templates/pdf/css/custom-block.css +90 -0
  8. package/templates/pdf/css/fonts.css +221 -0
  9. package/templates/pdf/css/hdocs-pdf.css +242 -0
  10. package/templates/pdf/css/vars.css +393 -0
  11. package/templates/pdf/fonts/inter-cyrillic copy.woff2 +0 -0
  12. package/templates/pdf/fonts/inter-cyrillic-ext.woff2 +0 -0
  13. package/templates/pdf/fonts/inter-cyrillic.woff2 +0 -0
  14. package/templates/pdf/fonts/inter-greek-ext.woff2 +0 -0
  15. package/templates/pdf/fonts/inter-greek.woff2 +0 -0
  16. package/templates/pdf/fonts/inter-italic-cyrillic-ext.woff2 +0 -0
  17. package/templates/pdf/fonts/inter-italic-cyrillic.woff2 +0 -0
  18. package/templates/pdf/fonts/inter-italic-greek-ext.woff2 +0 -0
  19. package/templates/pdf/fonts/inter-italic-greek.woff2 +0 -0
  20. package/templates/pdf/fonts/inter-italic-latin-ext.woff2 +0 -0
  21. package/templates/pdf/fonts/inter-italic-latin.woff2 +0 -0
  22. package/templates/pdf/fonts/inter-italic-vietnamese.woff2 +0 -0
  23. package/templates/pdf/fonts/inter-latin-ext.woff2 +0 -0
  24. package/templates/pdf/fonts/inter-latin.woff2 +0 -0
  25. package/templates/pdf/fonts/inter-roman-cyrillic-ext.woff2 +0 -0
  26. package/templates/pdf/fonts/inter-roman-cyrillic.woff2 +0 -0
  27. package/templates/pdf/fonts/inter-roman-greek-ext.woff2 +0 -0
  28. package/templates/pdf/fonts/inter-roman-greek.woff2 +0 -0
  29. package/templates/pdf/fonts/inter-roman-latin-ext.woff2 +0 -0
  30. package/templates/pdf/fonts/inter-roman-latin.woff2 +0 -0
  31. package/templates/pdf/fonts/inter-roman-vietnamese.woff2 +0 -0
  32. package/templates/pdf/fonts/inter-vietnamese.woff2 +0 -0
  33. package/templates/pdf/images/hornbill-logo-full.svg +92 -0
  34. package/templates/pdf/template-footer.html +19 -0
  35. package/templates/pdf/template.html +13 -0
  36. package/templates/pdf-header-non-git.html +13 -0
  37. package/templates/pdf-header.html +17 -0
@@ -0,0 +1,169 @@
1
+ (function () {
2
+ 'use strict';
3
+
4
+ const cheerio = require('cheerio'),
5
+ dree = require('dree'),
6
+ fs = require('fs-extra'),
7
+ mime = require('mime-types'),
8
+ path = require('path'),
9
+ puppeteer = require('puppeteer'),
10
+ request = require('sync-request'),
11
+ hdoc = require(path.join(__dirname, 'hdoc-module.js'));
12
+
13
+ const dree_options = {
14
+ extensions: ['css'],
15
+ normalize: true,
16
+ };
17
+
18
+ let css_files = [],
19
+ hb_logo = '',
20
+ header = '',
21
+ footer = '';
22
+
23
+ const file_callback = function (element) {
24
+ css_files.push(element.path);
25
+ };
26
+
27
+ const get_footer = function (template_path) {
28
+ let footer_content = null;
29
+ try {
30
+ footer_content = fs.readFileSync(path.join(template_path, 'template-footer.html'), 'utf8');
31
+ } catch (err) {
32
+ console.log(`Error loading template: ${err}`);
33
+ }
34
+ return footer_content;
35
+ };
36
+
37
+ exports.process_images = async function (file_path, html_source, verbose) {
38
+ const book_work_root = file_path.path.replace(file_path.relativePath, '');
39
+ if (verbose) console.log('Parsing img tags from HTML source');
40
+
41
+ // Use cheerio to parse html
42
+ const $ = cheerio.load(html_source);
43
+
44
+ // Get iFrames from HTML, to replace with a tags
45
+ let iframes = [];
46
+ const iframe_html = $('iframe').map(function () {
47
+ const response = {
48
+ html: $.html(this),
49
+ src: $(this).attr('src'),
50
+ title: $(this).attr('title') ? $(this).attr('title') : 'No Link Title Provided'
51
+ };
52
+ return response;
53
+ }).get();
54
+ iframes.push(...iframe_html);
55
+ for (let i = 0; i < iframes.length; i++) {
56
+ const link = `<p><a href="${iframes[i].src}">${iframes[i].title}</a></p>`;
57
+ const regex = new RegExp(`<iframe.*src="${iframes[i].src.replace('/', '\\/')}".*</iframe>`);
58
+ html_source = html_source.replace(regex, link);
59
+ }
60
+
61
+ // Get image links from HTML, to embed into the pdf
62
+ let imgs = [];
63
+ const srcs = $('img').map(function (i) {
64
+ return $(this).attr('src');
65
+ }).get();
66
+ imgs.push(...srcs);
67
+ for (let i = 0; i < imgs.length; i++) {
68
+ if (hdoc.valid_url(imgs[i]).valid) {
69
+ // External Link
70
+ const file_response = request('GET', imgs[i]);
71
+ if (file_response.statusCode === 200) {
72
+ const image_buffer = file_response.getBody();
73
+ const mime_type = mime.lookup(imgs[i]);
74
+ let image_b64 = image_buffer.toString("base64");
75
+ image_b64 = `data:${mime_type};base64,${image_b64}`;
76
+ html_source = html_source.replace(imgs[i], image_b64);
77
+ } else {
78
+ throw `Unexpected Status ${file_response.statusCode}`;
79
+ }
80
+ } else {
81
+ // Internal link
82
+ const image_path = path.join(book_work_root, imgs[i].replace('_books/', ''));
83
+ try {
84
+ const image_buffer = fs.readFileSync(image_path);
85
+ const mime_type = mime.lookup(image_path);
86
+ let image_b64 = image_buffer.toString("base64");
87
+ image_b64 = `data:${mime_type};base64,${image_b64}`;
88
+ html_source = html_source.replace(imgs[i], image_b64);
89
+ } catch (err) {
90
+ console.log('Error reading image from HTML source [', image_path, '] - ', err);
91
+ return null;
92
+ }
93
+ }
94
+ }
95
+
96
+ return html_source;
97
+ };
98
+
99
+ exports.generate_pdf = async function (pdf_template_path, pdf_template_content, book_config, html_source, target_file, verbose = false) {
100
+ if (verbose) console.log(`Generating PDF: ${target_file}`);
101
+
102
+ // Cache footer
103
+ if (footer === '') footer = get_footer(pdf_template_path);
104
+
105
+ // Read svg logo file into buffer, convert to B64 string
106
+ if (hb_logo === '') {
107
+ const hb_logo_path = path.join(pdf_template_path, 'images', 'hornbill-logo-full.svg');
108
+ try {
109
+ const hb_logo_file_buffer = fs.readFileSync(hb_logo_path);
110
+ hb_logo = hb_logo_file_buffer.toString("base64");
111
+ hb_logo = `data:image/svg+xml;base64,${hb_logo}`;
112
+ } catch (err) {
113
+ console.log('Error reading logo from template:', err);
114
+ return;
115
+ }
116
+ }
117
+
118
+ html_source = pdf_template_content.replace('{{book_title}}', book_config.title).replace('{{document_content}}', html_source).replace('{{hb_logo}}', hb_logo);
119
+
120
+ // Create a browser instance
121
+ const browser = await puppeteer.launch();
122
+
123
+ // Create a new page
124
+ const page = await browser.newPage();
125
+
126
+ // Set HTML content from HTML source
127
+ await page.setContent(html_source, {
128
+ waitUntil: 'domcontentloaded'
129
+ });
130
+
131
+ // To reflect CSS used for screens instead of print
132
+ await page.emulateMediaType('screen');
133
+
134
+ if (css_files.length === 0) {
135
+ // Get a list of CSS files
136
+ dree.scan(pdf_template_path, dree_options, file_callback);
137
+ }
138
+
139
+ for (let i = 0; i < css_files.length; i++) {
140
+ await page.addStyleTag({
141
+ path: css_files[i]
142
+ });
143
+ }
144
+
145
+ try {
146
+ await page.pdf({
147
+ path: target_file,
148
+ margin: {
149
+ top: '30px',
150
+ right: '35px',
151
+ bottom: '80px',
152
+ left: '35px'
153
+ },
154
+ printBackground: true,
155
+ format: 'A4',
156
+ displayHeaderFooter: true,
157
+ headerTemplate: '<div />',
158
+ footerTemplate: footer
159
+ });
160
+ if (verbose) console.log('PDF generation success.');
161
+
162
+ } catch (err) {
163
+ console.log(`Error generating PDF ${target_file} - ${err}`);
164
+ }
165
+
166
+ // Close the browser instance
167
+ await browser.close();
168
+ };
169
+ })();
package/hdoc-build.js CHANGED
@@ -1,3 +1,7 @@
1
+ const {
2
+ verbose
3
+ } = require('sqlite3');
4
+
1
5
  (function () {
2
6
  'use strict';
3
7
 
@@ -10,12 +14,17 @@
10
14
  validate = require(path.join(__dirname, 'hdoc-validate.js')),
11
15
  hdoc = require(path.join(__dirname, 'hdoc-module.js')),
12
16
  hdoc_build_db = require(path.join(__dirname, 'hdoc-build-db.js')),
17
+ hdoc_build_pdf = require(path.join(__dirname, 'hdoc-build-pdf.js')),
13
18
  hdoc_index = require(path.join(__dirname, 'hdoc-db.js')),
14
19
  zipper = require('zip-local');
15
20
 
16
21
  const h_tags_to_search = ['h1', 'h2', 'h3'],
17
22
  doc_header_template_path = path.join(__dirname, 'templates', 'doc-header.html'),
18
- non_git_doc_header_template_path = path.join(__dirname, 'templates', 'doc-header-non-git.html');
23
+ non_git_doc_header_template_path = path.join(__dirname, 'templates', 'doc-header-non-git.html'),
24
+ pdf_header_template_path = path.join(__dirname, 'templates', 'pdf-header.html'),
25
+ non_git_pdf_header_template_path = path.join(__dirname, 'templates', 'pdf-header-non-git.html'),
26
+ pdf_template_path = path.join(__dirname, 'templates', 'pdf'),
27
+ pdf_template_file_path = path.join(pdf_template_path, 'template.html');
19
28
 
20
29
  let bc = {}, // Breadcrumbs map
21
30
  book_read_time = 0,
@@ -25,6 +34,9 @@
25
34
  conversion_failed = 0,
26
35
  doc_header_template = '',
27
36
  doc_header_template_non_git = '',
37
+ pdf_header_template = '',
38
+ pdf_header_template_non_git = '',
39
+ pdf_template = '',
28
40
  doc_id = '',
29
41
  git_token = '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', // Github fine-grained personal access token that has minimum read-only access to Hornbill Docs org repo content
30
42
  hdocbook_config = {},
@@ -211,7 +223,7 @@
211
223
  }
212
224
  };
213
225
 
214
- const transform_markdown_and_save_html = async function (file_path) {
226
+ const transform_markdown_and_save_html = async function (file_path, verbose) {
215
227
  conversion_attempted++;
216
228
  if (fs.existsSync(file_path.path)) {
217
229
  // Load markdown file
@@ -372,17 +384,24 @@
372
384
  fm_header += ']]-->';
373
385
 
374
386
  let doc_header = '';
387
+ let pdf_header = '';
375
388
  if (hdocbook_config.publicSource.includes('github.com/Hornbill-Docs')) {
376
389
  // Build doc header from template and frontmatter tags
377
390
  doc_header = process_doc_header(fm_headers, file_path.relativePath, doc_header_template);
391
+ pdf_header = process_doc_header(fm_headers, file_path.relativePath, pdf_header_template);
378
392
  } else {
379
393
  // Build doc header from template and frontmatter tags
380
394
  doc_header = process_doc_header(fm_headers, file_path.relativePath, doc_header_template_non_git);
395
+ pdf_header = process_doc_header(fm_headers, file_path.relativePath, pdf_header_template_non_git);
381
396
  }
382
- /*
383
- const pdf_html = `${fm_header}\n${doc_header}\n${html_txt}`;
384
- const pdf_file = file_path.path.replace(path.extname(file_path.path), '.pdf');
385
- */
397
+
398
+ let pdf_txt = await hdoc_build_pdf.process_images(file_path, html_txt);
399
+ pdf_txt = `${pdf_header}\n${pdf_txt}`;
400
+
401
+ // Generate PDF file from HTML
402
+ const pdf_file_path = file_path.path.replace(path.extname(file_path.path), '.pdf');
403
+ await hdoc_build_pdf.generate_pdf(pdf_template_path, pdf_template, hdocbook_config, pdf_txt, pdf_file_path, verbose);
404
+
386
405
  html_txt = `${fm_header}\n${doc_header}\n${html_txt}`;
387
406
 
388
407
  // Save HTML into HTML file
@@ -658,21 +677,32 @@
658
677
  try {
659
678
  doc_header_template = fs.readFileSync(doc_header_template_path, 'utf8');
660
679
  doc_header_template_non_git = fs.readFileSync(non_git_doc_header_template_path, 'utf8');
680
+ pdf_header_template = fs.readFileSync(pdf_header_template_path, 'utf8');
681
+ pdf_header_template_non_git = fs.readFileSync(non_git_pdf_header_template_path, 'utf8');
661
682
  } catch (err) {
662
683
  console.log(`Error reading document header template: ${err}`);
663
684
  process.exit(1);
664
685
  }
665
686
 
687
+ // Load PDF templates
688
+ try {
689
+ pdf_template = fs.readFileSync(pdf_template_file_path, 'utf8');
690
+ } catch (err) {
691
+ console.log(`Error reading PDF template: ${err}`);
692
+ process.exit(1);
693
+ }
694
+
666
695
  build_breadcrumbs(hdocbook_config.navigation.items);
667
696
 
697
+ console.log('Processing content...');
668
698
  // Get a list of MD files in work_path
669
699
  dree.scan(work_path, dreeOptions, build_file_callback);
670
700
 
671
701
  // Work through MD files and convert to HTML
672
702
  for (let i = 0; i < md_files.length; i++) {
673
- await transform_markdown_and_save_html(md_files[i]);
703
+ await transform_markdown_and_save_html(md_files[i], verbose);
674
704
  }
675
-
705
+
676
706
  // Work through Static HTML files and add Frontmatter tags
677
707
  for (let i = 0; i < static_html_files.length; i++) {
678
708
  await transform_static_html(static_html_files[i]);
package/hdoc-init.js CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  // Required modules
5
5
  const prompt = require('prompt');
6
- //const fs = require('fs');
7
6
  const fs = require('fs-extra');
8
7
  const path = require('path');
9
8
 
package/hdoc-validate.js CHANGED
@@ -1,5 +1,3 @@
1
- const parseLinkDestination = require('markdown-it/lib/helpers/parse_link_destination');
2
-
3
1
  (function () {
4
2
  'use strict';
5
3
 
package/hdoc.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  (async function () {
4
4
  'use strict';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.8.23",
3
+ "version": "0.8.24",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "hdoc-db.js",
12
12
  "hdoc-build.js",
13
13
  "hdoc-build-db.js",
14
+ "hdoc-build-pdf.js",
14
15
  "hdoc-help.js",
15
16
  "hdoc-init.js",
16
17
  "hdoc-module.js",
@@ -43,9 +44,10 @@
43
44
  "markdown-it": "^13.0.1",
44
45
  "markdown-it-container": "^3.0.0",
45
46
  "markdown-it-front-matter": "^0.2.3",
47
+ "mime-types": "^2.1.35",
46
48
  "multer": "^1.4.5-lts.1",
47
- "pdf-creator-node": "^2.3.5",
48
49
  "prompt": "^1.3.0",
50
+ "puppeteer": "^19.6.0",
49
51
  "stream": "0.0.2",
50
52
  "sync-request": "^6.1.0",
51
53
  "words-count": "^2.0.2",
@@ -0,0 +1,90 @@
1
+ .custom-block {
2
+ border: 1px solid transparent;
3
+ border-radius: 8px;
4
+ padding: 16px 16px 8px;
5
+ line-height: 24px;
6
+ font-size: var(--htl-default-font-size);
7
+ color: var(--htl-c-text-2);
8
+ }
9
+
10
+ .custom-block.info {
11
+ border-color: var(--htl-custom-block-info-border);
12
+ color: var(--htl-custom-block-info-text);
13
+ background-color: var(--htl-custom-block-info-bg);
14
+ }
15
+
16
+ .custom-block.info code {
17
+ background-color: var(--htl-custom-block-info-code-bg);
18
+ }
19
+
20
+ .custom-block.tip {
21
+ border-color: var(--htl-custom-block-tip-border);
22
+ color: var(--htl-custom-block-tip-text);
23
+ background-color: var(--htl-custom-block-tip-bg);
24
+ }
25
+
26
+ .custom-block.tip code {
27
+ background-color: var(--htl-custom-block-tip-code-bg);
28
+ }
29
+
30
+ .custom-block.warning {
31
+ border-color: var(--htl-custom-block-warning-border);
32
+ color: var(--htl-custom-block-warning-text);
33
+ background-color: var(--htl-custom-block-warning-bg);
34
+ }
35
+
36
+ .custom-block.warning code {
37
+ background-color: var(--htl-custom-block-warning-code-bg);
38
+ }
39
+
40
+ .custom-block.danger {
41
+ border-color: var(--htl-custom-block-danger-border);
42
+ color: var(--htl-custom-block-danger-text);
43
+ background-color: var(--htl-custom-block-danger-bg);
44
+ }
45
+
46
+ .custom-block.danger code {
47
+ background-color: var(--htl-custom-block-danger-code-bg);
48
+ }
49
+
50
+ .custom-block.details {
51
+ border-color: var(--htl-custom-block-details-border);
52
+ color: var(--htl-custom-block-details-text);
53
+ background-color: var(--htl-custom-block-details-bg);
54
+ }
55
+
56
+ .custom-block.details code {
57
+ background-color: var(--htl-custom-block-details-code-bg);
58
+ }
59
+
60
+ .custom-block-title {
61
+ font-weight: 700;
62
+ }
63
+
64
+ .custom-block p + p {
65
+ margin: 8px 0;
66
+ }
67
+
68
+ .custom-block.details summary {
69
+ margin: 0 0 8px;
70
+ font-weight: 700;
71
+ }
72
+
73
+ .custom-block.details summary + p {
74
+ margin: 8px 0;
75
+ }
76
+
77
+ .custom-block a {
78
+ color: inherit;
79
+ font-weight: 600;
80
+ text-decoration: underline;
81
+ transition: opacity 0.25s;
82
+ }
83
+
84
+ .custom-block a:hover {
85
+ opacity: 0.6;
86
+ }
87
+
88
+ .custom-block code {
89
+ font-size: var(--htl-custom-block-code-font-size);
90
+ }
@@ -0,0 +1,221 @@
1
+ /* webfont-marker-begin */
2
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
3
+ /* webfont-marker-end */
4
+
5
+ @font-face {
6
+ font-family: 'Inter var';
7
+ font-weight: 100 900;
8
+ font-display: swap;
9
+ font-style: normal;
10
+ font-named-instance: 'Regular';
11
+ src: url('../fonts/inter-roman-cyrillic.woff2') format('woff2');
12
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
13
+ }
14
+
15
+ @font-face {
16
+ font-family: 'Inter var';
17
+ font-weight: 100 900;
18
+ font-display: swap;
19
+ font-style: normal;
20
+ font-named-instance: 'Regular';
21
+ src: url('../fonts/inter-roman-cyrillic-ext.woff2') format('woff2');
22
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
23
+ U+FE2E-FE2F;
24
+ }
25
+
26
+ @font-face {
27
+ font-family: 'Inter var';
28
+ font-weight: 100 900;
29
+ font-display: swap;
30
+ font-style: normal;
31
+ font-named-instance: 'Regular';
32
+ src: url('../fonts/inter-roman-greek.woff2') format('woff2');
33
+ unicode-range: U+0370-03FF;
34
+ }
35
+
36
+ @font-face {
37
+ font-family: 'Inter var';
38
+ font-weight: 100 900;
39
+ font-display: swap;
40
+ font-style: normal;
41
+ font-named-instance: 'Regular';
42
+ src: url('../fonts/inter-roman-greek-ext.woff2') format('woff2');
43
+ unicode-range: U+1F00-1FFF;
44
+ }
45
+
46
+ @font-face {
47
+ font-family: 'Inter var';
48
+ font-weight: 100 900;
49
+ font-display: swap;
50
+ font-style: normal;
51
+ font-named-instance: 'Regular';
52
+ src: url('../fonts/inter-roman-latin.woff2') format('woff2');
53
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
54
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
55
+ U+FEFF, U+FFFD;
56
+ }
57
+
58
+ @font-face {
59
+ font-family: 'Inter var';
60
+ font-weight: 100 900;
61
+ font-display: swap;
62
+ font-style: normal;
63
+ font-named-instance: 'Regular';
64
+ src: url('../fonts/inter-roman-latin-ext.woff2') format('woff2');
65
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
66
+ U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
67
+ }
68
+
69
+ @font-face {
70
+ font-family: 'Inter var';
71
+ font-weight: 100 900;
72
+ font-display: swap;
73
+ font-style: normal;
74
+ font-named-instance: 'Regular';
75
+ src: url('../fonts/inter-roman-vietnamese.woff2') format('woff2');
76
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
77
+ U+01AF-01B0, U+1EA0-1EF9, U+20AB;
78
+ }
79
+
80
+ @font-face {
81
+ font-family: 'Inter var';
82
+ font-weight: 100 900;
83
+ font-display: swap;
84
+ font-style: italic;
85
+ font-named-instance: 'Italic';
86
+ src: url('../fonts/inter-italic-cyrillic.woff2') format('woff2');
87
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
88
+ }
89
+
90
+ @font-face {
91
+ font-family: 'Inter var';
92
+ font-weight: 100 900;
93
+ font-display: swap;
94
+ font-style: italic;
95
+ font-named-instance: 'Italic';
96
+ src: url('../fonts/inter-italic-cyrillic-ext.woff2') format('woff2');
97
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
98
+ U+FE2E-FE2F;
99
+ }
100
+
101
+ @font-face {
102
+ font-family: 'Inter var';
103
+ font-weight: 100 900;
104
+ font-display: swap;
105
+ font-style: italic;
106
+ font-named-instance: 'Italic';
107
+ src: url('../fonts/inter-italic-greek.woff2') format('woff2');
108
+ unicode-range: U+0370-03FF;
109
+ }
110
+
111
+ @font-face {
112
+ font-family: 'Inter var';
113
+ font-weight: 100 900;
114
+ font-display: swap;
115
+ font-style: italic;
116
+ font-named-instance: 'Italic';
117
+ src: url('../fonts/inter-italic-greek-ext.woff2') format('woff2');
118
+ unicode-range: U+1F00-1FFF;
119
+ }
120
+
121
+ @font-face {
122
+ font-family: 'Inter var';
123
+ font-weight: 100 900;
124
+ font-display: swap;
125
+ font-style: italic;
126
+ font-named-instance: 'Italic';
127
+ src: url('../fonts/inter-italic-latin.woff2') format('woff2');
128
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
129
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
130
+ U+FEFF, U+FFFD;
131
+ }
132
+
133
+ @font-face {
134
+ font-family: 'Inter var';
135
+ font-weight: 100 900;
136
+ font-display: swap;
137
+ font-style: italic;
138
+ font-named-instance: 'Italic';
139
+ src: url('../fonts/inter-italic-latin-ext.woff2') format('woff2');
140
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
141
+ U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
142
+ }
143
+
144
+ @font-face {
145
+ font-family: 'Inter var';
146
+ font-weight: 100 900;
147
+ font-display: swap;
148
+ font-style: italic;
149
+ font-named-instance: 'Italic';
150
+ src: url('../fonts/inter-italic-vietnamese.woff2') format('woff2');
151
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
152
+ U+01AF-01B0, U+1EA0-1EF9, U+20AB;
153
+ }
154
+
155
+ @font-face {
156
+ font-family: 'Inter var experimental';
157
+ font-weight: 100 900;
158
+ font-display: swap;
159
+ font-style: oblique 0deg 10deg;
160
+ src: url('../fonts/inter-cyrillic.woff2') format('woff2');
161
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
162
+ }
163
+
164
+ @font-face {
165
+ font-family: 'Inter var experimental';
166
+ font-weight: 100 900;
167
+ font-display: swap;
168
+ font-style: oblique 0deg 10deg;
169
+ src: url('../fonts/inter-cyrillic-ext.woff2') format('woff2');
170
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
171
+ U+FE2E-FE2F;
172
+ }
173
+
174
+ @font-face {
175
+ font-family: 'Inter var experimental';
176
+ font-weight: 100 900;
177
+ font-display: swap;
178
+ font-style: oblique 0deg 10deg;
179
+ src: url('../fonts/inter-greek.woff2') format('woff2');
180
+ unicode-range: U+0370-03FF;
181
+ }
182
+
183
+ @font-face {
184
+ font-family: 'Inter var experimental';
185
+ font-weight: 100 900;
186
+ font-display: swap;
187
+ font-style: oblique 0deg 10deg;
188
+ src: url('../fonts/inter-greek-ext.woff2') format('woff2');
189
+ unicode-range: U+1F00-1FFF;
190
+ }
191
+
192
+ @font-face {
193
+ font-family: 'Inter var experimental';
194
+ font-weight: 100 900;
195
+ font-display: swap;
196
+ font-style: oblique 0deg 10deg;
197
+ src: url('../fonts/inter-latin.woff2') format('woff2');
198
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
199
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
200
+ U+FEFF, U+FFFD;
201
+ }
202
+
203
+ @font-face {
204
+ font-family: 'Inter var experimental';
205
+ font-weight: 100 900;
206
+ font-display: swap;
207
+ font-style: oblique 0deg 10deg;
208
+ src: url('../fonts/inter-latin-ext.woff2') format('woff2');
209
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
210
+ U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
211
+ }
212
+
213
+ @font-face {
214
+ font-family: 'Inter var experimental';
215
+ font-weight: 100 900;
216
+ font-display: swap;
217
+ font-style: oblique 0deg 10deg;
218
+ src: url('../fonts/inter-vietnamese.woff2') format('woff2');
219
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
220
+ U+01AF-01B0, U+1EA0-1EF9, U+20AB;
221
+ }