Skip to content

Commit

Permalink
Merge pull request #26 from nolastan/export
Browse files Browse the repository at this point in the history
Add export functionality + Update for Sketch 41
  • Loading branch information
nolastan authored Nov 8, 2016
2 parents f4739e6 + 3e800b5 commit a096e78
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 23 deletions.
8 changes: 5 additions & 3 deletions Contents/Sketch/colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ var applyColors = function (newColors, assetColors) {
var appController = app.delegate();
var colors = [];
for(var i=0; i<newColors.length; i++) {
var color = MSColor.colorWithSVGString("#" + newColors[i].Rgb);
color.alpha = newColors[i].Opacity;
var color = MSImmutableColor.colorWithSVGString("#" + newColors[i].Rgb);
if(newColors[i].Opacity) {
color.alpha = newColors[i].Opacity;
}
colors.push(color);
}
[assetColors addColors:colors];

// The following line is throwing the error: is not a function
// appController.globalAssets().objectDidChange();

}
84 changes: 84 additions & 0 deletions Contents/Sketch/export.cocoascript
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
var onRun = function(context) {
var output = 'Style, Typeface, Color, Opacity, Size, Alignment, Line, Character'

var alignmentEnum = Object.freeze([
'left','right','center','justified'
]);

var doc = context.document;
var sharedStyles = doc.documentData().layerTextStyles();
var styleObjects = sharedStyles.objects();
var textLayer = [[MSTextLayer alloc] initWithFrame:nil];


for (var i=0; i<styleObjects.length; i++) {
var color, opacity, alignment = "";

textLayer.setStyle(styleObjects[i].style());

var name = styleObjects[i].name();

var attributes = styleObjects[i].style().textStyle().attributes()

var paragraphStyle = attributes.NSParagraphStyle;

if(paragraphStyle) {
alignment = alignmentEnum[paragraphStyle.alignment()] || "";
}

var line = textLayer.lineHeight() || '';
var character = textLayer.characterSpacing() || '';

var font = attributes.NSFont.fontName();

if(attributes.NSColor) {
color = attributes.NSColor.hexValue();
opacity = attributes.NSColor.alphaComponent();
}
var size = attributes.NSFont.pointSize();
output += '\n' + name +', '+ font +', '+ color +', '+ opacity +', '+ size +', '+ alignment +', '+ line +', '+ character;
}

var writeTextToFile = function(text, filePath) {
var t = [NSString stringWithFormat:@"%@", text],
f = [NSString stringWithFormat:@"%@", filePath];
return [t writeToFile:f atomically:true encoding:NSUTF8StringEncoding error:nil];
}

var openInFinder = function(path) {
var finderTask = [[NSTask alloc] init],
openFinderArgs = [NSArray arrayWithObjects:"-R", path, nil];

[finderTask setLaunchPath:"/usr/bin/open"];
[finderTask setArguments:openFinderArgs];
[finderTask launch];
}

var createTempFolderNamed = function(name) {
var tempPath = getTempFolderPath(name);
createFolderAtPath(tempPath);
return tempPath;
}
var getTempFolderPath = function(withName) {
var fileManager = [NSFileManager defaultManager],
cachesURL = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject],
withName = (typeof withName !== 'undefined') ? withName : (Date.now() / 1000),
folderName = [NSString stringWithFormat:"%@", withName];
return [[cachesURL URLByAppendingPathComponent:folderName] path];
}

var createFolderAtPath = function(pathString) {
var fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:pathString]) return true;
return [fileManager createDirectoryAtPath:pathString withIntermediateDirectories:true attributes:nil error:nil];
}

var folder = createTempFolderNamed('sync');
var file = folder + '/typography.csv';

