drawio-export/pkg/drawio/options.go

422 lines
12 KiB
Go
Raw Normal View History

package drawio
import (
"flag"
"fmt"
"io"
"os"
"strconv"
)
// Интерфейс параметра экспортёра диаграмм
type Option interface {
apply(opts *Options) // Применить параметр к хранилищу параметров
}
// Ошибка "неподдерживаемый формат"
type ErrUnsupportedFormat struct {
Format string
}
// Описание ошибки
func (e ErrUnsupportedFormat) Error() string {
return fmt.Sprintf("unsupported format: '%s'", e.Format)
}
// Проверка эквивалентности ошибок
func (e ErrUnsupportedFormat) Is(target error) bool {
switch t := target.(type) {
case ErrUnsupportedFormat:
return t.Format == e.Format
}
return false
}
var _ error = (*ErrUnsupportedFormat)(nil) // Проверка реализации интерфейса
type Format string // Формат экспортированного файла
const (
PDF Format = "pdf"
PNG Format = "png"
JPG Format = "jpg"
SVG Format = "svg"
VSDX Format = "vsdx"
XML Format = "xml"
)
// Строковое представление формата
func (f Format) String() string {
return string(f)
}
// Загрузка формата из строки
func (f *Format) Set(str string) error {
for _, fmt := range SupportedFormats() {
if str == string(fmt) {
*f = Format(str)
return nil
}
}
return &ErrUnsupportedFormat{str}
}
// Список всех поддерживаемых форматов экспорта
func SupportedFormats() []Format {
return []Format{"pdf", "png", "jpg", "svg", "vsdx", "xml"}
}
var _ flag.Value = (*Format)(nil) // Поверка реализации интерфейса
// Расширение файла заданного формата
func (f Format) ext() string {
return "." + string(f)
}
// Параметры экспортёра диаграмм
type Options struct {
Application string // Путь к приложению drawio
Output string // Путь к папке с экспортированными файлами
Format Format // Формат экспортированных файлов
Recursive bool // Рекурсивно сканировать вложенные папки с файлами
RemovePageSuffix bool // Удалять суффикс страницы, если это возможно
Quality uint // Качество экспортированного изображения (только для JPEG)
Transparent bool // Прозрачный фона для PNG
// Включать копию диаграммы в экспортированный файл для PDF, PNG и SVG
EmbedDiagram bool
EmbedSvgImages bool // Встраивать изображения в файл формата SVG
Border uint // Ширина рамки вокруг диаграмм
Scale uint // Масштаб в процентах размера экспортированных диаграмм
Width uint // Ширина экспортированной диаграммы с сохранением масштаба
Height uint // Высота экспортированной диаграммы с сохранением масштаба
Crop bool // Обрезать результирующий PDF до размера диаграммы
Uncompressed bool // Выводить несжатый XML
EnablePlugins bool // Включить подключаемые модули
openFile OpenFileFunc // Открыть файл
readDir ReadDirFunc // Прочитать папку на диске
}
// Функция открытия файла
type OpenFileFunc func(string) (io.ReadCloser, error)
// Функция чтения папки на диске
type ReadDirFunc func(string) ([]os.DirEntry, error)
// Путь к приложению drawio
func (opts Options) App() string {
app := opts.Application
if len(app) == 0 {
app = "drawio"
}
return app
}
// Путь к папке с экспортированными файлами
func (opts Options) OutDir() string {
out := opts.Output
if len(out) == 0 {
out = "export"
}
return out
}
// Расширение экспортированных файлов
func (opts Options) OutExt() string {
fmt := opts.Format
if len(fmt) == 0 {
fmt = Format("pdf")
}
return fmt.ext()
}
// Аргументы командной строки drawio
func (opts Options) Args() []string {
args := []string{}
if len(opts.Format) > 0 {
args = append(args, "--format", string(opts.Format))
}
if opts.Quality != 0 {
args = append(args, "--quality", strconv.Itoa(int(opts.Quality)))
}
if opts.Transparent {
args = append(args, "--transparent")
}
if opts.EmbedDiagram {
args = append(args, "--embed-diagram")
}
if opts.EmbedSvgImages {
args = append(args, "--embed-svg-images")
}
if opts.Border != 0 {
args = append(args, "--border", strconv.Itoa(int(opts.Border)))
}
if opts.Scale != 0 {
args = append(args, "--scale", strconv.Itoa(int(opts.Scale)))
}
if opts.Width != 0 {
args = append(args, "--width", strconv.Itoa(int(opts.Width)))
}
if opts.Height != 0 {
args = append(args, "--height", strconv.Itoa(int(opts.Height)))
}
if opts.Crop {
args = append(args, "--crop")
}
if opts.Uncompressed {
args = append(args, "--uncompressed")
}
if opts.EnablePlugins {
args = append(args, "--enable-plugins")
}
return args
}
// Путь к приложению drawio
func WithAppPath(path string) Option {
return optionApplication(path)
}
type optionApplication string
var _ Option = (*optionApplication)(nil) // Проверка реализации интерфейса
func (opt optionApplication) apply(opts *Options) {
opts.Application = string(opt)
}
// Путь к папке с экспортированными файлами
func WithOutput(path string) Option {
return optionOutput(path)
}
type optionOutput string
var _ Option = (*optionOutput)(nil) // Проверка реализации интерфейса
func (opt optionOutput) apply(opts *Options) {
opts.Output = string(opt)
}
// Формат экспортированных файлов
func WithFormat(format Format) Option {
return format
}
var _ Option = (*Format)(nil) // Проверка реализации интерфейса
func (opt Format) apply(opts *Options) {
opts.Format = opt
}
// Рекурсивно сканировать вложенные папки с файлами
func WithRecursive() Option {
return optionRecursive{}
}
type optionRecursive struct{}
var _ Option = optionRecursive{} // Проверка реализации интерфейса
func (opt optionRecursive) apply(opts *Options) {
opts.Recursive = true
}
// Удалять суффикс страницы, если это возможно
func WithRemovePageSuffix() Option {
return optionRemovePageSuffix{}
}
type optionRemovePageSuffix struct{}
var _ Option = optionRemovePageSuffix{} // Проверка реализации интерфейса
func (opt optionRemovePageSuffix) apply(opts *Options) {
opts.RemovePageSuffix = true
}
// Качество экспортированного изображения (только для JPEG)
func WithQuality(q uint) Option {
return optionQuality(q)
}
type optionQuality uint
var _ Option = (*optionQuality)(nil) // Проверка реализации интерфейса
func (opt optionQuality) apply(opts *Options) {
opts.Quality = uint(opt)
}
// Прозрачный фона для PNG
func WithTransparent() Option {
return optionTransparent{}
}
type optionTransparent struct{}
var _ Option = optionTransparent{} // Проверка реализации интерфейса
func (opt optionTransparent) apply(opts *Options) {
opts.Transparent = true
}
// Включать копию диаграммы в экспортированный файл для PDF, PNG и SVG
func WithEmbedDiagram() Option {
return optionEmbedDiagram{}
}
type optionEmbedDiagram struct{}
var _ Option = optionEmbedDiagram{} // Проверка реализации интерфейса
func (opt optionEmbedDiagram) apply(opts *Options) {
opts.EmbedDiagram = true
}
// Встраивать изображения в файл формата SVG
func WithEmbedSvgImages() Option {
return optionEmbedSvgImages{}
}
type optionEmbedSvgImages struct{}
var _ Option = optionEmbedSvgImages{} // Проверка реализации интерфейса
func (opt optionEmbedSvgImages) apply(opts *Options) {
opts.EmbedSvgImages = true
}
// Ширина рамки вокруг диаграмм
func WithBorder(border uint) Option {
return optionBorder(border)
}
type optionBorder uint
var _ Option = (*optionBorder)(nil) // Проверка реализации интерфейса
func (opt optionBorder) apply(opts *Options) {
opts.Border = uint(opt)
}
// Масштаб в процентах размера экспортированных диаграмм
func WithScale(scale uint) Option {
return optionScale(scale)
}
type optionScale uint
var _ Option = (*optionScale)(nil) // Проверка реализации интерфейса
func (opt optionScale) apply(opts *Options) {
opts.Scale = uint(opt)
}
// Ширина экспортированной диаграммы с сохранением масштаба
func WithWidth(width uint) Option {
return optionWidth(width)
}
type optionWidth uint
var _ Option = (*optionWidth)(nil) // Проверка реализации интерфейса
func (opt optionWidth) apply(opts *Options) {
opts.Width = uint(opt)
}
// Высота экспортированной диаграммы с сохранением масштаба
func WithHeight(height uint) Option {
return optionHeight(height)
}
type optionHeight uint
var _ Option = (*optionHeight)(nil) // Проверка реализации интерфейса
func (opt optionHeight) apply(opts *Options) {
opts.Height = uint(opt)
}
// Обрезать результирующий PDF до размера диаграммы
func WithCrop() Option {
return optionCrop{}
}
type optionCrop struct{}
var _ Option = optionCrop{} // Проверка реализации интерфейса
func (opt optionCrop) apply(opts *Options) {
opts.Crop = true
}
// Выводить несжатый XML
func WithUncompressed() Option {
return optionUncompressed{}
}
type optionUncompressed struct{}
var _ Option = optionUncompressed{} // Проверка реализации интерфейса
func (opt optionUncompressed) apply(opts *Options) {
opts.Uncompressed = true
}
// Включить подключаемые модули
func WithEnablePlugins() Option {
return optionEnablePlugins{}
}
type optionEnablePlugins struct{}
var _ Option = optionEnablePlugins{} // Проверка реализации интерфейса
func (opt optionEnablePlugins) apply(opts *Options) {
opts.EnablePlugins = true
}
// Открыть файл
func WithOpenFile(openFile OpenFileFunc) Option {
return optionOpenFile{openFile}
}
type optionOpenFile struct {
openFile OpenFileFunc
}
var _ Option = optionOpenFile{} // Проверка реализации интерфейса
func (opt optionOpenFile) apply(opts *Options) {
opts.openFile = opt.openFile
}
// Прочитать папку на диске
func WithReadDir(readDir ReadDirFunc) Option {
return optionReadDir{readDir}
}
type optionReadDir struct {
readDir ReadDirFunc
}
var _ Option = optionReadDir{} // Проверка реализации интерфейса
func (opt optionReadDir) apply(opts *Options) {
opts.readDir = opt.readDir
}
// Пустой параметр
func WithNop() Option {
return optionNop{}
}
type optionNop struct{}
var _ Option = optionNop{}
func (opt optionNop) apply(opts *Options) {
// Не требуется действий, так как это пустой параметр
}