Skip to content

Commit

Permalink
Paragraph Spacing & Indent (#84)
Browse files Browse the repository at this point in the history
* paragraph space and paragraph indent

fixes

fixes

fine tuning

fine tuning

fine tuning

fine tuning

fixes

* wip

* fix

* paragraph space and paragraph indent

* changeset

* Delete .changeset/new-walls-sort.md

---------

Co-authored-by: Jordi Sala Morales <jordism91@gmail.com>
  • Loading branch information
Cenadros and jordisala1991 authored May 3, 2024
1 parent 58f7b0a commit 4ded73e
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-islands-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"penpot-exporter": minor
---

Paragraph spacing and indent support
48 changes: 3 additions & 45 deletions plugin-src/transformers/partials/transformText.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { transformFills } from '@plugin/transformers/partials';
import { translateFills } from '@plugin/translators';
import {
translateFontId,
translateFontStyle,
transformTextStyle,
translateGrowType,
translateHorizontalAlign,
translateLetterSpacing,
translateLineHeight,
translateTextDecoration,
translateTextTransform,
translateStyleTextSegments,
translateVerticalAlign
} from '@plugin/translators/text';

import { TextStyle } from '@ui/lib/types/text/textContent';
import { TextShape } from '@ui/lib/types/text/textShape';

export const transformText = (node: TextNode): Partial<TextShape> => {
Expand All @@ -37,11 +30,7 @@ export const transformText = (node: TextNode): Partial<TextShape> => {
children: [
{
type: 'paragraph',
children: styledTextSegments.map(segment => ({
fills: translateFills(segment.fills, node.width, node.height),
text: segment.characters,
...transformTextStyle(node, segment)
})),
children: translateStyleTextSegments(node, styledTextSegments),
...(styledTextSegments.length ? transformTextStyle(node, styledTextSegments[0]) : {}),
...transformFills(node)
}
Expand All @@ -52,34 +41,3 @@ export const transformText = (node: TextNode): Partial<TextShape> => {
growType: translateGrowType(node)
};
};

const transformTextStyle = (
node: TextNode,
segment: Pick<
StyledTextSegment,
| 'characters'
| 'start'
| 'end'
| 'fontName'
| 'fontSize'
| 'fontWeight'
| 'lineHeight'
| 'letterSpacing'
| 'textCase'
| 'textDecoration'
| 'fills'
>
): Partial<TextStyle> => {
return {
...translateFontId(segment.fontName, segment.fontWeight),
fontFamily: segment.fontName.family,
fontSize: segment.fontSize.toString(),
fontStyle: translateFontStyle(segment.fontName.style),
fontWeight: segment.fontWeight.toString(),
textAlign: translateHorizontalAlign(node.textAlignHorizontal),
textDecoration: translateTextDecoration(segment),
textTransform: translateTextTransform(segment),
letterSpacing: translateLetterSpacing(segment),
lineHeight: translateLineHeight(segment)
};
};
2 changes: 2 additions & 0 deletions plugin-src/translators/text/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export * from './translateGrowType';
export * from './translateHorizontalAlign';
export * from './translateLetterSpacing';
export * from './translateLineHeight';
export * from './translateParagraphProperties';
export * from './translateStyleTextSegments';
export * from './translateTextDecoration';
export * from './translateTextTransform';
export * from './translateVerticalAlign';
75 changes: 75 additions & 0 deletions plugin-src/translators/text/translateParagraphProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { TextNode as PenpotTextNode } from '@ui/lib/types/text/textContent';

export const translateParagraphProperties = (
node: TextNode,
segments: PenpotTextNode[]
): PenpotTextNode[] => {
if (node.paragraphSpacing === 0 && node.paragraphIndent === 0) return segments;

const splitSegments: PenpotTextNode[] = [segmentIndent(node.paragraphIndent)];

segments.forEach(segment => {
splitSegments.push(...splitTextNodeByEOL(segment));
});

return addParagraphProperties(splitSegments, node.paragraphIndent, node.paragraphSpacing);
};

const splitTextNodeByEOL = (node: PenpotTextNode): PenpotTextNode[] => {
const split = node.text.split(/(\n)/).filter(text => text !== '');

return split.map(text => ({
...node,
text: text
}));
};

const addParagraphProperties = (
nodes: PenpotTextNode[],
indent: number,
paragraphSpacing: number
): PenpotTextNode[] => {
const indentedTextNodes: PenpotTextNode[] = [];

nodes.forEach(node => {
indentedTextNodes.push(node);

if (node.text !== '\n') return;

if (paragraphSpacing !== 0) {
indentedTextNodes.push(segmentParagraphSpacing(paragraphSpacing));
}

if (indent !== 0) {
indentedTextNodes.push(segmentIndent(indent));
}
});

return indentedTextNodes;
};

const segmentIndent = (indent: number): PenpotTextNode => {
return {
text: ' '.repeat(indent),
fontId: 'sourcesanspro',
fontVariantId: 'regular',
fontSize: '5',
fontStyle: 'normal',
fontWeight: '400',
lineHeight: 1,
letterSpacing: 0
};
};

const segmentParagraphSpacing = (paragraphSpacing: number): PenpotTextNode => {
return {
text: '\n',
fontId: 'sourcesanspro',
fontVariantId: 'regular',
fontSize: paragraphSpacing.toString(),
fontStyle: 'normal',
fontWeight: '400',
lineHeight: 1,
letterSpacing: 0
};
};
65 changes: 65 additions & 0 deletions plugin-src/translators/text/translateStyleTextSegments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { translateFills } from '@plugin/translators';
import {
translateFontId,
translateFontStyle,
translateHorizontalAlign,
translateLetterSpacing,
translateLineHeight,
translateParagraphProperties,
translateTextDecoration,
translateTextTransform
} from '@plugin/translators/text';

import { TextNode as PenpotTextNode, TextStyle } from '@ui/lib/types/text/textContent';

type StyleTextSegment = Pick<
StyledTextSegment,
| 'characters'
| 'start'
| 'end'
| 'fontName'
| 'fontSize'
| 'fontWeight'
| 'lineHeight'
| 'letterSpacing'
| 'textCase'
| 'textDecoration'
| 'fills'
>;

export const translateStyleTextSegments = (
node: TextNode,
segments: StyleTextSegment[]
): PenpotTextNode[] => {
const textNodes = segments.map(segment => {
return translateStyleTextSegment(node, segment);
});

return translateParagraphProperties(node, textNodes);
};

export const transformTextStyle = (
node: TextNode,
segment: StyleTextSegment
): Partial<TextStyle> => {
return {
...translateFontId(segment.fontName, segment.fontWeight),
fontFamily: segment.fontName.family,
fontSize: segment.fontSize.toString(),
fontStyle: translateFontStyle(segment.fontName.style),
fontWeight: segment.fontWeight.toString(),
textAlign: translateHorizontalAlign(node.textAlignHorizontal),
textDecoration: translateTextDecoration(segment),
textTransform: translateTextTransform(segment),
letterSpacing: translateLetterSpacing(segment),
lineHeight: translateLineHeight(segment)
};
};

const translateStyleTextSegment = (node: TextNode, segment: StyleTextSegment): PenpotTextNode => {
return {
fills: translateFills(segment.fills, node.width, node.height),
text: segment.characters,
...transformTextStyle(node, segment)
};
};

0 comments on commit 4ded73e

Please sign in to comment.