@adobe/helix-importer 1.2.2 → 1.3.0

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.3.0](https://github.com/adobe/helix-importer/compare/v1.2.2...v1.3.0) (2022-01-31)
2
+
3
+
4
+ ### Features
5
+
6
+ * restore custom handlers ([a051c80](https://github.com/adobe/helix-importer/commit/a051c80e18d23c87b845c6fc023e81f788d5e9fc))
7
+
1
8
  ## [1.2.2](https://github.com/adobe/helix-importer/compare/v1.2.1...v1.2.2) (2022-01-25)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-importer",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Helix Importer tool: create md / docx from html",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -33,6 +33,7 @@
33
33
  "@semantic-release/git": "10.0.1",
34
34
  "c8": "7.11.0",
35
35
  "codecov": "3.8.3",
36
+ "dirname-filename-esm": "1.1.1",
36
37
  "eslint": "8.7.0",
37
38
  "eslint-plugin-header": "3.1.1",
38
39
  "eslint-plugin-import": "2.25.4",
@@ -20,7 +20,6 @@ import parse from 'rehype-parse';
20
20
  import { toHtml } from 'hast-util-to-html';
21
21
  import rehype2remark from 'rehype-remark';
22
22
  import stringify from 'remark-stringify';
23
- import { all } from 'hast-util-to-mdast/lib/all.js';
24
23
  import fs from 'fs-extra';
25
24
  import { md2docx } from '@adobe/helix-md2docx';
26
25
  import Utils from '../utils/Utils.js';
@@ -56,9 +55,18 @@ export default class PageImporter {
56
55
  .use(parse, { emitParseErrors: true })
57
56
  .use(rehype2remark, {
58
57
  handlers: {
59
- hlxembed: (h, node) => h(node, 'hlxembed', node.children[0].value),
60
- u: (h, node) => h(node, 'u', all(h, node)),
61
- table: (h, node) => h(node, 'table', toHtml(node)),
58
+ hlxembed: (h, node) => {
59
+ const children = node.children.map((child) => processor.stringify(child).trim());
60
+ return h(node, 'text', `${children.join()}\n`);
61
+ },
62
+ u: (h, node) => {
63
+ if (node.children && node.children.length > 0) {
64
+ const children = node.children.map((child) => processor.stringify(child).trim());
65
+ return h(node, 'html', `<u>${children.join()}</u>`);
66
+ }
67
+ return '';
68
+ },
69
+ table: (h, node) => h(node, 'html', toHtml(node)),
62
70
  },
63
71
  })
64
72
  .use(stringify, {
@@ -69,36 +77,6 @@ export default class PageImporter {
69
77
  rule: '-',
70
78
  ruleRepetition: 3,
71
79
  ruleSpaces: false,
72
- })
73
- .use(() => {
74
- // use custom tag and rendering because text is always encoded by default
75
- // we need the raw url
76
- // processor.Compiler.prototype.visitors.hlxembed = (node) => node.value;
77
- })
78
- .use(() => {
79
- // processor.Compiler.prototype.visitors.table = (node) => node.value;
80
- })
81
- .use(() => {
82
- // processor.Compiler.prototype.visitors.u = (node) => {
83
- // // u handling: remove the u is the first element is a link
84
- // if (node.children && node.children.length > 0) {
85
- // const children = node.children.map((child) => processor.stringify(child));
86
- // if (node.children[0].type === 'link') {
87
- // // first element in the <u> is a link: remove the <u> - unsupported case
88
- // return `${children.join()}`;
89
- // }
90
- // return `<u>${children.join()}</u>`;
91
- // }
92
- // return '';
93
- // };
94
- })
95
- .use(() => {
96
- // const originalEmphasis = processor.Compiler.prototype.visitors.emphasis;
97
- // processor.Compiler.prototype.visitors.emphasis = (node) => {
98
- // // @ts-ignore
99
- // const ori = originalEmphasis.apply(processor.Compiler(), [node]);
100
- // return ori;
101
- // };
102
80
  });
103
81
 
104
82
  const file = await processor.process(resource.document.innerHTML);
@@ -256,19 +234,7 @@ export default class PageImporter {
256
234
  }
257
235
 
258
236
  postProcessMD(md) {
259
- let ret = md.replace(/\\\\~/gm, '\\~');
260
-
261
- const match = ret.match(/hlx_replaceTag\(.*?\)/gm);
262
- if (match) {
263
- const hlxReplaceTags = match.filter((i, p, s) => s.indexOf(i) === p);
264
- hlxReplaceTags.forEach((r) => {
265
- const by = r.substring(0, r.length - 1).split('(')[1];
266
- const regex = new RegExp(r.replace('(', '\\(').replace(')', '\\)'), 'gm');
267
- ret = ret.replace(regex, `<${by}>`);
268
- });
269
- }
270
-
271
- return ret;
237
+ return md.replace(/\\\\~/gm, '\\~');
272
238
  }
273
239
 
274
240
  async download(url) {
@@ -38,13 +38,11 @@ export default class Blocks {
38
38
  const value = metadata[key];
39
39
  if (value) {
40
40
  if (Array.isArray(value)) {
41
- let list = '';
42
41
  value.forEach((v) => {
43
- // p tags in table are stripped out
44
- // list must receive special hlx_replaceTag command to be post-processed
45
- list += `hlx_replaceTag(p)${v}hlx_replaceTag(/p)`;
42
+ const p = document.createElement('p');
43
+ p.innerHTML = v;
44
+ valueCell.append(p);
46
45
  });
47
- valueCell.textContent = list;
48
46
  } else if (typeof value === 'string') {
49
47
  valueCell.textContent = value;
50
48
  } else {
@@ -79,8 +77,6 @@ export default class Blocks {
79
77
  const cellContent = [];
80
78
  Array.from(cell.childNodes).forEach((c) => cellContent.push(c));
81
79
  rowData.push(cellContent);
82
- } else {
83
- rowData.push(cell);
84
80
  }
85
81
  });
86
82
  data.push(rowData);
@@ -202,4 +202,79 @@ describe('PagingExplorer tests', () => {
202
202
  const se = new Test(params);
203
203
  await se.explore();
204
204
  });
205
+
206
+ it('explorer params are honored', async () => {
207
+ const start = 2;
208
+ let callbackCalled = 0;
209
+ let processCalled = 0;
210
+ class Test extends PagingExplorer {
211
+ async fetch() {
212
+ return new Response('test');
213
+ }
214
+
215
+ process() {
216
+ processCalled += 1;
217
+ return [{
218
+ a: processCalled + start - 1,
219
+ }];
220
+ }
221
+ }
222
+
223
+ const se = new Test(params);
224
+ const results = await se.explore(2, () => {
225
+ callbackCalled += 1;
226
+ });
227
+
228
+ strictEqual(callbackCalled, 2, 'callback called twice');
229
+ deepStrictEqual(results, [{ a: 2 }, { a: 3 }], 'result is correct');
230
+ });
231
+
232
+ it('no text in response', async () => {
233
+ let processCalled = 0;
234
+ class Test extends PagingExplorer {
235
+ async fetch() {
236
+ if (processCalled < 2) {
237
+ return new Response('test');
238
+ }
239
+ return new Response('');
240
+ }
241
+
242
+ process() {
243
+ processCalled += 1;
244
+ return [{
245
+ a: processCalled,
246
+ }];
247
+ }
248
+ }
249
+
250
+ const se = new Test(params);
251
+ const results = await se.explore();
252
+
253
+ deepStrictEqual(results, [{ a: 1 }, { a: 2 }], 'result is correct');
254
+ });
255
+
256
+ it('no entries on page', async () => {
257
+ let processCalled = 0;
258
+ class Test extends PagingExplorer {
259
+ async fetch() {
260
+ return new Response('test');
261
+ }
262
+
263
+ process() {
264
+ if (processCalled < 2) {
265
+ processCalled += 1;
266
+ return [{
267
+ a: processCalled,
268
+ }];
269
+ } else {
270
+ return null;
271
+ }
272
+ }
273
+ }
274
+
275
+ const se = new Test(params);
276
+ const results = await se.explore();
277
+
278
+ deepStrictEqual(results, [{ a: 1 }, { a: 2 }], 'result is correct');
279
+ });
205
280
  });
@@ -12,9 +12,12 @@
12
12
 
13
13
  /* eslint-disable max-classes-per-file, class-methods-use-this */
14
14
 
15
+ import path from 'path';
16
+ import fs from 'fs-extra';
15
17
  import { strictEqual, ok } from 'assert';
16
18
  import { describe, it } from 'mocha';
17
19
  import { Response } from 'node-fetch';
20
+ import { dirname } from 'dirname-filename-esm';
18
21
 
19
22
  import { docx2md } from '@adobe/helix-docx2md';
20
23
 
@@ -25,6 +28,9 @@ import MemoryHandler from '../../src/storage/MemoryHandler.js';
25
28
  import MockMediaHandler from '../mocks/MockMediaHandler.js';
26
29
  import NoopLogger from '../mocks/NoopLogger.js';
27
30
 
31
+ // eslint-disable-next-line no-underscore-dangle
32
+ const __dirname = dirname(import.meta);
33
+
28
34
  const logger = new NoopLogger();
29
35
 
30
36
  describe('PageImporter tests', () => {
@@ -84,3 +90,58 @@ describe('PageImporter tests - various options', () => {
84
90
  strictEqual(md, test, 'valid backward conversion');
85
91
  });
86
92
  });
93
+
94
+ describe('PageImporter tests - fixtures', () => {
95
+ const featureTest = async (feature) => {
96
+ class Test extends PageImporter {
97
+ async fetch() {
98
+ const html = await fs.readFile(path.resolve(__dirname, 'fixtures', `${feature}.spec.html`), 'utf-8');
99
+ return new Response(html);
100
+ }
101
+
102
+ async process(document) {
103
+ const pir = new PageImporterResource(feature, '', document.documentElement, null, null);
104
+ return [pir];
105
+ }
106
+ }
107
+
108
+ const storageHandler = new MemoryHandler(logger);
109
+ const config = {
110
+ storageHandler,
111
+ skipDocxConversion: true,
112
+ logger,
113
+ };
114
+ const se = new Test(config);
115
+ const results = await se.import(`https://www.sample.com/${feature}`);
116
+
117
+ strictEqual(results.length, 1, 'expect one result');
118
+
119
+ const md = await storageHandler.get(`/${feature}.md`);
120
+ const expectedMD = await fs.readFile(path.resolve(__dirname, 'fixtures', `${feature}.spec.md`), 'utf-8');
121
+ strictEqual(md.trim(), expectedMD.trim(), 'inported md is expected one');
122
+ };
123
+
124
+ it('import - tables', async () => {
125
+ await featureTest('table');
126
+ });
127
+
128
+ it('import - underlines', async () => {
129
+ await featureTest('u');
130
+ });
131
+
132
+ it('import - links', async () => {
133
+ await featureTest('link');
134
+ });
135
+
136
+ it('import - spans', async () => {
137
+ await featureTest('span');
138
+ });
139
+
140
+ it('import - emphasises', async () => {
141
+ await featureTest('em');
142
+ });
143
+
144
+ it('import - complex', async () => {
145
+ await featureTest('complex');
146
+ });
147
+ });
@@ -0,0 +1,70 @@
1
+ <div class="js-post-content blogPostMain">
2
+ <section class="blogPostBanner__container">
3
+ <div class="blogPostBanner__imgContainer js-parallax">
4
+ <h1 class="blogPostContent__title">How Sample Performance Management Improved in 2021</h1><img src="https://www.sample.com/blog/wp-content/uploads/How-Sample-Performance-Management-Improved-in-2021_1920x733-scaled.jpg">
5
+ </div>
6
+
7
+ </section>
8
+
9
+ <section class="blogPostContent__wrapper" aria-label="Sample blog post main content" role="main">
10
+
11
+
12
+ <div class="blogPostContent__bg"></div>
13
+ <div class="bhrsection-padding">
14
+ <div class="bhrsection-container-sm">
15
+ <div class="blogPostContent__container blogPostContent__container--product-announcements js-page-color" data-page-color="#1d9336" data-page-color3="#edffc8">
16
+
17
+
18
+
19
+
20
+ <div class="blogPostContentDetail__container">
21
+
22
+ <div class="blogPostContent blogPostContent--default">
23
+ <div class="essb_break_scroll"></div> </div>
24
+
25
+ <div class="blogPostContent">
26
+ <p>Over the course of 2021, we've improved Sample® Performance Management with more flexibility and greater depth, giving you more choice for the when, who, and how of the performance management process at your organization. Here's a quick summary to let you know how to take advantage of these updates.</p>
27
+ <h2>Scheduling Flexibility and Improved Search in Reports</h2>
28
+ <p>These updates give greater flexibility in the cadence and dates you administer assessments and feedback. We separated scheduling for assessments and feedback, so each process can operate on separate timelines depending on your needs. For example, you might choose to have feedback sessions every four months while keeping formal assessments on a six-month schedule.</p>
29
+ <div class="blogPostContent__fullWidthImgContainer">
30
+ <img class="blogPostContent__fullWidthImg lazyload " src="https://www.sample.com/blog/wp-content/uploads/Screen_Shot_2022-01-05_at_9.26.41_AM.png" alt="Screen_Shot_2022-01-05_at_9.26.41_AM">
31
+ </div>
32
+ <p>We also made performance reports searchable by date range instead of tying them to individual Performance Management events.</p>
33
+ <h2>Additional Assessment Flexibility</h2>
34
+ <p>When an employee moves to a new team right before their scheduled assessment, their new manager might not have what they need to make accurate observations. To resolve this issue, you now have the option to <a href="https://help.sample.com/hc/en-us/articles/360060935131-skip-assessments">skip a regularly-scheduled assessment</a>.</p>
35
+ <div class="blogPostContent__fullWidthImgContainer">
36
+ <img class="blogPostContent__fullWidthImg lazyload " src="https://www.sample.com/blog/wp-content/uploads/a66eddc3-4e16-49a9-b597-1151e233790d.png" alt="a66eddc3-4e16-49a9-b597-1151e233790d">
37
+ </div>
38
+ <p>This doesn't mean someone who skips an assessment has to go without feedback for months. Scheduling <a href="https://help.sample.com/hc/en-us/articles/360060531312-impromptu-assessments">impromptu assessments</a> helps you keep employees informed during off-cycle evaluations, such as:</p>
39
+ <ul>
40
+ <li style="font-weight: 400;" aria-level="1">When considering employees for a promotion or raise</li>
41
+ <li style="font-weight: 400;" aria-level="1">When they face disciplinary action</li>
42
+ <li style="font-weight: 400;" aria-level="1">On their anniversary</li>
43
+ <li style="font-weight: 400;" aria-level="1">As part of their onboarding process</li>
44
+ </ul>
45
+ <div class="blogPostContent__fullWidthImgContainer">
46
+ <img class="blogPostContent__fullWidthImg lazyload " src="https://www.sample.com/blog/wp-content/uploads/Impromptu-Assessment-1.png" alt="Impromptu Assessment (1)">
47
+ </div>
48
+ <h2>Expanded Feedback</h2>
49
+ <p>Great feedback can come from anyone who interacts with an employee, from their closest co-workers to employees in a different department who regularly rely on their efforts. We updated our Feedback feature to emphasize this breadth of feedback, expanding the maximum number of reviewers to 10 per employee.</p>
50
+ <p>Feedback is also no longer limited to assessment periods, letting you ask in the moment for what you need. Here are a few examples:</p>
51
+ <ul>
52
+ <li style="font-weight: 400;" aria-level="1">After a big project, the manager wants to see how the team lead performed. They can send feedback requests to everyone involved in it. This could include team members, directors and executives they presented to, or other departments that they trained.</li>
53
+ <li style="font-weight: 400;" aria-level="1">A manager thinks an employee is struggling and wants to know how well the employee works with their peers or with other departments. This feedback can help the manager understand an employee's situation before speaking with them.</li>
54
+ <li style="font-weight: 400;" aria-level="1">An employee is up for a promotion, and the manager would like to understand how the employee works with others.</li>
55
+ </ul>
56
+ <h2>Sample Performance Management: Timely and Targeted</h2>
57
+ <p>These updates help expand Performance Management's reach and help your managers and employees provide meaningful, accurate feedback through continuing conversations. For more information on each of these updates, click the links below:</p>
58
+ <p><a href="https://help.sample.com/hc/en-us/articles/360060533412-Skip-and-Impromptu-Assessments-5-6-2021-">Skip and Impromptu Assessments</a></p>
59
+ <p><a href="https://help.sample.com/hc/en-us/articles/4415512886669-We-ve-Added-Flexibility-to-Performance-Management-12-3-2021-">Impromptu Feedback</a></p>
60
+ <p><a href="https://help.sample.com/hc/en-us/articles/4406463743501-More-Opportunities-for-Peer-Feedback-Participants-8-4-2021-">Feedback Request Limit Increase</a></p>
61
+ <p><a href="https://help.sample.com/hc/en-us/articles/360057083332-Performance-Management-Settings-Update-2-25-2021-">Performance Settings Updates</a></p>
62
+ </div>
63
+
64
+ </div>
65
+
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </section>
70
+ <table><tr><th>Related Posts</th></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/how-sample-performance-management-improved-in-2021/" aria-label="How Sample Performance Management Improved in 2021">https://www.sample.com/blog/how-sample-performance-management-improved-in-2021/</a></td></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/announcing-the-product-updates-webpage/" aria-label="Announcing the Product Updates Webpage">https://www.sample.com/blog/announcing-the-product-updates-webpage/</a></td></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/take-a-look-back-at-2021/" aria-label="Take a Look Back at 2021">https://www.sample.com/blog/take-a-look-back-at-2021/</a></td></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/whats-new-in-sample-vaccination-tracking-feature/" aria-label="What's New in Sample: Vaccination Tracking Feature">https://www.sample.com/blog/whats-new-in-sample-vaccination-tracking-feature/</a></td></tr></table><table><tr><th colspan="2">Metadata</th></tr><tr><td>Title</td><td>How Sample Performance Management Improved in 2021 - Sample Blog</td></tr><tr><td>Description</td><td>In 2021, we improved Sample® Performance Management with more flexibility and greater depth, giving you finer control of your performance management.</td></tr><tr><td>Category</td><td>Product Announcements</td></tr><tr><td>Author</td><td><a href="https://www.sample.com/blog/author/eserdar/" rel="author" class="fn" style="color: #1d9336;">Eric Serdar</a></td></tr><tr><td>Read Time</td><td> 8 min</td></tr><tr><td>Image</td><td><img src="https://www.sample.com/blog/wp-content/uploads/How-Sample-Performance-Management-Improved-in-2021_1200x628-1024x536.jpg"></td></tr></table></div>
@@ -0,0 +1,54 @@
1
+ # How Sample Performance Management Improved in 2021
2
+
3
+ ![](https://www.sample.com/blog/wp-content/uploads/How-Sample-Performance-Management-Improved-in-2021_1920x733-scaled.jpg)
4
+
5
+ Over the course of 2021, we've improved Sample® Performance Management with more flexibility and greater depth, giving you more choice for the when, who, and how of the performance management process at your organization. Here's a quick summary to let you know how to take advantage of these updates.
6
+
7
+ ## Scheduling Flexibility and Improved Search in Reports
8
+
9
+ These updates give greater flexibility in the cadence and dates you administer assessments and feedback. We separated scheduling for assessments and feedback, so each process can operate on separate timelines depending on your needs. For example, you might choose to have feedback sessions every four months while keeping formal assessments on a six-month schedule.
10
+
11
+ ![Screen\_Shot\_2022-01-05\_at\_9.26.41\_AM](https://www.sample.com/blog/wp-content/uploads/Screen_Shot_2022-01-05_at_9.26.41_AM.png)
12
+
13
+ We also made performance reports searchable by date range instead of tying them to individual Performance Management events.
14
+
15
+ ## Additional Assessment Flexibility
16
+
17
+ When an employee moves to a new team right before their scheduled assessment, their new manager might not have what they need to make accurate observations. To resolve this issue, you now have the option to [skip a regularly-scheduled assessment](https://help.sample.com/hc/en-us/articles/360060935131-skip-assessments).
18
+
19
+ ![a66eddc3-4e16-49a9-b597-1151e233790d](https://www.sample.com/blog/wp-content/uploads/a66eddc3-4e16-49a9-b597-1151e233790d.png)
20
+
21
+ This doesn't mean someone who skips an assessment has to go without feedback for months. Scheduling [impromptu assessments](https://help.sample.com/hc/en-us/articles/360060531312-impromptu-assessments) helps you keep employees informed during off-cycle evaluations, such as:
22
+
23
+ - When considering employees for a promotion or raise
24
+ - When they face disciplinary action
25
+ - On their anniversary
26
+ - As part of their onboarding process
27
+
28
+ ![Impromptu Assessment (1)](https://www.sample.com/blog/wp-content/uploads/Impromptu-Assessment-1.png)
29
+
30
+ ## Expanded Feedback
31
+
32
+ Great feedback can come from anyone who interacts with an employee, from their closest co-workers to employees in a different department who regularly rely on their efforts. We updated our Feedback feature to emphasize this breadth of feedback, expanding the maximum number of reviewers to 10 per employee.
33
+
34
+ Feedback is also no longer limited to assessment periods, letting you ask in the moment for what you need. Here are a few examples:
35
+
36
+ - After a big project, the manager wants to see how the team lead performed. They can send feedback requests to everyone involved in it. This could include team members, directors and executives they presented to, or other departments that they trained.
37
+ - A manager thinks an employee is struggling and wants to know how well the employee works with their peers or with other departments. This feedback can help the manager understand an employee's situation before speaking with them.
38
+ - An employee is up for a promotion, and the manager would like to understand how the employee works with others.
39
+
40
+ ## Sample Performance Management: Timely and Targeted
41
+
42
+ These updates help expand Performance Management's reach and help your managers and employees provide meaningful, accurate feedback through continuing conversations. For more information on each of these updates, click the links below:
43
+
44
+ [Skip and Impromptu Assessments](https://help.sample.com/hc/en-us/articles/360060533412-Skip-and-Impromptu-Assessments-5-6-2021-)
45
+
46
+ [Impromptu Feedback](https://help.sample.com/hc/en-us/articles/4415512886669-We-ve-Added-Flexibility-to-Performance-Management-12-3-2021-)
47
+
48
+ [Feedback Request Limit Increase](https://help.sample.com/hc/en-us/articles/4406463743501-More-Opportunities-for-Peer-Feedback-Participants-8-4-2021-)
49
+
50
+ [Performance Settings Updates](https://help.sample.com/hc/en-us/articles/360057083332-Performance-Management-Settings-Update-2-25-2021-)
51
+
52
+ <table><tbody><tr><th>Related Posts</th></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/how-sample-performance-management-improved-in-2021/" aria-label="How Sample Performance Management Improved in 2021">https://www.sample.com/blog/how-sample-performance-management-improved-in-2021/</a></td></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/announcing-the-product-updates-webpage/" aria-label="Announcing the Product Updates Webpage">https://www.sample.com/blog/announcing-the-product-updates-webpage/</a></td></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/take-a-look-back-at-2021/" aria-label="Take a Look Back at 2021">https://www.sample.com/blog/take-a-look-back-at-2021/</a></td></tr><tr><td><a class="blogPostsBlock__titleLink" href="https://www.sample.com/blog/whats-new-in-sample-vaccination-tracking-feature/" aria-label="What&#x27;s New in Sample: Vaccination Tracking Feature">https://www.sample.com/blog/whats-new-in-sample-vaccination-tracking-feature/</a></td></tr></tbody></table>
53
+
54
+ <table><tbody><tr><th colspan="2">Metadata</th></tr><tr><td>Title</td><td>How Sample Performance Management Improved in 2021 - Sample Blog</td></tr><tr><td>Description</td><td>In 2021, we improved Sample® Performance Management with more flexibility and greater depth, giving you finer control of your performance management.</td></tr><tr><td>Category</td><td>Product Announcements</td></tr><tr><td>Author</td><td><a href="https://www.sample.com/blog/author/eserdar/" rel="author" class="fn" style="color: #1d9336;">Eric Serdar</a></td></tr><tr><td>Read Time</td><td>8 min</td></tr><tr><td>Image</td><td><img src="https://www.sample.com/blog/wp-content/uploads/How-Sample-Performance-Management-Improved-in-2021_1200x628-1024x536.jpg"></td></tr></tbody></table>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <body>
3
+ <h1>EM sample</h1>
4
+ <p><strong><em>&nbsp;</em></strong></p><p>usefull</p>
5
+ <p><strong><em>emphasis</em></strong><strong><em> space </em></strong><strong><em>another emphasis</em></strong> <strong><em>last emphasis</em></strong></p>
6
+ <p><a href="https://www.sample.com">linkcontent</a><i>. </i></p>
7
+ </body>
8
+ </html>
@@ -0,0 +1,7 @@
1
+ # EM sample
2
+
3
+ usefull
4
+
5
+ ***emphasis* *space* *another emphasis* *last emphasis***
6
+
7
+ [linkcontent](https://www.sample.com).
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <body>
3
+ <h1>Links sample</h1>
4
+ <p><a href="http://wwww.sample.com/a">Link on a single online</a></p>
5
+ <a href="http://wwww.sample.com/b">Link without p</a>
6
+ <p>http://wwww.sample.com/c</p>
7
+ <hlxembed>http://wwww.sample.com/d</hlxembed>
8
+ </body>
9
+ </html>
@@ -0,0 +1,9 @@
1
+ # Links sample
2
+
3
+ [Link on a single online](http://wwww.sample.com/a)
4
+
5
+ [Link without p](http://wwww.sample.com/b)
6
+
7
+ http://wwww.sample.com/c
8
+
9
+ http://wwww.sample.com/d
@@ -0,0 +1,6 @@
1
+ <html>
2
+ <body>
3
+ <h1>Spans sample</h1>
4
+ <p><span>spans </span> can be a mess, <span>especially</span><span> </span>when<span> </span>used for<span> </span><span>spaces</span>, or <span><b>mixed</b> with other tags</span>. <a href="http://wwww.sample.com/">Link with a <span>span</span>.</a></p>
5
+ </body>
6
+ </html>
@@ -0,0 +1,3 @@
1
+ # Spans sample
2
+
3
+ spans can be a mess, especially when used for spaces, or **mixed** with other tags. [Link with a span.](http://wwww.sample.com/)
@@ -0,0 +1,31 @@
1
+ <html>
2
+ <body>
3
+ <h1>Table sample</h1>
4
+ <table>
5
+ <tr><td colspan="2">Metadata</td></tr>
6
+ <tr><td>Title</td><td>This is the title of the page</td></tr>
7
+ <tr><td>Link</td><td><a href="https://www.sample.com"> A link</a></td></tr>
8
+ <tr>
9
+ <td>List</td>
10
+ <td><ul>
11
+ <li>Value 1</li>
12
+ <li>Value 2</li>
13
+ <li>Another value...</li>
14
+ </ul></td>
15
+ </tr>
16
+ <tr><td>Paragraphs</td><td><p>Paragraph 1 with some text</p><p>Paragraph 2 with some text too!</p></td></tr>
17
+ </table>
18
+ <table>
19
+ <tr><th colspan="2">Metadata</th></tr>
20
+ <tr><td>title</td><td>Some title</td></tr>
21
+ <tr>
22
+ <td>Tags</td>
23
+ <td>
24
+ <p>Creative</p>
25
+ <p>Experience Cloud</p>
26
+ <p>Photography</p>
27
+ </td>
28
+ </tr>
29
+ </table>
30
+ </body>
31
+ </html>
@@ -0,0 +1,5 @@
1
+ # Table sample
2
+
3
+ <table><tbody><tr><td colspan="2">Metadata</td></tr><tr><td>Title</td><td>This is the title of the page</td></tr><tr><td>Link</td><td><span></span><a href="https://www.sample.com">A link</a></td></tr><tr><td>List</td><td><ul><li>Value 1</li><li>Value 2</li><li>Another value...</li></ul></td></tr><tr><td>Paragraphs</td><td><p>Paragraph 1 with some text</p><p>Paragraph 2 with some text too!</p></td></tr></tbody></table>
4
+
5
+ <table><tbody><tr><th colspan="2">Metadata</th></tr><tr><td>title</td><td>Some title</td></tr><tr><td>Tags</td><td><p>Creative</p><p>Experience Cloud</p><p>Photography</p></td></tr></tbody></table>
@@ -0,0 +1,17 @@
1
+ <html>
2
+ <body>
3
+ <h1>Underline combo sample</h1>
4
+ <p><u>Underline 1</u></p>
5
+ <p>Some normal text with random <u>underline</u> or <span><u>span with underline</u></span> or <u><span>underline with span</u>...</p>
6
+ <p><span><strong><u>Underline 2</u></strong></span></p>
7
+ <p><strong><u>Underline 3</u></strong></p>
8
+ <ul>
9
+ <li><u>li underline 1</u></li>
10
+ <li><u>li underline 2</u> also may have text here</li>
11
+ <li><u>li underline 3</u></li>
12
+ </ul>
13
+ <p>
14
+ <u><a href="https:/www.sample.com/a">Unlined link</a></u> or <a href="https:/www.sample.com/b"><u>Linked underline</u></a> ?
15
+ </p>
16
+ </body>
17
+ </html>
@@ -0,0 +1,19 @@
1
+ # Underline combo sample
2
+
3
+ <u>Underline 1</u>
4
+
5
+ Some normal text with random <u>underline</u> or <u>span with underline</u> or <u>underline with span</u>...
6
+
7
+ **<u>Underline 2</u>**
8
+
9
+ **<u>Underline 3</u>**
10
+
11
+ - <u>li underline 1</u>
12
+
13
+ - <u>li underline 2</u>
14
+
15
+ also may have text here
16
+
17
+ - <u>li underline 3</u>
18
+
19
+ [Unlined link](https:/www.sample.com/a) or [<u>Linked underline</u>](https:/www.sample.com/b) ?
@@ -96,6 +96,7 @@ describe('Blocks#convertBlocksToTables tests', () => {
96
96
  <div class="promotion">
97
97
  <div>
98
98
  <div><a href="https://blog.adobe.com/en/promotions/doc-cloud-education.html">https://blog.adobe.com/en/promotions/doc-cloud-education.html</a></div>
99
+ <div><span>with content</span></div>
99
100
  </div>
100
101
  </div>
101
102
  </main>`,
@@ -103,7 +104,10 @@ describe('Blocks#convertBlocksToTables tests', () => {
103
104
  <div>
104
105
  <table>
105
106
  <tr><th>Promotion</th></tr>
106
- <tr><td><a href="https://blog.adobe.com/en/promotions/doc-cloud-education.html">https://blog.adobe.com/en/promotions/doc-cloud-education.html</a></td></tr>
107
+ <tr>
108
+ <td><a href="https://blog.adobe.com/en/promotions/doc-cloud-education.html">https://blog.adobe.com/en/promotions/doc-cloud-education.html</a></td>
109
+ <td><span>with content</span></td>
110
+ </tr>
107
111
  </table>
108
112
  </div>
109
113
  </main>`,
@@ -133,6 +137,6 @@ describe('Blocks#getMetadataBlock tests', () => {
133
137
  });
134
138
 
135
139
  it('getMetadataBlock lists', () => {
136
- test({ title: 'Some title', Tags: ['Creative', 'Experience Cloud', 'Photography'] }, '<table><tr><th colspan="2">Metadata</th></tr><tr><td>title</td><td>Some title</td></tr><tr><td>Tags</td><td>hlx_replaceTag(p)Creativehlx_replaceTag(/p)hlx_replaceTag(p)Experience Cloudhlx_replaceTag(/p)hlx_replaceTag(p)Photographyhlx_replaceTag(/p)</td></tr></table>');
140
+ test({ title: 'Some title', Tags: ['Creative', 'Experience Cloud', 'Photography'] }, '<table><tr><th colspan="2">Metadata</th></tr><tr><td>title</td><td>Some title</td></tr><tr><td>Tags</td><td><p>Creative</p><p>Experience Cloud</p><p>Photography</p></td></tr></table>');
137
141
  });
138
142
  });