Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F96116706
main.go
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Dec 22, 19:18
Size
5 KB
Mime Type
text/x-tex
Expires
Tue, Dec 24, 19:18 (2 d)
Engine
blob
Format
Raw Data
Handle
23126077
Attached To
R7035 kicad-pick-and-place-aci-epfl
main.go
View Options
// Copyright (C) 2018 Alexandre Tuleu
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or any later version.
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/>.
package
main
import
(
"bufio"
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
const
(
aciCols
int
=
2
aciRows
=
8
myCols
=
2
myRows
=
6
)
type
Page
struct
{
Width
,
Height
float64
}
func
ParseData
(
pdffile
string
)
([]
Page
,
error
)
{
cmd
:=
exec
.
Command
(
"pdftk"
,
pdffile
,
"dump_data"
)
out
:=
bytes
.
NewBuffer
(
nil
)
cmd
.
Stdout
=
out
if
err
:=
cmd
.
Run
();
err
!=
nil
{
return
nil
,
err
}
s
:=
bufio
.
NewScanner
(
out
)
nbPages
:=
0
var
res
[]
Page
=
nil
for
s
.
Scan
()
{
if
err
:=
s
.
Err
();
err
!=
nil
{
return
nil
,
err
}
l
:=
s
.
Text
()
if
strings
.
HasPrefix
(
l
,
"NumberOfPages"
)
{
if
_
,
err
:=
fmt
.
Sscanf
(
l
,
"NumberOfPages: %d"
,
&
nbPages
);
err
!=
nil
{
return
nil
,
err
}
res
=
make
([]
Page
,
0
,
nbPages
)
}
if
strings
.
HasPrefix
(
l
,
"PageMediaDimensions:"
)
{
if
nbPages
==
0
{
return
nil
,
fmt
.
Errorf
(
"Missing a number of pages"
)
}
w
,
h
:=
0.0
,
0.0
if
_
,
err
:=
fmt
.
Sscanf
(
l
,
"PageMediaDimensions: %f %f"
,
&
w
,
&
h
);
err
!=
nil
{
return
nil
,
err
}
res
=
append
(
res
,
Page
{
Width
:
w
,
Height
:
h
})
}
}
return
res
,
nil
}
type
Label
struct
{
Filename
string
Left
,
Lower
,
Right
,
Upper
float64
}
func
BurstImages
(
filename
string
,
pages
[]
Page
)
([]
Label
,
error
)
{
burstCmd
:=
exec
.
Command
(
"pdftk"
,
filename
,
"burst"
)
if
err
:=
burstCmd
.
Run
();
err
!=
nil
{
return
nil
,
err
}
res
:=
make
([]
Label
,
0
,
len
(
pages
)*
aciCols
*
aciRows
)
for
i
,
p
:=
range
pages
{
width
:=
p
.
Width
/
float64
(
aciCols
)
height
:=
p
.
Height
/
float64
(
aciRows
)
cutFile
:=
fmt
.
Sprintf
(
"pg_%04d.pdf"
,
i
+
1
)
for
i
:=
0
;
i
<
aciRows
;
i
++
{
for
j
:=
0
;
j
<
aciCols
;
j
++
{
l
:=
Label
{
Filename
:
cutFile
,
Left
:
float64
(
j
)
*
width
,
Lower
:
float64
(
aciRows
-
i
-
1
)
*
height
,
Right
:
float64
(
aciCols
-
j
-
1
)
*
width
,
Upper
:
float64
(
i
)
*
height
,
}
res
=
append
(
res
,
l
)
}
}
}
return
res
,
nil
}
const
(
TEXFILE
string
=
"layout.tex"
)
func
GenerateTexfile
(
labels
[]
Label
)
error
{
texfile
,
err
:=
os
.
Create
(
TEXFILE
)
if
err
!=
nil
{
return
err
}
defer
texfile
.
Close
()
fmt
.
Fprintf
(
texfile
,
`%generated automatically
\documentclass[a4paper]{article}
\usepackage[paperwidth=21cm, paperheight=29.7cm, margin=0mm,tmargin=4mm,bmargin=4mm,centering,bindingoffset=0mm,marginparsep=0mm,marginparwidth=0mm,layouthoffset=-5.5mm]{geometry}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\begin{document}
\pagestyle{empty}
`
)
closed
:=
true
for
i
,
l
:=
range
labels
{
if
i
%(
myCols
*
myRows
)
==
0
{
fmt
.
Fprintf
(
texfile
,
`\begin{tikzpicture}[
label/.style={
minimum width =%f\paperwidth,
minimum height = %f\paperheight
}
]
`
,
1.0
/
float64
(
myCols
)-
0.01
,
1.0
/
float64
(
myRows
)-
0.01
)
closed
=
false
}
ii
:=
(
i
%
myCols
)
jj
:=
((
i
-
ii
)
/
myCols
)
%
myRows
fmt
.
Fprintf
(
texfile
,
`
\node[label] at (%f\textwidth,-%f\textheight) {
\includegraphics[trim={%fpt %fpt %fpt %fpt} ,clip, width=0.49\paperwidth]{%s}
};
`
,
float64
(
ii
)/
float64
(
myCols
),
float64
(
jj
)/
float64
(
myRows
),
l
.
Left
,
l
.
Lower
,
l
.
Right
,
l
.
Upper
,
l
.
Filename
)
if
i
%(
myCols
*
myRows
)
==
(
myCols
*
myRows
-
1
)
{
fmt
.
Fprintf
(
texfile
,
`\end{tikzpicture}
\clearpage
`
)
closed
=
true
}
}
if
closed
==
false
{
fmt
.
Fprintf
(
texfile
,
`\end{tikzpicture}
`
)
}
fmt
.
Fprintf
(
texfile
,
`
\end{document}
`
)
return
nil
}
func
GeneratePDF
(
destination
string
)
error
{
latexCmd
:=
exec
.
Command
(
"latexmk"
,
"-pdf"
,
"-interaction=nonstopmode"
,
"-shell-escape"
,
TEXFILE
)
if
err
:=
latexCmd
.
Run
();
err
!=
nil
{
return
err
}
resname
:=
strings
.
TrimSuffix
(
TEXFILE
,
".tex"
)
+
".pdf"
if
err
:=
os
.
Rename
(
resname
,
destination
);
err
!=
nil
{
return
nil
}
return
nil
}
func
Execute
()
error
{
if
len
(
os
.
Args
)
!=
2
{
return
fmt
.
Errorf
(
"Input file required"
)
}
filename
,
err
:=
filepath
.
Abs
(
os
.
Args
[
1
])
if
err
!=
nil
{
return
err
}
destination
:=
strings
.
TrimSuffix
(
filename
,
filepath
.
Ext
(
filename
))
+
"-formatted.pdf"
cdir
,
err
:=
os
.
Getwd
()
if
err
!=
nil
{
return
err
}
tmpdir
,
err
:=
ioutil
.
TempDir
(
""
,
"converter"
)
if
err
!=
nil
{
return
err
}
os
.
Chdir
(
tmpdir
)
defer
func
()
{
os
.
Chdir
(
cdir
)
os
.
RemoveAll
(
tmpdir
)
}()
pages
,
err
:=
ParseData
(
filename
)
if
err
!=
nil
{
return
err
}
labels
,
err
:=
BurstImages
(
filename
,
pages
)
if
err
!=
nil
{
return
err
}
if
err
=
GenerateTexfile
(
labels
);
err
!=
nil
{
return
err
}
if
err
=
GeneratePDF
(
destination
);
err
!=
nil
{
return
err
}
return
nil
}
func
main
()
{
if
err
:=
Execute
();
err
!=
nil
{
log
.
Printf
(
"Got unexpected error: %s"
,
err
)
os
.
Exit
(
1
)
}
}
Event Timeline
Log In to Comment