var shortcutPath = folder + '/README.url';
var shortcutFile = '[InternetShortcut]\nURL=https://github.com/nolastan/sync.sketchplugin#exporting-styles'
writeTextToFile(output, file);
writeTextToFile(shortcutFile, shortcutPath);
openInFinder(file);
}
19 changes: 13 additions & 6 deletions Contents/Sketch/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@
{
"script" : "script.cocoascript",
"handler" : "onRun",
"shortcut" : "option s",
"name" : "Sync",
"identifier" : "sync"
"shortcut" : "command option s",
"name" : "⬇️ Import from URL",
"identifier" : "import"
},
{
"script" : "export.cocoascript",
"handler" : "onRun",
"name" : "⬆️ Export typography as CSV",
"identifier" : "export"
},
],
"menu": {
"isRoot": true,
"isRoot": false,
"items": [
"sync",
"export",
"import"
],
},
"identifier" : "com.github.nolastan.sync",
"version" : "1.1",
"description" : "Sync styles and symbols",
"authorEmail" : "[email protected]",
"name" : "Sync"
"name" : "🎨 Sync"
}
2 changes: 1 addition & 1 deletion Contents/Sketch/script.cocoascript
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ var onRun = function(context) {

function showOptions() {
var alert = [NSAlert alertWithMessageText: "Sync text styles"
defaultButton:"Sync"
defaultButton:"Import"
alternateButton:"Cancel"
otherButton:nil
informativeTextWithFormat:"Enter the URL where your styles live."];
Expand Down
12 changes: 6 additions & 6 deletions Contents/Sketch/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,26 @@ var applyStyles = function (newStyles, sharedStyles) {

if(style.Background) {
var fill = sharedStyle.addStylePartOfType(alignmentHash['fill']);
fill.color = MSColor.colorWithSVGString("#" + style.Background);
fill.color = MSImmutableColor.colorWithSVGString("#" + style.Background);
}

if(style.Borderthickness > 0 && style.Bordercolor) {
var borders = sharedStyle.addStylePartOfType(alignmentHash['border']);
borders.thickness = style.Borderthickness;
borders.color = MSColor.colorWithSVGString("#" + style.Bordercolor);
borders.color = MSImmutableColor.colorWithSVGString("#" + style.Bordercolor);
}

if(style.Shadow) {
var shadow = sharedStyle.addStylePartOfType(alignmentHash['shadow']);
var shadowColor = MSColor.colorWithSVGString("#" + style.Shadowcolor);
shadow.color = shadowColor.colorWithAlpha(style.Shadowopacity);
var shadowColor = MSImmutableColor.colorWithSVGString("#" + style.Shadowcolor);
shadow.color = shadowColor.colorWithAlphaComponent(style.Shadowopacity);
setShadowAttribute(shadow, style.Shadow);
}

if(style.Innershadow) {
var innerShadow = sharedStyle.addStylePartOfType(alignmentHash['innerShadow']);
var innerShadowColor = MSColor.colorWithSVGString("#" + style.Innershadowcolor);
innerShadow.color = innerShadowColor.colorWithAlpha(style.Innershadowopacity);
var innerShadowColor = MSImmutableColor.colorWithSVGString("#" + style.Innershadowcolor);
innerShadow.color = innerShadowColor.colorWithAlphaComponent(style.Innershadowopacity);
setShadowAttribute(innerShadow, style.Innershadow);
}

Expand Down
4 changes: 3 additions & 1 deletion Contents/Sketch/typography.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,19 @@ var applyTypography = function (newStyles, sharedStyles) {
if(style.Style == "") { return; }

var textLayer = [[MSTextLayer alloc] initWithFrame:nil];
var paragraphStyle = textLayer.style().textStyle().attributes().NSParagraphStyle;

if("Size" in style) { textLayer.setFontSize(style.Size); }
if("Line" in style) { textLayer.setLineHeight(style.Line); }
if("Paragraph" in style) { paragraphStyle.setParagraphSpacing(style.Paragraph); }
if("Character" in style) {
var characterSpacing = Number(style.Character);
textLayer.setCharacterSpacing(characterSpacing);
}
if("Alignment" in style) { textLayer.setTextAlignment(alignmentEnum[style.Alignment]); }
if("Typeface" in style) { textLayer.setFontPostscriptName(style.Typeface); }
if("Color" in style) {
var color = MSColor.colorWithSVGString("#" + style.Color);
var color = MSImmutableColor.colorWithSVGString("#" + style.Color);
color.alpha = style.Opacity;
textLayer.setTextColor(color);
}
Expand Down
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
# Sync Sketch Plugin
![](https://i.imgur.com/dUeIJjI.gif)

Save your text styles, layer styles, and color palette in a Google Sheet to keep your design team in sync. Every time you run this plugin your styles and colors will be replaced with those you specify in a spreadsheet. This should make it easier to share typography styles across teams!
Share styles with your team using Google Sheets.
* Import and update styles from a shared Google Sheet.
* Export styles as CSV files, which can be uploaded to Google Sheets and shared with your team.
* Use formulas in Google Sheets to set relative font sizes and line heights.

# Installation
Install from [Sketch Toolbox](http://sketchtoolbox.com/) (recommended) or [download the zip](https://github.com/nolastan/sync.sketchplugin/releases/download/1.1/sync.sketchplugin.zip), unzip, and open `sync.sketchplugin`.

# Getting Started
# Setting up Google Sheets
You'll need a published sheet to use Sync.

1. Create a Google Sheet from [this template](https://drive.google.com/previewtemplate?id=17q6GOMM1X6kkvgeL3LeGkRr4C2vOhpM_JiQUWxbBtew&mode=public) (click the "Use this template" button).

2. Select *File > Publish to web…* and then click the *Publish* button.

3. Copy the link to your sheet. (See below if you are using Google Apps at work)
# Exporting styles
Export styles from Sketch to your sheet. Alternatively, you can skip this step and define your initial styles in the Google Sheets interface.

4. Run the Sync command from the plugin menu and paste your URL into the prompt.
1. With the Sketch document containing your styles open, run the *Export* command from the Sync plugin menu. A finder window should open revealing `typography.csv`.
2. Open your Google Sheet, select *File > Import…* and then *Upload*.
3. Drag `typography.csv` into the upload screen and select *Replace current sheet* then click *Import*.

# Importing styles
Import styles from your sheet to Sketch.

1. Copy the URL to your Google Sheet. (See below if you are using Google Apps at work)

2. Run the `Import` command from the Sync plugin menu and paste your URL into the prompt.

Your text styles, layer styles, and color palette should now be synced with your spreadsheet. Run the plugin again any time to update. Share your published sheet URL with your team to stay in sync.

## Using Google Apps at work?
Some companies prevent employees from publishing sheets. If the *Published content & settings* drill-down in the *Publish to the web* modal says that people at your company must log in to view, then Sync will not be able to access your sheet. Don't worry – you can still use Sync for typography. Just visit [Sheetsu](http://sheetsu.com/) to generate an API for your new sheet. Use your new Sheetsu URL and continue to step 4.

## Font Weight
Font variants—such as bold, italic, or narrow—are actually separate font files on your computer. You should specify these exactly as named in `~/Library/Fonts/` folder on your Mac, *excluding* the file extension (e.g. `ttf`). The [Google Sheet template](https://drive.google.com/previewtemplate?id=17q6GOMM1X6kkvgeL3LeGkRr4C2vOhpM_JiQUWxbBtew&mode=public) provides an example of this.
Font variants—such as bold, italic, or narrow—are actually separate font files on your computer. You should specify these exactly as named in `~/Library/Fonts/` folder on your Mac, *excluding* the file extension (e.g. `ttf`). The [Google Sheet template](https://drive.google.com/previewtemplate?id=17q6GOMM1X6kkvgeL3LeGkRr4C2vOhpM_JiQUWxbBtew&mode=public) provides an example of this. If you get stuck, consider defining your styles in Sketch and using the export feature.

## Need help?
[View the screencast](https://dl.dropboxusercontent.com/s/f4ubqenqz8n5wne/68D4E91B-173A-4AA0-964C-AA7F9EA77AC8-5233-000032842DD067F4.gif?dl=0), [create an issue](https://github.com/nolastan/sync.sketchplugin/issues/new) or [tweet @stan](https://twitter.com/stan).
Expand Down Expand Up @@ -51,4 +65,4 @@ As an alternative to Google Sheets, you can create a custom JSON api with the fo
]
}
```
Run the Sync command from the plugin menu and paste your API endpoint URL into the prompt.
Run the *Import* command from the Sync plugin menu and paste your API endpoint URL into the prompt.

0 comments on commit a096e78

Please sign in to comment.