Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to single layer text styling #3

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 77 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,57 +11,96 @@ Learn more about writing `.jsx` files for After Effects here: https://motiondeve

## Overview

This library provides a few functions for turning text strings into an array of style objects. This can then be used in Ae to style an position a bunch of text layers.
This library takes in a string of markdown, and renders it using the appropriate `set` text style expressions.

```ts
type StyleResult = { content: string; style: string; line: number }[];

/** Parse a markdown-ish string*/
type parseStyles = (
textString: string,
parsers?: Array<{ matcher: RegExp; stylename: string }>
) => StyleResult;

/** Style the given word indexes */
type styleByIndex = (textString: string, {
boldIndexes: number[],
italicsIndexes: number[]
}) => StyleResult;

/** Style the given words */
type styleBySearch = (textString: string, {
boldString?: string,
italicsString?: string,
}) => StyleResult;
const { parse } = footage('style-parser.jsx').sourceData.get();

parse(value);
```

## Example
For example, by default the text wrapped in `*` will be set to a bold font, and text wrapped in `_` will be italicized.

Expression:
> For the full set of default parsers, see [/src/parsers.ts](src/parsers.ts).

```js
const { parseStyles } = footage('style-parser.jsx').sourceData;
const textString = `This will
*be bold* and
this will _be italics_`;
So the following source text:

const parsed = parseStyles(textString);
```txt
This is *a string* of _markdown_
```

Results in:
Will result in the expression:

```js
[
{ content: 'This will', style: 'regular', line: 0 },
text.sourceText.style
.setFont('Verdana-Bold', 8, 16)
.setFont('Verdana-Italic', 20, 8)
.setText('This is a string of markdown');
```

## API

### Parse function

```ts
parse(markdown: string, {
parsers?: Parser[],
fontMap?: FontMap,
textStyle?: TextStyle
}): TextStyle;
```

### `parsers`

```ts
type Parser = {
name: string;
matcher?: RegExp;
styles: StyleDefinition;
};
```

`StyleDefintion` is an object, where each property is a settable [`TextStyle`](https://docs.motiondeveloper.com/classes/textstyle) attribute with an equivalent value type. For example:

```ts
parse(value, {
parsers: [
{ name: 'bold', styles: { fontSize: 40, fillColor: [1, 0, 0, 1] } },
{ name: 'italic', styles: { fontName: 'Arial-Italic ' } },
{ name: 'wide', matcher: /~(.*?)~/g, styles: { tracking: 130 } },
],
});
```

### `fontMap`

```ts
type FontMap = {
regular?: string;
bold?: string;
italic?: string;
};
```

To avoid having to manually set the `fontName` for multiple styles (such as bold and all the headings), you can pass in a `fontMap` object that will be used to set the default fonts for each parser. For example:

{ content: 'be bold', style: 'bold', line: 1 },
{ content: 'and', style: 'regular', line: 1 },
```ts
parse(value, { fontMap: { bold: 'Menlo-Bold' } });
```

Will set the `fontName` for all the bold parsers to 'Menlo-Bold'.

### `textStyle`

{ content: 'this will', style: 'regular', line: 2 },
{ content: 'be italics', style: 'italics', line: 2 },
];
```ts
// typeof thisLayer.text.sourceText.style
type textStyle = TextStyle;
```

## Limitations
By default, the `parse` function will apply the default text style from the current layer. You can pass in a custom text style if you want to modify the default styles, or inherit them from another layer. For example:

Currently you need to style whole words in each method, otherwise you'll get unnecessary spaces inserted.
```ts
// Modify the current style
const textStyle = thisLayer.text.sourceText.style.setLeading(20);
parse(value, { textStyle });
```
Loading