diff --git a/markdown/dev/reference/macros/title/en.md b/markdown/dev/reference/macros/title/en.md index 6c1049221b2..acdd7abb95e 100644 --- a/markdown/dev/reference/macros/title/en.md +++ b/markdown/dev/reference/macros/title/en.md @@ -9,6 +9,7 @@ It is provided by the [annotations plugin](/reference/plugins/annotations). ```js macro('title', { + String align, Boolean append, Point at, Boolean cutlist @@ -51,6 +52,7 @@ macro('title', { | Property | Default | Type | Description | | ----------:| :-----: | ------------------- | ----------- | +| `align' | 'left' | String | Horizontal text alignment. Valid values: 'left', 'right', 'center' | | `append` | `false` | Boolean | Set this to `true` to append the `nr` to any text already set in Point `at`'s attributes, rather than overwrite it | | `at` | | [Point](/reference/api/point) | The point at which to insert the title | | `cutlist` | `true` | Boolean | Whether to include cutting instructions | diff --git a/plugins/plugin-annotations/src/title.mjs b/plugins/plugin-annotations/src/title.mjs index 317cac25734..ec6b9731d8d 100644 --- a/plugins/plugin-annotations/src/title.mjs +++ b/plugins/plugin-annotations/src/title.mjs @@ -32,19 +32,26 @@ const titleMacro = function (so, { points, scale, locale, store, part }) { scale: 1, rotation: 0, cutlist: true, + align: 'left', } so = { ...defaults, ...so } so.scale = so.scale * scale + const validAlignments = ['left', 'right', 'center'] + const alignment = validAlignments.includes(so.align) ? ' ' + so.align : ' left' + points[`_${prefix}_titleNr`] = so.at .clone() .attr('data-text', so.nr, overwrite) - .attr('data-text-class', 'text-4xl fill-note font-bold') + .attr('data-text-class', 'text-4xl fill-note font-bold' + alignment) .attr('data-text-transform', transform(so.at)) if (so.title) { - points[`_${prefix}_titleName`] = nextPoint(so.title, 'text-lg fill-current font-bold') + points[`_${prefix}_titleName`] = nextPoint( + so.title, + 'text-lg fill-current font-bold' + alignment + ) shift += 8 } @@ -59,7 +66,7 @@ const titleMacro = function (so, { points, scale, locale, store, part }) { // each set of instructions partCutlist.materials[material].forEach(({ cut, identical, bias, ignoreOnFold }, c) => { // make a new point for this set of instructions - const cutPoint = nextPoint('plugin:cut', 'text-md fill-current').addText(cut) + const cutPoint = nextPoint('plugin:cut', 'text-md fill-current' + alignment).addText(cut) // if they're not identical, add that to the point's text if (!identical && cut > 1) cutPoint.addText('plugin:mirrored') @@ -83,11 +90,14 @@ const titleMacro = function (so, { points, scale, locale, store, part }) { let name = store.data?.name || 'No Name' name = name.replace('@freesewing/', '') name += ' v' + (store.data?.version || 'No Version') - points[`_${prefix}_titlePattern`] = nextPoint(name, 'fill-note') + points[`_${prefix}_titlePattern`] = nextPoint(name, 'fill-note' + alignment) if (store.data.for) { shift += 8 - points[`_${prefix}_titleFor`] = nextPoint(`( ${store.data.for} )`, 'fill-current font-bold') + points[`_${prefix}_titleFor`] = nextPoint( + `( ${store.data.for} )`, + 'fill-current font-bold' + alignment + ) } shift += 6 const now = new Date() @@ -101,7 +111,10 @@ const titleMacro = function (so, { points, scale, locale, store, part }) { month: 'short', day: 'numeric', }) - points[`_${prefix}_exportDate`] = nextPoint(`${exportDate}@ ${hours}:${mins}`, 'text-sm') + points[`_${prefix}_exportDate`] = nextPoint( + `${exportDate}@ ${hours}:${mins}`, + 'text-sm' + alignment + ) } // Export macros diff --git a/plugins/plugin-annotations/tests/title.test.mjs b/plugins/plugin-annotations/tests/title.test.mjs index ab271ef823a..2587f589333 100644 --- a/plugins/plugin-annotations/tests/title.test.mjs +++ b/plugins/plugin-annotations/tests/title.test.mjs @@ -30,19 +30,21 @@ describe('Title Plugin Tests', () => { expect(p.x).to.equal(-12) expect(p.y).to.equal(-34) expect(p.attributes.get('data-text')).to.equal('3') - expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold') + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-34') p = pattern.parts[0].test.points.__titleName expect(p.attributes.get('data-text')).to.equal('unitTest') - expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold') + expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-26') p = pattern.parts[0].test.points.__titlePattern expect(p.attributes.get('data-text')).to.equal('testPattern v99') - expect(p.attributes.get('data-text-class')).to.equal('fill-note') + expect(p.attributes.get('data-text-class')).to.equal('fill-note left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-18') + p = pattern.parts[0].test.points.__exportDate + expect(p.attributes.get('data-text')).to.match(/^.+, .+ \d{1,2}, \d{4}@ \d\d:\d\d$/) }) it('Should run the title macro with append flag', () => { @@ -71,7 +73,7 @@ describe('Title Plugin Tests', () => { expect(p.x).to.equal(-12) expect(p.y).to.equal(-34) expect(p.attributes.get('data-text')).to.equal('# 3') - expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold') + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-34') }) @@ -102,18 +104,105 @@ describe('Title Plugin Tests', () => { expect(p.x).to.equal(-12) expect(p.y).to.equal(-34) expect(p.attributes.get('data-text')).to.equal('3') - expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold') + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-34') p = pattern.parts[0].test.points._foo_titleName expect(p.attributes.get('data-text')).to.equal('unitTest') - expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold') + expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-26') p = pattern.parts[0].test.points._foo_titlePattern expect(p.attributes.get('data-text')).to.equal('testPattern v99') - expect(p.attributes.get('data-text-class')).to.equal('fill-note') + expect(p.attributes.get('data-text-class')).to.equal('fill-note left') expect(p.attributes.get('data-text-x')).to.equal('-12') expect(p.attributes.get('data-text-y')).to.equal('-18') }) + + it('Should run the title macro with valid align prefixes', () => { + const part = { + name: 'test', + draft: ({ points, Point, macro, part }) => { + points.anchor = new Point(-12, -34).attr('data-text', '#') + macro('title', { + at: points.anchor, + nr: 3, + title: 'unitTest', + align: 'left', + prefix: 'left', + }) + macro('title', { + at: points.anchor, + nr: 3, + title: 'unitTest', + align: 'right', + prefix: 'right', + }) + macro('title', { + at: points.anchor, + nr: 3, + title: 'unitTest', + align: 'center', + prefix: 'center', + }) + + return part + }, + plugins: [annotationsPlugin], + } + const Pattern = new Design({ + data: { name: 'testPattern', version: 99 }, + parts: [part], + }) + const pattern = new Pattern() + pattern.draft().render() + let p = pattern.parts[0].test.points._left_titleNr + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold left') + p = pattern.parts[0].test.points._left_titleName + expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold left') + p = pattern.parts[0].test.points._left_titlePattern + expect(p.attributes.get('data-text-class')).to.equal('fill-note left') + p = pattern.parts[0].test.points._center_titleNr + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold center') + p = pattern.parts[0].test.points._center_titleName + expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold center') + p = pattern.parts[0].test.points._center_titlePattern + expect(p.attributes.get('data-text-class')).to.equal('fill-note center') + p = pattern.parts[0].test.points._right_titleNr + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold right') + p = pattern.parts[0].test.points._right_titleName + expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold right') + p = pattern.parts[0].test.points._right_titlePattern + expect(p.attributes.get('data-text-class')).to.equal('fill-note right') + }) + + it('Should run the title macro with an invalid align prefix', () => { + const part = { + name: 'test', + draft: ({ points, Point, macro, part }) => { + points.anchor = new Point(-12, -34).attr('data-text', '#') + macro('title', { + at: points.anchor, + nr: 3, + title: 'unitTest', + align: 'invalidprefix', + }) + + return part + }, + plugins: [annotationsPlugin], + } + const Pattern = new Design({ + data: { name: 'testPattern', version: 99 }, + parts: [part], + }) + const pattern = new Pattern() + pattern.draft().render() + let p = pattern.parts[0].test.points.__titleNr + expect(p.attributes.get('data-text-class')).to.equal('text-4xl fill-note font-bold left') + p = pattern.parts[0].test.points.__titleName + expect(p.attributes.get('data-text-class')).to.equal('text-lg fill-current font-bold left') + p = pattern.parts[0].test.points.__titlePattern + expect(p.attributes.get('data-text-class')).to.equal('fill-note left') + }) })