Changed readme template

Updated documentation
This commit is contained in:
Unknown
2018-07-05 16:07:10 -04:00
parent a0d6686cbc
commit 4294932b1f
11 changed files with 264 additions and 81 deletions

40
.doc.template Normal file
View File

@@ -0,0 +1,40 @@
{{with .PDoc}}{{if $.IsMain}}> {{ base .ImportPath }}
{{comment_md .Doc}}{{else}}# {{ .Name }}
[![GoDoc](https://godoc.org/{{ .ImportPath }}?status.svg)](https://godoc.org/github.com/sbrow/{{ .Name }}) [![Build Status](https://travis-ci.org/sbrow/{{ .Name }}.svg?branch=master)](https://travis-ci.org/sbrow/{{ .Name }}) [![Coverage Status](https://coveralls.io/repos/github/sbrow/{{ .Name }}/badge.svg?branch=master)](https://coveralls.io/github/sbrow/{{ .Name }}?branch=master) [![Go Report Card](https://goreportcard.com/badge/{{ .ImportPath }})](https://goreportcard.com/report/{{ .ImportPath }})
`import "{{.ImportPath}}"`
* [Overview](#pkg-overview)
* [Installation](pkg-installation){{if $.Dirs}}
* [Subdirectories](#pkg-subdirectories){{end}}{{ with .Notes}}{{ range $marker, $content := .}}
* [{{$marker}}](#pkg-note-{{$marker}}){{end}}
{{- end}}
* [Documentation](#pkg-doc)
## <a name="pkg-overview">Overview</a>
{{comment_md .Doc}}
{{example_html $ ""}}
## <a name="pkg-installation">Installation</a>
```sh
$ go get -u {{ .ImportPath }}
```
<!---
{{if $.Examples}}
#### <a name="pkg-examples">Examples</a>{{- range $.Examples}}
* [{{example_name .Name}}](example_{{.Name}}_test.go){{- end}}{{- end}}
{{end}}
--->
{{ with .Notes}}
{{ range $marker, $content := .}}
## <a name="pkg-note-{{$marker}}">{{$marker}}</a>
{{ range $key, $value := .}}
`{{ $value.UID }}:` {{ $value.Body }}{{end}}{{end}}{{end}}
## <a name="pkg-doc">Documentation</a>
For full Documentation please visit https://godoc.org/{{.ImportPath}}
- - -
{{end}}
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)

View File

@@ -1,9 +0,0 @@
# {{ .Name }}
[![GoDoc](https://godoc.org/github.com/sbrow/{{ .Name }}?status.svg)](https://godoc.org/github.com/sbrow/{{ .Name }}) [![Build Status](https://travis-ci.org/sbrow/{{ .Name }}.svg?branch=master)](https://travis-ci.org/sbrow/{{ .Name }}) [![Coverage Status](https://coveralls.io/repos/github/sbrow/{{ .Name }}/badge.svg?branch=master)](https://coveralls.io/github/sbrow/{{ .Name }}?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/sbrow/{{ .Name }})](https://goreportcard.com/report/github.com/sbrow/{{ .Name }})
{{ .EmitSynopsis }}
## Installation
```bash
$ go get -u {{ .ImportPath }}
```

View File

@@ -1,12 +1,54 @@
# ps # ps
[![GoDoc](https://godoc.org/github.com/sbrow/ps?status.svg)](https://godoc.org/github.com/sbrow/ps) [![Build Status](https://travis-ci.org/sbrow/ps.svg?branch=master)](https://travis-ci.org/sbrow/ps) [![Coverage Status](https://coveralls.io/repos/github/sbrow/ps/badge.svg?branch=master)](https://coveralls.io/github/sbrow/ps?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/sbrow/ps)](https://goreportcard.com/report/github.com/sbrow/ps) [![GoDoc](https://godoc.org/github.com/sbrow/ps?status.svg)](https://godoc.org/github.com/sbrow/ps) [![Build Status](https://travis-ci.org/sbrow/ps.svg?branch=master)](https://travis-ci.org/sbrow/ps) [![Coverage Status](https://coveralls.io/repos/github/sbrow/ps/badge.svg?branch=master)](https://coveralls.io/github/sbrow/ps?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/sbrow/ps)](https://goreportcard.com/report/github.com/sbrow/ps)
Package ps is a rudimentary API between Adobe Photoshop CS5 and Golang. The `import "github.com/sbrow/ps"`
interaction between the two is implemented using Javascript/VBScript.
* [Overview](#pkg-overview)
* [Installation](pkg-installation)
* [Subdirectories](#pkg-subdirectories)
* [TODO](#pkg-note-TODO)
* [Documentation](#pkg-doc)
## <a name="pkg-overview">Overview</a>
Package ps is a rudimentary API between Adobe Photoshop CS5 and Golang.
The interaction between the two is implemented using Javascript/VBScript.
Use it to control Photoshop, edit documents, and perform batch operations.
Currently only supports Photoshop CS5 Windows x86_64. Currently only supports Photoshop CS5 Windows x86_64.
## Installation
```bash
## <a name="pkg-installation">Installation</a>
```sh
$ go get -u github.com/sbrow/ps $ go get -u github.com/sbrow/ps
``` ```
<!---
#### <a name="pkg-examples">Examples</a>
* [JSLayer](example_JSLayer_test.go)
--->
## <a name="pkg-note-TODO">TODO</a>
`sbrow:` (2) Make TextLayer a subclass of ArtLayer.
`sbrow:` Reduce cylcomatic complexity
`sbrow:` Does funky things when passed invalid layername.
`sbrow:` Move to Document
`sbrow:` get rid of the semicolon.
## <a name="pkg-doc">Documentation</a>
For full Documentation please visit https://godoc.org/github.com/sbrow/ps
- - -
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)

View File

@@ -11,7 +11,7 @@ import (
// ArtLayer reflects some values from an Art Layer in a Photoshop document. // ArtLayer reflects some values from an Art Layer in a Photoshop document.
// //
// TODO: (2) Make TextLayer a subclass of ArtLayer. // TODO(sbrow): (2) Make TextLayer a subclass of ArtLayer.
type ArtLayer struct { type ArtLayer struct {
name string // The layer's name. name string // The layer's name.
bounds [2][2]int // The corners of the layer's bounding box. bounds [2][2]int // The corners of the layer's bounding box.
@@ -200,9 +200,9 @@ func (a *ArtLayer) Path() string {
} }
// SetVisible makes the layer visible. // SetVisible makes the layer visible.
func (a *ArtLayer) SetVisible(b bool) { func (a *ArtLayer) SetVisible(b bool) error {
if a.visible == b { if a.visible == b {
return return nil
} }
a.visible = b a.visible = b
switch b { switch b {
@@ -214,8 +214,10 @@ func (a *ArtLayer) SetVisible(b bool) {
js := fmt.Sprintf("%s.visible=%v;", js := fmt.Sprintf("%s.visible=%v;",
strings.TrimRight(JSLayer(a.Path()), ";"), b) strings.TrimRight(JSLayer(a.Path()), ";"), b)
if byt, err := DoJS("compilejs.jsx", js); err != nil { if byt, err := DoJS("compilejs.jsx", js); err != nil {
log.Println(string(byt), err) log.Println(string(byt))
return err
} }
return nil
} }
// Visible returns whether or not the layer is currently hidden. // Visible returns whether or not the layer is currently hidden.

View File

@@ -71,6 +71,23 @@ func (d *Document) Height() int {
return d.height return d.height
} }
// ArtLayer returns the first top level ArtLayer matching
// the given name.
func (d *Document) ArtLayer(name string) *ArtLayer {
for _, lyr := range d.artLayers {
if lyr.name == name {
if Mode == 0 && !lyr.current {
err := lyr.Refresh()
if err != nil {
log.Panic(err)
}
}
return lyr
}
}
return nil
}
// ArtLayers returns this document's ArtLayers, if any. // ArtLayers returns this document's ArtLayers, if any.
func (d *Document) ArtLayers() []*ArtLayer { func (d *Document) ArtLayers() []*ArtLayer {
return d.artLayers return d.artLayers
@@ -99,7 +116,7 @@ func (d *Document) LayerSet(name string) *LayerSet {
// ActiveDocument returns document currently focused in Photoshop. // ActiveDocument returns document currently focused in Photoshop.
// //
// TODO: Reduce cylcomatic complexity // TODO(sbrow): Reduce cylcomatic complexity
func ActiveDocument() (*Document, error) { func ActiveDocument() (*Document, error) {
log.Println("Loading ActiveDoucment") log.Println("Loading ActiveDoucment")
d := &Document{} d := &Document{}
@@ -111,26 +128,32 @@ func ActiveDocument() (*Document, error) {
d.name = strings.TrimRight(string(byt), "\r\n") d.name = strings.TrimRight(string(byt), "\r\n")
if Mode != Safe { if Mode != Safe {
err = d.Restore() err = d.Restore()
return d, err switch {
case os.IsNotExist(err):
log.Println("Previous version not found.")
case err == nil:
return d, err
default:
return nil, err
}
} }
log.Println("Loading manually (This could take awhile)") log.Println("Loading manually (This could take awhile)")
byt, err = DoJS("getActiveDoc.jsx") byt, err = DoJS("getActiveDoc.jsx")
if err != nil { if err != nil {
log.Panic(err) return nil, err
} }
err = json.Unmarshal(byt, &d) if err = json.Unmarshal(byt, &d); err != nil {
if err != nil {
d.Dump() d.Dump()
log.Panic(err) return nil, err
} }
for _, lyr := range d.artLayers { for _, lyr := range d.artLayers {
lyr.SetParent(d) lyr.SetParent(d)
} }
for i, set := range d.layerSets { for i, set := range d.layerSets {
var s *LayerSet var s *LayerSet
s, err = NewLayerSet(set.Path()+"/", d) if s, err = NewLayerSet(set.Path()+"/", d); err != nil {
if err != nil { return nil, err
log.Fatal(err)
} }
d.layerSets[i] = s d.layerSets[i] = s
s.SetParent(d) s.SetParent(d)
@@ -190,3 +213,20 @@ func (d *Document) Dump() {
log.Println(err) log.Println(err)
} }
} }
// MustExist returns a Layer from the set with the given name, and
// panics if it doesn't exist.
//
// If there is a LayerSet and an ArtLayer with the same name,
// it will return the LayerSet.
func (d *Document) MustExist(name string) Layer {
set := d.LayerSet(name)
if set == nil {
lyr := d.ArtLayer(name)
if lyr == nil {
log.Panicf("no Layer found at \"%s%s\"", d.Path(), name)
}
return lyr
}
return set
}

31
interfaces.go Normal file
View File

@@ -0,0 +1,31 @@
package ps
// Group represents a Document or LayerSet.
type Group interface {
Name() string
Parent() Group
SetParent(Group)
Path() string
ArtLayer(name string) *ArtLayer
LayerSet(name string) *LayerSet
ArtLayers() []*ArtLayer
LayerSets() []*LayerSet
MustExist(name string) Layer
MarshalJSON() ([]byte, error)
UnmarshalJSON(b []byte) error
}
// Layer represents an ArtLayer or LayerSet Object.
type Layer interface {
Bounds() [2][2]int
MarshalJSON() ([]byte, error)
Name() string
Parent() Group
Path() string
Refresh() error
SetParent(g Group)
SetPos(x, y int, bound string)
SetVisible(b bool) error
UnmarshalJSON(b []byte) error
Visible() bool
}

View File

@@ -2,24 +2,11 @@ package ps
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
) )
// Group represents a Document or LayerSet.
type Group interface {
Name() string
Parent() Group
SetParent(Group)
Path() string
ArtLayers() []*ArtLayer
LayerSets() []*LayerSet
MarshalJSON() ([]byte, error)
UnmarshalJSON(b []byte) error
}
// LayerSet holds a group of Layer objects and a group of LayerSet objects. // LayerSet holds a group of Layer objects and a group of LayerSet objects.
type LayerSet struct { type LayerSet struct {
name string name string
@@ -95,7 +82,6 @@ func (l *LayerSet) ArtLayers() []*ArtLayer {
// ArtLayer returns the first top level ArtLayer matching // ArtLayer returns the first top level ArtLayer matching
// the given name. // the given name.
// TODO: Does funky things when passed invalid layername.
func (l *LayerSet) ArtLayer(name string) *ArtLayer { func (l *LayerSet) ArtLayer(name string) *ArtLayer {
for _, lyr := range l.artLayers { for _, lyr := range l.artLayers {
if lyr.name == name { if lyr.name == name {
@@ -113,12 +99,7 @@ func (l *LayerSet) ArtLayer(name string) *ArtLayer {
return lyr return lyr
} }
} }
lyr := l.ArtLayer(name) return nil
fmt.Println(lyr)
if lyr == nil {
log.Panic(errors.New("layer not found"))
}
return lyr
} }
// LayerSets returns the LayerSets contained within // LayerSets returns the LayerSets contained within
@@ -138,6 +119,23 @@ func (l *LayerSet) LayerSet(name string) *LayerSet {
return nil return nil
} }
// MustExist returns a Layer from the set with the given name, and
// panics if it doesn't exist.
//
// If there is a LayerSet and an ArtLayer with the same name,
// it will return the LayerSet.
func (l *LayerSet) MustExist(name string) Layer {
set := l.LayerSet(name)
if set == nil {
lyr := l.ArtLayer(name)
if lyr == nil {
log.Panicf("no Layer found at \"%s%s\"", l.Path(), name)
}
return lyr
}
return set
}
// Bounds returns the furthest corners of the LayerSet. // Bounds returns the furthest corners of the LayerSet.
func (l LayerSet) Bounds() [2][2]int { func (l LayerSet) Bounds() [2][2]int {
return l.bounds return l.bounds
@@ -165,7 +163,6 @@ func (l *LayerSet) Path() string {
func NewLayerSet(path string, g Group) (*LayerSet, error) { func NewLayerSet(path string, g Group) (*LayerSet, error) {
path = strings.Replace(path, "//", "/", -1) path = strings.Replace(path, "//", "/", -1)
byt, err := DoJS("getLayerSet.jsx", JSLayer(path), JSLayerMerge(path)) byt, err := DoJS("getLayerSet.jsx", JSLayer(path), JSLayerMerge(path))
fmt.Println(JSLayer(path), JSLayerMerge(path))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -300,3 +297,10 @@ func (l *LayerSet) Refresh() error {
l.current = true l.current = true
return nil return nil
} }
func (l *LayerSet) Set(ll *LayerSet) {
if ll == nil {
panic("AHHHHHH")
}
l = ll
}

10
ps.go
View File

@@ -1,8 +1,10 @@
//go:generate godocdown -output=README.md //go:generate sh -c "godoc2md -template ./.doc.template github.com/sbrow/ps > README.md"
// Package ps is a rudimentary API between Adobe Photoshop CS5 and Golang. // Package ps is a rudimentary API between Adobe Photoshop CS5 and Golang.
// The interaction between the two is implemented using Javascript/VBScript. // The interaction between the two is implemented using Javascript/VBScript.
// //
// Use it to control Photoshop, edit documents, and perform batch operations.
//
// Currently only supports Photoshop CS5 Windows x86_64. // Currently only supports Photoshop CS5 Windows x86_64.
package ps package ps
@@ -38,7 +40,7 @@ func ApplyDataset(name string) error {
} }
// Close closes the active document in Photoshop, using the given save option. // Close closes the active document in Photoshop, using the given save option.
// TODO: Move to Document // TODO(sbrow): Move to Document
func Close(save SaveOption) error { func Close(save SaveOption) error {
_, err := runner.Run("close", fmt.Sprint(save)) _, err := runner.Run("close", fmt.Sprint(save))
return err return err
@@ -104,7 +106,7 @@ func Init() error {
// The output always ends with a semicolon, so if you want to access a specific // The output always ends with a semicolon, so if you want to access a specific
// property of the layer, you'll have to trim the output before concatenating. // property of the layer, you'll have to trim the output before concatenating.
// //
// TODO: get rid of the semicolon. // TODO(sbrow): get rid of the semicolon.
func JSLayer(path string) string { func JSLayer(path string) string {
pth := strings.Split(path, "/") pth := strings.Split(path, "/")
js := "app.activeDocument" js := "app.activeDocument"
@@ -138,7 +140,7 @@ func Open(path string) error {
return err return err
} }
// Quit exits Photoshop, closing all open docuemnts using the given save option. // Quit exits Photoshop, closing all open documents using the given save option.
func Quit(save SaveOption) error { func Quit(save SaveOption) error {
_, err := runner.Run("quit", fmt.Sprint(save)) _, err := runner.Run("quit", fmt.Sprint(save))
return err return err

View File

@@ -1,19 +1,14 @@
// TODO: Update package tests. // TODO(sbrow): Update package tests.
package ps package ps
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"testing" "testing"
"github.com/sbrow/ps/runner" "github.com/sbrow/ps/runner"
) )
/*
var testDoc string var testDoc string
func init() { func init() {
@@ -34,7 +29,9 @@ func TestInit(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("Skipping \"TestStart\"") t.Skip("Skipping \"TestStart\"")
} }
Quit(2) if err := Quit(2); err != nil {
log.Println("error:", err)
}
if err := Init(); err != nil { if err := Init(); err != nil {
t.Error(err) t.Error(err)
} }
@@ -44,6 +41,9 @@ func TestOpen(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("Skipping \"TestOpen\"") t.Skip("Skipping \"TestOpen\"")
} }
if err := Init(); err != nil {
t.Fatal(err)
}
if err := Open(testDoc); err != nil { if err := Open(testDoc); err != nil {
log.Println(testDoc) log.Println(testDoc)
t.Fatal(err) t.Fatal(err)
@@ -54,8 +54,12 @@ func TestClose(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("Skipping \"TestClose\"") t.Skip("Skipping \"TestClose\"")
} }
err := Close(DoNotSaveChanges) var err error
if err != nil { if err = Open(testDoc); err != nil {
log.Println(testDoc)
t.Fatal(err)
}
if err = Close(DoNotSaveChanges); err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
@@ -139,6 +143,9 @@ func TestLayerSet(t *testing.T) {
} }
} }
func TestMove(t *testing.T) { func TestMove(t *testing.T) {
if err := Open(testDoc); err != nil {
t.Fatal(err)
}
d, err := ActiveDocument() d, err := ActiveDocument()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -282,19 +289,18 @@ func TestTextItem(t *testing.T) {
} }
} }
/* byt := []byte(`{"Name": "lyr", "TextItem": {"Contents": "lyr", "Size": 12.000, "Font": "ArialItalic"}}`) byt := []byte(`{"Name": "lyr", "TextItem": {"Contents": "lyr", "Size": 12.000, "Font": "ArialItalic"}}`)
lyr := &ArtLayer{} lyr := &ArtLayer{}
// byt := []byte(`{"Name": "lyr"}`) // byt := []byte(`{"Name": "lyr"}`)
// lyr := &TextItem{} // lyr := &TextItem{}
err := lyr.UnmarshalJSON(byt) err := lyr.UnmarshalJSON(byt)
fmt.Printf("%+v\n", lyr) fmt.Printf("%+v\n", lyr)
fmt.Println(lyr.TextItem) fmt.Println(lyr.TextItem)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
*/
} }
*/
func BenchmarkDoc_Go(b *testing.B) { func BenchmarkDoc_Go(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_, err := ActiveDocument() _, err := ActiveDocument()

View File

@@ -1,11 +1,35 @@
# runner # runner
[![GoDoc](https://godoc.org/github.com/sbrow/runner?status.svg)](https://godoc.org/github.com/sbrow/runner) [![Build Status](https://travis-ci.org/sbrow/runner.svg?branch=master)](https://travis-ci.org/sbrow/runner) [![Coverage Status](https://coveralls.io/repos/github/sbrow/runner/badge.svg?branch=master)](https://coveralls.io/github/sbrow/runner?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/sbrow/runner)](https://goreportcard.com/report/github.com/sbrow/runner) [![GoDoc](https://godoc.org/github.com/sbrow/ps/runner?status.svg)](https://godoc.org/github.com/sbrow/runner) [![Build Status](https://travis-ci.org/sbrow/runner.svg?branch=master)](https://travis-ci.org/sbrow/runner) [![Coverage Status](https://coveralls.io/repos/github/sbrow/runner/badge.svg?branch=master)](https://coveralls.io/github/sbrow/runner?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/sbrow/ps/runner)](https://goreportcard.com/report/github.com/sbrow/ps/runner)
Package runner runs the non-go code that Photoshop understands, and passes it to `import "github.com/sbrow/ps/runner"`
back to the go program. Currently, this is primarily implemented through Adobe
Extendscript, but hopefully in the future it will be upgraded to a C++ plugin.
## Installation * [Overview](#pkg-overview)
```bash * [Installation](pkg-installation)
* [Documentation](#pkg-doc)
## <a name="pkg-overview">Overview</a>
Package runner runs the non-go code that Photoshop understands,
and passes it to back to the go program. Currently, this is
primarily implemented through Adobe Extendscript, but hopefully
in the future it will be upgraded to a C++ plugin.
## <a name="pkg-installation">Installation</a>
```sh
$ go get -u github.com/sbrow/ps/runner $ go get -u github.com/sbrow/ps/runner
``` ```
<!---
--->
## <a name="pkg-doc">Documentation</a>
For full Documentation please visit https://godoc.org/github.com/sbrow/ps/runner
- - -
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)

View File

@@ -1,4 +1,4 @@
//go:generate godocdown -template ../.godocdown.template -output=README.md //go:generate sh -c "godoc2md -template ../.doc.template github.com/sbrow/ps/runner > README.md"
// Package runner runs the non-go code that Photoshop understands, // Package runner runs the non-go code that Photoshop understands,
// and passes it to back to the go program. Currently, this is // and passes it to back to the go program. Currently, this is
@@ -16,7 +16,8 @@ import (
"strings" "strings"
) )
// Windows is the runner for Visual Basic Scripts. // Windows is the runner Windows Operating Systems.
// It runs Visual Basic Scripts.
var Windows = Runner{ var Windows = Runner{
Cmd: "cscript.exe", Cmd: "cscript.exe",
Args: []string{"/nologo"}, Args: []string{"/nologo"},