* arthur/xml_transform/README
* arthur/xml_transform/templates/opendoc/xsl.xsl
* arthur/xml_transform/templates/pdf/main.xsl
* arthur/xml_transform/templates/pdf/regions.xsl
* arthur/xml_transform/image_crop.cc,
* arthur/xml_transform/image_crop.hh: Change ppm loader to magick loader.
* arthur/xml_transform/main.cc: Change man.
* arthur/xml_transform/templates/pdf/main_crop_64.xsl,
* arthur/xml_transform/templates/pdf/regions_base64.xsl,
* arthur/xml_transform/templates/pdf/regions_png.xsl,
* arthur/xml_transform/templates/html/html_generator.sh,
* arthur/xml_transform/templates/pdf/svg_generator.sh,
* arthur/xml_transform/templates/pdf/pdf_generator.sh: Delete.
* arthur/xml_transform/templates/html/xsl.xsl: Rename as...
* thur/xml_transform/templates/html/main.xsl: ...This.
* arthur/xml_transform/templates/html/xsl_base64.xsl: Rename as...
* arthur/xml_transform/templates/html/main.xsl: ...This.
* arthur/xml_transform/templates/pdf/regions_svg.xsl: Rename as...
* arthur/xml_transform/templates/svg/regions.xsl: ...This.
* arthur/xml_transform/templates/xml_transform.sh,
* arthur/xml_transform/templates/svg/line.xsl,
* arthur/xml_transform/templates/ooconvert,
* arthur/xml_transform/templates/pdf/full/line.xsl: New.
* arthur/xml_transform/xml_transform.cc,
* arthur/xml_transform/xml_transform.hh: Change output.
* arthur/xml_transform/xml_transform.pro: Add QMAKE_POST_LINK.
---
scribo/sandbox/ChangeLog | 44 ++-
scribo/sandbox/arthur/xml_transform/README | 31 +-
.../sandbox/arthur/xml_transform/_build/common.o | Bin 0 -> 2580 bytes
.../arthur/xml_transform/_build/image_crop.o | Bin 0 -> 165880 bytes
scribo/sandbox/arthur/xml_transform/image_crop.cc | 73 ++-
scribo/sandbox/arthur/xml_transform/image_crop.hh | 11 +-
scribo/sandbox/arthur/xml_transform/main.cc | 139 ++++--
.../xml_transform/templates/html/html_generator.sh | 3 -
.../templates/html/{xsl.xsl => main.xsl} | 46 ++-
.../html/{xsl_base64.xsl => main_base64.xsl} | 111 +++--
.../arthur/xml_transform/templates/ooconvert | 517 ++++++++++++++++++++
.../templates/opendoc/opendoc_generator.sh | 24 -
.../arthur/xml_transform/templates/opendoc/xsl.xsl | 33 ++-
.../arthur/xml_transform/templates/pdf/main.xsl | 22 +-
.../arthur/xml_transform/templates/pdf/main64.xsl | 62 ---
.../xml_transform/templates/pdf/pdf_generator.sh | 3 -
.../pdf/{regions_base64.xsl => regions.xsl} | 0
.../xml_transform/templates/pdf/regions_png.xsl | 59 ---
.../xml_transform/templates/pdf/svg_generator.sh | 3 -
.../xml_transform/templates/{pdf => svg}/line.xsl | 0
.../templates/{pdf/main_crop.xsl => svg/main.xsl} | 0
.../{pdf/regions_svg.xsl => svg/regions.xsl} | 0
.../xml_transform/templates/xml_transform.sh | 134 +++++
.../sandbox/arthur/xml_transform/xml_transform.cc | 76 +--
.../sandbox/arthur/xml_transform/xml_transform.hh | 2 +
.../sandbox/arthur/xml_transform/xml_transform.pro | 8 +-
26 files changed, 1018 insertions(+), 383 deletions(-)
create mode 100644 scribo/sandbox/arthur/xml_transform/_build/common.o
create mode 100644 scribo/sandbox/arthur/xml_transform/_build/image_crop.o
delete mode 100644 scribo/sandbox/arthur/xml_transform/templates/html/html_generator.sh
rename scribo/sandbox/arthur/xml_transform/templates/html/{xsl.xsl => main.xsl} (89%)
rename scribo/sandbox/arthur/xml_transform/templates/html/{xsl_base64.xsl =>
main_base64.xsl} (75%)
create mode 100755 scribo/sandbox/arthur/xml_transform/templates/ooconvert
delete mode 100755
scribo/sandbox/arthur/xml_transform/templates/opendoc/opendoc_generator.sh
delete mode 100644 scribo/sandbox/arthur/xml_transform/templates/pdf/main64.xsl
delete mode 100644 scribo/sandbox/arthur/xml_transform/templates/pdf/pdf_generator.sh
rename scribo/sandbox/arthur/xml_transform/templates/pdf/{regions_base64.xsl =>
regions.xsl} (100%)
delete mode 100644 scribo/sandbox/arthur/xml_transform/templates/pdf/regions_png.xsl
delete mode 100644 scribo/sandbox/arthur/xml_transform/templates/pdf/svg_generator.sh
copy scribo/sandbox/arthur/xml_transform/templates/{pdf => svg}/line.xsl (100%)
rename scribo/sandbox/arthur/xml_transform/templates/{pdf/main_crop.xsl =>
svg/main.xsl} (100%)
rename scribo/sandbox/arthur/xml_transform/templates/{pdf/regions_svg.xsl =>
svg/regions.xsl} (100%)
create mode 100755 scribo/sandbox/arthur/xml_transform/templates/xml_transform.sh
diff --git a/scribo/sandbox/ChangeLog b/scribo/sandbox/ChangeLog
index 176e809..dcff59e 100644
--- a/scribo/sandbox/ChangeLog
+++ b/scribo/sandbox/ChangeLog
@@ -1,4 +1,40 @@
-2010-07-23 Arthur Crepin-Leblond <crepin(a)ptaouchnok.lrde.epita.fr>
+2010-08-05 Arthur Crepin-Leblond <crepin@ptaouchnok.lrde.epita.fr@>
+
+ Output change in xml_tranform.
+
+ * arthur/xml_transform/README
+ * arthur/xml_transform/templates/opendoc/xsl.xsl
+ * arthur/xml_transform/templates/pdf/main.xsl
+ * arthur/xml_transform/templates/pdf/regions.xsl
+
+ * arthur/xml_transform/image_crop.cc,
+ * arthur/xml_transform/image_crop.hh: Change ppm loader to magick loader.
+ * arthur/xml_transform/main.cc: Change man.
+
+ * arthur/xml_transform/templates/pdf/main_crop_64.xsl,
+ * arthur/xml_transform/templates/pdf/regions_base64.xsl,
+ * arthur/xml_transform/templates/pdf/regions_png.xsl,
+ * arthur/xml_transform/templates/html/html_generator.sh,
+ * arthur/xml_transform/templates/pdf/svg_generator.sh,
+ * arthur/xml_transform/templates/pdf/pdf_generator.sh: Delete.
+
+ * arthur/xml_transform/templates/html/xsl.xsl: Rename as...
+ * thur/xml_transform/templates/html/main.xsl: ...This.
+ * arthur/xml_transform/templates/html/xsl_base64.xsl: Rename as...
+ * arthur/xml_transform/templates/html/main.xsl: ...This.
+ * arthur/xml_transform/templates/pdf/regions_svg.xsl: Rename as...
+ * arthur/xml_transform/templates/svg/regions.xsl: ...This.
+
+ * arthur/xml_transform/templates/xml_transform.sh,
+ * arthur/xml_transform/templates/svg/line.xsl,
+ * arthur/xml_transform/templates/ooconvert,
+ * arthur/xml_transform/templates/pdf/full/line.xsl: New.
+
+ * arthur/xml_transform/xml_transform.cc,
+ * arthur/xml_transform/xml_transform.hh: Change output.
+ * arthur/xml_transform/xml_transform.pro: Add QMAKE_POST_LINK.
+
+2010-07-23 Arthur Crepin-Leblond <crepin(a)lrde.epita.fr>
OpenDocument output (odt and odf).
@@ -13,7 +49,7 @@
* arthur/xml_transform/xml_transform.cc
* arthur/xml_transform/xml_transform.hh
-2010-07-22 Arthur Crepin-Leblond <crepin(a)ptaouchnok.lrde.epita.fr>
+2010-07-22 Arthur Crepin-Leblond <crepin(a)lrde.epita.fr>
SVG output.
@@ -60,7 +96,7 @@
* arthur/xml_transform/templates/pdf/regions.xsl: Rename as...
* arthur/xml_transform/templates/pdf/regions_png.xsl:...this.
-2010-07-08 Arthur Crepin-Leblond <crepin(a)ptaouchnok.lrde.epita.fr>
+2010-07-08 Arthur Crepin-Leblond <crepin(a)lrde.epita.fr>
XML transform program.
@@ -99,7 +135,7 @@
* arthur/xml_transform/templates/pdf/regions.xsl,
* arthur/xml_transform/xml_transform.pro: New.
-2010-07-05 Arthur Crepin-Leblond <crepin(a)stockholm.lrde.epita.fr>
+2010-07-05 Arthur Crepin-Leblond <crepin(a)lrde.epita.fr>
ICDAR XML to HTML.
diff --git a/scribo/sandbox/arthur/xml_transform/README
b/scribo/sandbox/arthur/xml_transform/README
index 9ac4973..1733535 100644
--- a/scribo/sandbox/arthur/xml_transform/README
+++ b/scribo/sandbox/arthur/xml_transform/README
@@ -2,35 +2,31 @@ xml_transform
OPTIONS:
HTML output:
- --html <xml> <ppm> <out_dir> : HTML output with non-text regions
cropped into many png files.
- --html-base64 <xml> <out_dir> : HTML output from a container XML file.
+ --html input.xml image output.html Creates HTML file, images are embedded inside
in base 64 format.
+ --html-base64 input.xml output.html Same as --html but input is a XML file with
images encoded in base 64 inside.
+ --html-full input.xml image output_dir Creates HTML file without converting images
in base 64. Images + HTML file are placed in output_dir.
PDF output:
- --pdf <xml> <ppm> <out_dir> : PDF output with non-text regions
cropped into many png files.
- --pdf-no-crop <xml> <ppm> <out_dir>: PDF output with the entire
picture displayed over the text.
- --pdf-base64 <xml> <out_dir> : PDF output from a container XML file.
- --pdf-base64-no-crop <xml> <ppm> <out_dir> : PDF with the entire
picture displayed over the text, the picture is loaded from a container XML file.
+ --pdf input.xml image output.pdf Creates PDF file, images are embedded inside in
base 64 format.
+ --pdf-base64 input.xml output.pdf Same as --pdf but input is a XML file with images
encoded in base 64 inside.
-SVG output:
- --svg <xml> <out_dir> : SVG output (works only with base 64 xml encoded.
-
-Base 64 operations:
- --to-base64 <xml> <ppm> <out_xml> : Produces a container XML file
by converting cropped pictures into base 64 format.
+SVG output (experimental, may not work with all files):
+ --svg input.xml image output.svg Creates SVG file, images are embedded inside in
base 64 format.
+ --svg-base64 input.xml output.svg Same as --svg but input is a XML file with images
encoded in base 64 inside.
OpenDocument output:
- --open <xml> <ppm> <out_dir> : OpenDocument output (odt, odf).
+ --oo-doc input.xml image output.odt Creates Open Document Writer (odt) file.
Base 64 operations:
- --to-base64 <xml> <ppm> <out_xml> : Produces a container XML file
by converting cropped pictures into base 64 format.
- --to-base64-no-crop <xml> <ppm> <out_xml> : Same as to-base64 but
only the picture is converted in base 64.
- --from-base64 <xml> <out_dir> : Decodes a XML container file to produce
original image files.
+ --to-base64 input.xml image output.xml Creates a container XML file. It will
contain regions which are cropped and converted in base 64.
+ --to-base64-no-crop input.xml mage output.xml Same as --to-base64 but only the full
picture will be converted, regions are not cropped
+ --from-base64 input.xml output_dir Decodes a XML file which has been encoded in
base 64, regions will be converted into png files and saved in output_dir.
-For PDF/HTML/SVG/OD output, Bourne shell scripts are provided to produce the outputs,
just run sh *_generator.sh
Requirements:
PDF : fop >= 0.95
HTML : xsltproc
SVG : trunk version of fop
-OpenDocument : ooconvert
+OpenDocument : ooconvert (included)
BUILD:
@@ -38,7 +34,6 @@ Chnage the environment variable QMAKE_CXXFLAGS in xml_transfrom.pro
then
mkdir _build
cd _build
-cp -r ../templates .
qmake ../xml_transfrom.pro
make
diff --git a/scribo/sandbox/arthur/xml_transform/_build/common.o
b/scribo/sandbox/arthur/xml_transform/_build/common.o
new file mode 100644
index 0000000000000000000000000000000000000000..c89e964d50e6ca7ed0d9c1b2f2ffb1e0c8ebce39
GIT binary patch
literal 2580
zcma)8U1%It6h5;%iK|Uho1%yojOkh%HDfl}w4y$wCX==%#<U^UzjWA4Cc8s-XT$Dn
z+(?4p*4ANM{DD3Q{!j#;`%uLP3$=O3lL$owUj#wHl0_2egAalAJG1v@r)fkF-2Kkq
z{qDJE@4dTk>tiE|qL37YqSUmAeu_3C$p8+~UTP2GtzyEI_eZ7nv{(AuFSU8go7LrY
zZ~B(s>c0|O9geGY$f_FW+&?#2AC9*%J21vEZz-;N$+)Ml2jT7&Uypfj#ABWdzZwsm
zm7417>+AK{o{QJd-6-vXAw$Uau^JX%-t=nI*H!XXyyqIzy!{RQuzKYnuV4M{F$UCo
z`sK+=?MZ*S%`e4JZ>Y`)5`r~R(2k`F&dN1~!@&-)6I9H**r8fC^RKO_F4sK0w&N;-
zs(U3&?CUkz1GlSc-SXC7KV$HgtKaaxLS0$&s|&DevP<D)^hdDE{@mFybkJLAwBe52
zwHhxL67<u5G3F~<wY5&KRNaH*E1n*kzR6#@Mo&?_u5@&_5FLN;1BJ>^K2`7mZ|@_(
z!Oo8&bWUlx8lkV0eP2fCSEZ${&|iV){RlEX=Z|ms1M+}aUwLa{jFhFAIE!tn`kumP
zty9D=0aezIw#VL$JiohT<h(j^Av#h4O()#PF)ni$M^e3?6`5CQIj>%b(y^hTXF3lJ
zTQhdb=}c<<T3=5>OLR9>BCWWXb5k=wx6r_h)CyKsbFH#V+HA^Akv3B-k|v#+@!I&2
zlap@2cGANMeF2d?r!f!sNlTliVU<m5-Zj9RwHi~cj4@Y8<zSilT+VVp?&MudJ2pPm
zQ*=}2SxhYCOY_*s|C5iAwl|c@cRYr%2cr#xd&lEp477;kogak0!44t!3VaB7w{!yI
zFs=cakFOSUG5@0&JY763l;mJYg6|CW6BwNTUwK@2P@mu#1Rj7-ima~}j&Oay!;t&s
zy~+AsfX;k<7%V3EWKC>yjK`}2W%+3+JXZ?mu;ejVmw8v9WH=y1a-W4AuCE5;5PaOf
zdoW~ui_j%ERN9XQ@pmLe#@>NL>KuDkHc}+Y7@vV~i1R)XISew7QSO2LOK93WoZMe|
zURdWng!yWB5e-NZ#6l{priA?}ZPc3)<_oXPw(MFXD@u*GLC%S8omLs=Z@MYb+d9pB
z+~KA~X?N3r77cdTbn&m`E@2)3c40j}|5CUQN2CE{dqmimfF0OR_zZB|7jXu*zu#v6
zyv<&NeHnw_FXn3xHIV0bZL^8rjl83oCT)L#LUwYlU|IUa_@t2>#-pT@G3C5zJF~_q
zt60M8gVe)A0a2naZMnvrowe{<xw?GP!sLm=bA^2FXwkH7BV%Rft%5!=YTBGKD)SSG
zY^vy<aAvLYOLO|E(MiJ|?>p%x28L2aYtnLxwrelg?jkA)%^E1!>5Qv`%1D>X2AGR^
zCzVB>vCtbXvVW^c2ao4%Rc@8gpR;FmJ19$5l{7Q?dC)_G_X=nIap(~=_5>p?%^AiH
zBEF9i9G8oXxCoyywiEpTR50%b+nBe(h<W@MC~_ZBFOcJWH#mNp5pjzVzeo6~40yi~
v_%$Q=uQGyvRoFiY`xjyVCh(^4^V`7np;S`#;az6Lb?RZn-5eA4l(7E+fD8?b
literal 0
HcmV?d00001
diff --git a/scribo/sandbox/arthur/xml_transform/_build/image_crop.o
b/scribo/sandbox/arthur/xml_transform/_build/image_crop.o
new file mode 100644
index 0000000000000000000000000000000000000000..33fdc249e52ac5b0464f82e2441fb17003caf471
GIT binary patch
literal 165880
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≷pCy0ge(XWX>kOoaV5v2RaAc{7P;xbq?QfA%Bx{}Dj$A0}dd
z)(`ieM7vQBJ;|~EAw=xY_L<K9e{}wx5T|pFloQwQEEl=%_ZVMveS$Z$JQ$ZQq8)y-
z$zi`i_*`<>^|<-x){l$l7vlb?U(V-PzhjB0-*W1qem%b<#qT)rJ6Zh3S$;X>=egHu
ztbh6k&c%IuBDfw;aJ+kyqx~F4JRi@$fsBLWIOAaX8OIdbjpNMo2lwMVmiuvk?x)*3
z_8Ucx{f?*oH|)oDOZ^)K?;~F9&hv<`lcSw|Kt#EEu%Cl-d?6o3#QvuU>UkIVCBh#D
zGVVo0#LaPnxRiFpy<F^TB^`%c+i~kg+jTwQIA=+G`g{X@uRV8Tx>rx|8zg>u-VQ(A
z&XE6UNN2u(CZgWXryug~N)9`Z6YcC*M2<7G>v03R7mDBYV!wq5ojb(uK(QYtcE(8^
zo?oeR77;r7e1QD!75hU(=sYfdyAr)|0_D<iV85f7j`Ex+IFSfD&vT6bIwJC$ON8F-
zK<4`}IqZvwu)iYqrDAVWe!Jm$r07wfdb%9QkLNSyw?OPm#Qr7`_T^%4AxAvxh}i#o
zBJ3N0+`j{lKkPe8JLpD)Jp)MlcJ#w}WPk1lzkWpM6cORaeont*$YIz07xqfAv)|FK
z+ZEcc?q8_i(M$)gk^N35V!v~U(AE6}`*o)u{B=8ne;Mt_NB3j+PZNLc&wRQNQExX9
zufh5s;<Z>`MnvP+^#c2k<kw*xH_M6sl}Us?@24>RNFw|zh$}FD3jba>nu3nwKqBJE
zAtLSqAmbP!c1UXbDPpe>`y?XH-#T8@uW!7tf5Uk397P{D#KrkX0Qdj*l(_B`uKPRc
z2O;ZxR}&G}$Fw6Z#?SiOQsUZ9;=-*hZD+X{7m5@+?t$xNUV(Ye*-YOL>j}i(T6<@G
zGrzS&h<-^#Ji0uHN9Tj%!S==S9ZvM}=_UEV{#*0$&JVi%L0`8|%%}By5(i@j;{xjT
zH(u`JVV-_1(}A}!u8Z*enjHHrCdYa5P2ukmvHypHpVE%=CW@}F7ZmFs{@bwrq0e@w
zuO9?;`-A@><k;y5A}WXNko7eb$m4e`5y$^zB97A&%x4as6B1ERdkgZs%KBvdOn-)W
zb3lDYM7^#DGM`S+VLsavA;NKh`E)0Ty^q*=e}MKvu@{NGMC`|leXQ8Maqa--hv(2d
zuGAY&M1Fc+06jgvB0qh6(9R3!kK;o>#$8Ut_&l8m9kv6GM=ujG&t<)ne<A!kBK$it
z9^|(x5&5y7Fn(Rn$WNCG_WoiYB=)0#EWa)n>}6ut^L6a6=j*UXnGX9*v0p@leKwH$
zUr)qwx|N9IbT1Ld<FAbG2KT-i$2DEf<MG^`=^fnjC+`!_1gHL0M8toC;9MZ}?;?l&
zaY=ugi2N6cJ(CFCenjL`CS2De(l3>CU7z5q#r`c3^DMRt?th@5zAuFQioqF=t{>#5
z+auy(dt^MdV%PNp`wZ?6yS{F;%R8_2>yf#Lhr08L$d}_d%eeqZ-5tm=kL7uv^H)9p
z0O$FE{p~cdH<PC^&qWrx{q!JWFx2D4OsPlk!AxK8#Li#igf|jVUl#%y@AX88-9kjX
z-n`|0vHwHt&x>8RXOzdwUmri@mkoOW`41rOhV@)T<X=xjerE{3M7W+OApb|enLq1^
z`9DKD^j{)}{avxQ5Mlo}koNzO!~Qc7`|J4u>|4ok+yO{?Pa^ESiLf6ecKjJTZ_tnJ
zkA6jh-h5#+{m_5Qh)uZu6@E4m<-MGUey!^bemwr{*9(cLm)D5!d!GnD-S6S2=P}5)
zm&C{R%lNV+K8|0Ei~XE&jSw6yc8*`Pv!B!M-QS!p_GYoOpVNK~5&Cn)ew)}I7W-3z
z3&pPc)swhiz_@Yz^!X0`ZKUufBKis25AFK+A)Za0-*p!~-9MmnJUHV%g^0NIxP#-4
zKhr;MsPBpNM}1F~{jLzM<Hm8)#|`)-({a4?xP<*SkfVHh97g#HST7u(h~RqsK%8et
zy?Nv71yX-Ei2ow-e^+=Q;O^fC$m7?ah;j}hqHws?quV!bC2M<`*l{Y>cHC;wc72~1
z`=e>;{c+0I_Ss^`R8sGMm)IW=`@>>iAoe9<e^czs#oi+Jbz=Ws>>I?c=Yy!X45_yq
zsjs7n=VN`jpdQ~)ujdHY<2m?s<i9xTZX)V+84>mRArW@nPoSe%Z{XVy;on{AaUc=?
zZ1(}QQyvHUC2iNJSFc?!fgkIAB@y-hArbbq+#l@=L$S6iDfgCA?#@!~oyoC(FR>pe
zm?d`IKEIOt2B;rBE&~Tjxpe=*L5q+hZaqH2uCD_TziyWc<^CS>`38QB6Mt&d^?^9q
zKN&|?BJ8|>&2sbtvK)QH-e2tPJ#WzE%t&#)g?JLiPx#fbycj>vB%(j+^8o5W-(P@T
z_rJZR|Dir~dq92Y_5i=HxgY#=`GETVCCaa#`yjuOQhwgQWce$l{QCS3`)Oit7W*u*
zUrU7jW<j<e?$3D;>vw^qKSxBN7mIzV*jvQT>lW&KF7|K4-a*>OHbm^-McPSMa_ILK
z`ypb_^X$|?`_S`*Meccr>-KcNc^>P**dD;&Aj1A%LG~M_vpw*AH9b!U4>2D2oym0U
zugeL1N%$7nkMF;6a{zk~5pO1t>p2e~Hp+8C=;-?wYq4&P={R1xJ>z)kc^mrexsrY@
z5$X33k-m!fNkE^!1D|5OHTh@Aka2u2{TzBd$gy8G5&IoZL^_W%(|LTEem?O(c<){8
zcZ!|oGma}blzPAaN;;N6=y79TBF<<1gpVO!jrG;UbFqGwi2dIX`xnG{_^v__i2X8&
z7=QTujO!)_5iuVgNkp8LM8wJGXFUI(C;W2adPm(t#QqNme_HszfPAjV=U@S3x*zdN
ztVbncFdjnuFYfmM*?uMx(e5S_alEF|jzXVL{0ieN@oUt-*dHSQ8109Mlg<lF$MMwP
zGx!G26Ud>vfe76o8U}Sc0jb-C9QF(%?E8tmkJ$6XK3MES#a<%zv0|?gdz0XFu{Vo-
zwxnM}ME-Ncew)}I7W-3TUnus)VqY$Hem{ZxuMzv_V&5S4U`N;93CQwoOOF0hNRIvy
zB1d_TC8E6i-U9W?X@`FmIs7jthyOi9Tt_`ZM7v%{M7_R7#PR!tcr>nS1$RUHr`}%d
z2RJVJ`UCwem+3ez!<qgx)_;p%MEq)r@MC|Y-xcKW^TyLx$<e;_yc6y9E8#n^AE2G{
zI+^YKL?Y~*&(QxoBHHt%M6_o;kHL7W=ZUC?MM!5oydubPkoCaxDaZBCh#2QNhLA%_
zw|@-ndi)+B=|hR=CnpinPbL!4Pw)ss``tjq{<<Gx9DIQsVy_Yr*9s!`M_17MEA}7k
zk5{+!^+zrd{Y>{uluP$Z@N%Yu-$+Ec=L>&B@M9wS{dVjh@Y`4LP$JUHgkLCl0}(p+
z3ttB0@mxuc<GF^2e)c8Pah$edyMuiPAnm&oVeiFs*awj#-_hi#?@A)-dlC`*HPDXw
zK3(h=i~UNmUn};xVxKSe$Hcxs?2E*{OzbPf-Xiw3VqY)zUj;j`-6H?aK*radi1_vv
z>@D^zvGY46v=1R7{$XMtE%r*WPZE2B*r$tqme?;7yZ*ij@}DF2d&T~c*dGTnzC~hR
zCiWF#ZxQ>y$<c4SYzcq#+dY9S&p|}Qn@2>v{2mJR_&pT*SChm4baMD#OoTtbe?q*L
zcKFW~`+P}%j0n92VqYY7eiw!Ntq^;Q*#AwA{5p4X^V=OrUL^c%BF34Eh!{`y<TwER
zeb~>@uJpVU<Ac7gMZ41Ta`YE{J@q~MJN<T(^Yo2!Ul;xS38vqI_mha<2Gl=^*Sq5g
z^*<(uKJSmR-Tnw<yVduvP#^osxWMadmMe$j0qTR-PmF&YIqI*T9R6n!;m2`@`WMj-
z|0~5lPwaP#{Q<G-@d$b=$e|bHIDq?BoM*9K^m!h*7dh(ZK(QAJA4x>HGFT4u>tQSh
z;^B1*<EapwKs(~$bqwvzl72oB@#_1_u(RIDb-km0`hs(O9>8?ePZjx(c>hEEI1lE!
znsb;w1mi3b7k~4_uIEcg*Y^{C!uvY3<Km0+CFaBHQ|{08Qrur(AHkkM4jf4Q8S6rU
z%s;^L{(^M@QvQ92zv4NP;3y*YJDrHZbf)mffXwe7MCA7z(~;jRlFsW!@_!SZpu$v4
z`=jaT^es7_A|0=s>vX&Vtkd_F^aCYbkJr!{K#t=&fp#3%Da1g~{mv7P<0a(5pt_of
z<NF{H=^Vcq=etD2xr*t~`wtNZ`&*{txc)5ZTyMnn3|%-bW53;q*pKUuxL<E#hoH)0
zI`%7+^rIxbgz4CCjHK)H0`&Ae4E<{+(=WsI91;ENP4Qnr{xPm=i0D6`5fT3nM3k#D
z#@WD`=ugD6uuhNIjN?Q+8}C68PjJr<M9!lEn7m#@d<y4F;ub;0@jifyk=KRm`49Ln
z!gt^}2);WJ`|l(8Cn9u9h=^-4u?MbCiGRm@o46kLO^BFBEFj{f|0=N~jz4i%+&>{A
zp6(paZbNyb-S%KRM)~(8qJQKt9qm(J7yp3sD>>>__dEFM`v<6})5Py0BHG9OK(-Hk
z{}6n+aE?c87aiID5kC%{o+s#hySe$XzjOR!e?Ef<r<p|Ldjb8?pD!2tEn>e*?DvUX
z>tej@Eq;aKcZA?z@#DC{>(+5Z%xCm<F!*`GFD33S*ZoM>*TINS_ix14nf(`;;gUed
z*Olc$eC+3pKTGU-d`0}c-lu)A*hh=~BqHo(VxJ)P>0;O8FzhqM&hj}q?)p`y3+_vi
z?|}P_#Qu1GKs;RTcMrgGd-6f@{5FK^T<Q*y_=@E|{7|fuVfrz6UO*h7+<7Gq{xb4X
zjB7;PbnV4)1UCUOBr0bNuJ4H_VE#kIzZt@>5{@pW?T-t8M)*qM7~1rH-8l|aC{;v^
z;5h*iy1ZU<s_<Mu_$(p{%j-4T?<GRx5#f3rBW~X4@doy9n2yHE@rC|f(Vv~k?)pXY
z{^X6gFG2+8c;PhRd_sio1(JRnF^YLM5jQRQeK`k{e2xpwsd&ysJRS8(#7TtnL1z}`
z9mETjdYp)p(sCjim%h$HW6nT-bgo5x60gU8#5p*Q#GA2BfQYyrCf=gd--RzH&Vvr|
zcIco#J9jFzKN0?eiFjBvfryiqo)4juTrGAz|3Uel5U%Gtk14gD9F4tuC*T4c58|^p
z4#Y)xu1<Ub^-f%j_C<uwyF}#s4e>41xA3l8fxm<LCc@sIxE%E@yo|UK>uZG1B>qdO
hON8G=g#O=zFBSf-@Nb0wEWGR1@Lz>|h`7l5e*nx+9+Ut8
literal 0
HcmV?d00001
diff --git a/scribo/sandbox/arthur/xml_transform/image_crop.cc
b/scribo/sandbox/arthur/xml_transform/image_crop.cc
index ffe2b44..50fadd8 100644
--- a/scribo/sandbox/arthur/xml_transform/image_crop.cc
+++ b/scribo/sandbox/arthur/xml_transform/image_crop.cc
@@ -34,6 +34,7 @@
#include <mln/core/alias/box2d.hh>
#include <mln/core/image/image2d.hh>
#include <mln/io/magick/save.hh>
+#include <mln/io/magick/load.hh>
#include <mln/io/ppm/all.hh>
ImageCrop::ImageCrop(QString xml, QString img, QString output) :
@@ -47,26 +48,15 @@ ImageCrop::~ImageCrop()
{
}
-/* Save PPM image to PNG format in output_dir/img. */
-void ImageCrop::save_image(QString file)
+/* Save image to PNG format in output_dir/img. */
+void ImageCrop::save_image(QString out)
{
using namespace mln;
image2d<value::rgb8> ima;
- io::ppm::load(ima, image_.toStdString());
+ io::magick::load(ima, image_.toStdString());
- QString filename;
- if (file == QString::Null())
- filename = Common::get_file_name(image_);
- else
- filename = file;
-
- // std::cout << "Saving " << image_.toStdString() <<
" to "
- // << output_dir_.toStdString() << "img/"
- // << filename.toStdString() << ".png"
- // << std::endl;
-
- io::magick::save(ima, output_dir_.toStdString() + "img/" +
filename.toStdString() + ".png");
+ io::magick::save(ima, out.toStdString());
}
/* Return the image in base 64. */
@@ -83,7 +73,7 @@ QString ImageCrop::img_to_base64()
}
/* Decode the base 64 string str and save into output_dir_/img/img_name. */
-bool ImageCrop::img_from_base64(QString str, QString img_name, QString mime)
+bool ImageCrop::img_from_base64(QString str, QString img)
{
QByteArray ba;
@@ -91,7 +81,7 @@ bool ImageCrop::img_from_base64(QString str, QString img_name, QString
mime)
QByteArray out_ba = QByteArray::fromBase64(ba);
QImage ima = QImage::fromData(out_ba);
- return ima.save(output_dir_ + "img/" + img_name + "." + mime);
+ return ima.save(output_dir_ + img);
}
/* Read all regions of the XML file and save all base 64 data into output_dir/img */
@@ -125,7 +115,8 @@ void ImageCrop::from_base64()
{
QString data = node.firstChildElement("data").text();
QString mime = node.firstChildElement("mime").text();
- img_from_base64(data, id, mime);
+ QString img = id + "." + mime;
+ img_from_base64(data, img);
}
}
child = child.nextSibling();
@@ -138,6 +129,21 @@ void ImageCrop::to_base64(QString out_file, bool no_crop)
{
QFile file(xml_);
file.open(QIODevice::ReadOnly);
+
+ QDomDocument doc;
+ doc.setContent(&file);
+
+ QDomElement root = doc.documentElement();
+ QDomNode child = root.firstChild();
+
+ while (!child.isNull() &&
!child.toElement().tagName().contains("page"))
+ child = child.nextSibling();
+
+ QString width = child.toElement().attribute("image_width", "0");
+ QString height = child.toElement().attribute("image_height", "0");
+
+ file.close();
+ file.open(QIODevice::ReadOnly);
QTextStream stream(&file);
QFile file2(out_file);
@@ -163,9 +169,10 @@ void ImageCrop::to_base64(QString out_file, bool no_crop)
stream2 << "\n" << " <container>\n";
stream2 << " <mime>png</mime>\n";
- QString file_name = Common::get_file_name(image_);
- save_image();
- QFile img(output_dir_ + "img/" + file_name + ".png");
+ QTemporaryFile tmp(output_dir_ + Common::get_file_name(image_) +
"_XXXXXX.png");
+ tmp.open();
+ save_image(tmp.fileName());
+ QFile img(tmp.fileName());
img.open(QIODevice::ReadOnly);
stream2 << " <data>\n";
@@ -178,7 +185,9 @@ void ImageCrop::to_base64(QString out_file, bool no_crop)
stream2 << "\n <coords>\n";
stream2 << " <point x=\"0\" y=\"0\"
/>\n";
- stream2 << " <point x=\"0\" y=\"0\"
/>";
+ stream2 << " <point x=\"" << width <<
"\" y=\"0\" />\n";
+ stream2 << " <point x=\"" << width <<
"\" y=\"" << height << "\" />\n";
+ stream2 << " <point x=\"0\" y=\"" <<
height << "\" />";
stream2 << "\n </coords>";
stream2 << "\n" << " </image_region>\n";
@@ -210,7 +219,7 @@ void ImageCrop::to_base64(QString out_file, bool no_crop)
QDomElement root = doc.documentElement();
QString id = root.attribute("id", "none");
- QFile img(output_dir_ + "img/" + id + ".png");
+ QFile img(region_map_[id]);
img.open(QIODevice::ReadOnly);
stream2 << " <data>\n";
@@ -220,6 +229,7 @@ void ImageCrop::to_base64(QString out_file, bool no_crop)
stream2 << " </data>";
stream2 << "\n </container>";
+ img.remove();
img.close();
}
@@ -233,7 +243,7 @@ void ImageCrop::to_base64(QString out_file, bool no_crop)
file.close();
}
-bool ImageCrop::crop_regions()
+bool ImageCrop::crop_regions(bool temp)
{
Loader loader;
QFile f(xml_);
@@ -265,7 +275,7 @@ bool ImageCrop::crop_regions()
QDomNode coords = region.firstChild();
QString id = region.toElement().attribute("id", "none");
- qDebug() << region.toElement().tagName();
+ // qDebug() << region.toElement().tagName();
while (!coords.isNull() &&
!coords.toElement().tagName().contains("coords"))
coords = coords.nextSibling();
@@ -301,10 +311,19 @@ bool ImageCrop::crop_regions()
box2d box = make::box2d(y_min, x_min, y_max, x_max);
image2d<value::rgb8> ima;
- io::ppm::load(ima, image_.toStdString());
+ io::magick::load(ima, image_.toStdString());
ima = scribo::preprocessing::crop(ima, box);
- io::magick::save(ima, output_dir_.toStdString() + "img/" +
id.toStdString() + ".png");
+ if (temp)
+ {
+ QTemporaryFile tmp(output_dir_ + id + ".XXXXXX.png");
+ tmp.open();
+ region_map_[id] = tmp.fileName();
+ tmp.setAutoRemove(false);
+ io::magick::save(ima, tmp.fileName().toStdString());
+ }
+ else
+ io::magick::save(ima, QString(output_dir_ + id + ".png").toStdString());
}
region = region.nextSibling();
}
diff --git a/scribo/sandbox/arthur/xml_transform/image_crop.hh
b/scribo/sandbox/arthur/xml_transform/image_crop.hh
index 9b034cc..ee5ca56 100644
--- a/scribo/sandbox/arthur/xml_transform/image_crop.hh
+++ b/scribo/sandbox/arthur/xml_transform/image_crop.hh
@@ -36,15 +36,15 @@ class ImageCrop : public QObject
Q_OBJECT
public:
- ImageCrop(QString xml, QString img, QString output);
+ ImageCrop(QString, QString, QString);
~ImageCrop();
- void save_image(QString file = QString::Null());
- bool crop_regions();
+ void save_image(QString);
+ bool crop_regions(bool temp = false);
QString img_to_base64();
- bool img_from_base64(QString str, QString img_name, QString mime);
- void to_base64(QString out_file, bool no_crop);
+ bool img_from_base64(QString, QString);
+ void to_base64(QString, bool);
void from_base64();
@@ -52,6 +52,7 @@ private:
QString xml_;
QString image_;
QString output_dir_;
+ QMap<QString, QString> region_map_;
};
#endif /* !IMAGE_CROP_HH */
diff --git a/scribo/sandbox/arthur/xml_transform/main.cc
b/scribo/sandbox/arthur/xml_transform/main.cc
index 34a1b6e..2270d2e 100644
--- a/scribo/sandbox/arthur/xml_transform/main.cc
+++ b/scribo/sandbox/arthur/xml_transform/main.cc
@@ -1,5 +1,7 @@
#include <iostream>
-#include <QDomDocument>
+#include <string>
+#include <string>
+#include <cstdlib>
#include "xml_transform.hh"
int main(int argc, char **argv)
@@ -8,60 +10,109 @@ int main(int argc, char **argv)
std::string man;
man = "xml_transform\n"
"OPTIONS:\n\n"
+
"HTML output:\n"
- "\t--html <xml> <ppm> <out_dir> : HTML output with non-text
regions cropped into many png files.\n"
- "\t--html-base64 <xml> <out_dir> : HTML output from a container XML
file.\n\n"
+ "\t\033[01m--html\033[00m\033[00m \033[04minput.xml\033[00m
\033[04mimage\033[00m \033[04moutput.html\033[00m"
+ "\t\t\tCreates HTML file, images are embedded inside in base 64 format.\n"
+ "\t\033[01m--html-base64\033[00m \033[04minput.xml\033[00m
\033[04moutput.html\033[00m"
+ "\t\t\tSame as --html but input is a XML file with images encoded in base 64
inside.\n"
+
+ "\t\033[01m--html-full\033[00m \033[04minput.xml\033[00m \033[04mimage\033[00m
\033[04moutput_dir\033[00m"
+ "\t\t\tCreates HTML file without converting images in base 64. Images + HTML
file are placed in output_dir.\n\n"
+
"PDF output:\n"
- "\t--pdf <xml> <ppm> <out_dir> : PDF output with non-text
regions cropped into many png files.\n"
- "\t--pdf-no-crop <xml> <ppm> <out_dir>: PDF output with the
entire picture displayed over the text.\n"
- "\t--pdf-base64 <xml> <out_dir> : PDF output from a container XML
file.\n"
- "\t--pdf-base64-no-crop <xml> <ppm> <out_dir> : PDF with the
entire picture displayed over the text, the picture is loaded from a container XML
file.\n\n"
- "SVG output:\n"
- "\t--svg <xml> <out_dir> : SVG output (works only with base 64 xml
encoded.\n\n"
- "Base 64 operations:\n"
- "\t--to-base64 <xml> <ppm> <out_xml> : Produces a container
XML file by converting cropped pictures into base 64 format.\n\n"
+ "\t\033[01m--pdf\033[00m \033[04minput.xml\033[00m \033[04mimage\033[00m
\033[04moutput.pdf\033[00m"
+ "\t\t\tCreates PDF file, images are embedded inside in base 64 format.\n"
+ "\t\033[01m--pdf-base64\033[00m \033[04minput.xml\033[00m
\033[04moutput.pdf\033[00m"
+ "\t\t\tSame as --pdf but input is a XML file with images encoded in base 64
inside.\n\n"
+
+ "SVG output (experimental, may not work with all files):\n"
+ "\t\033[01m--svg\033[00m \033[04minput.xml\033[00m \033[04mimage\033[00m
\033[04moutput.svg\033[00m"
+ "\t\t\tCreates SVG file, images are embedded inside in base 64 format.\n"
+ "\t\033[01m--svg-base64\033[00m \033[04minput.xml\033[00m
\033[04moutput.svg\033[00m"
+ "\t\t\tSame as --svg but input is a XML file with images encoded in base 64
inside.\n\n"
"OpenDocument output:\n"
- "\t--open <xml> <ppm> <out_dir> : OpenDocument output (odt,
odf).\n\n"
+ "\t\033[01m--oo-doc\033[00m \033[04minput.xml\033[00m \033[04mimage\033[00m
\033[04moutput.odt\033[00m"
+ "\t\t\tCreates Open Document Writer (odt) file.\n\n"
+
"Base 64 operations:\n"
- "\t--to-base64 <xml> <ppm> <out_xml> : Produces a container
XML file by converting cropped pictures into base 64 format.\n"
- "\t--to-base64-no-crop <xml> <ppm> <out_xml> : Same as
to-base64 but only the picture is converted in base 64.\n"
- "\t--from-base64 <xml> <out_dir> : Decodes a XML container file to
produce original image files.\n\n"
- "For PDF/HTML/SVG/OD output, Bourne shell scripts are provided to produce the
outputs, just run sh *_generator.sh \n"
+ "\t\033[01m--to-base64\033[00m \033[04minput.xml\033[00m \033[04mimage\033[00m
\033[04moutput.xml\033[00m"
+ "\t\t\tCreates a container XML file. It will contain regions which are cropped
and converted in base 64.\n"
+
+ "\t\033[01m--to-base64-no-crop\033[00m \033[04minput.xml\033[00m
\033[04image\033[00m \033[04moutput.xml\033[00m"
+ "\t\tSame as --to-base64 but only the full picture will be converted, regions
are not cropped\n"
+
+ "\t\033[01m--from-base64\033[00m \033[04minput.xml\033[00m
\033[04moutput_dir\033[00m"
+ "\t\t\tDecodes a XML file which has been encoded in base 64, regions will be
converted into png files and saved in output_dir.\n\n"
+
"Requirements:\n"
"PDF : fop >= 0.95\n"
"HTML : xsltproc\n"
"SVG : trunk version of fop\n"
- "OpenDocument : ooconvert";
-
+ "OpenDocument : ooconvert (included)";
if (argc > 4)
{
std::string html = "--html";
- std::string open = "--open";
+ std::string html_full = "--html-full";
+ std::string open = "--oo-doc";
std::string pdf = "--pdf";
- std::string pdf_no_crop = "--pdf-no-crop";
+ std::string svg = "--svg";
std::string to_base64 = "--to-base64";
std::string to_base64nocrop = "--to-base64-no-crop";
- if (html.compare(argv[1]) == 0)
+ if (html_full.compare(argv[1]) == 0)
{
XmlTransform xmlt(argv[2], argv[3], argv[4]);
xmlt.createHTML(false);
+
+ QString cmd = "sh templates/xml_transform.sh html " + xmlt.out() +
"output.xml " + xmlt.out() + "output.html";
+ return system (cmd.toAscii().constData());
+ }
+ else if (html.compare(argv[1]) == 0)
+ {
+ QTemporaryFile tmp;
+ tmp.open();
+ tmp.fileName();
+
+ XmlTransform xmlt(argv[2], argv[3], QString::Null(), tmp.fileName());
+ xmlt.toBase64(false);
+
+ QString cmd = "sh templates/xml_transform.sh html-base64 " + tmp.fileName()
+ " " + argv[4];
+ return system (cmd.toAscii().constData());
}
else if (pdf.compare(argv[1]) == 0)
{
- XmlTransform xmlt(argv[2], argv[3], argv[4]);
- xmlt.createPDF(true, false);
+ QTemporaryFile tmp;
+ tmp.open();
+ tmp.fileName();
+
+ XmlTransform xmlt(argv[2], argv[3], QString::Null(), tmp.fileName());
+ xmlt.toBase64(false);
+
+ QString cmd = "sh templates/xml_transform.sh pdf " + tmp.fileName() + "
" + argv[4];
+ return system (cmd.toAscii().constData());
}
- else if (open.compare(argv[1]) == 0)
+ else if (svg.compare(argv[1]) == 0)
{
- XmlTransform xmlt(argv[2], argv[3], argv[4]);
- xmlt.createOpen();
+ QTemporaryFile tmp;
+ tmp.open();
+ tmp.fileName();
+
+ XmlTransform xmlt(argv[2], argv[3], QString::Null(), tmp.fileName());
+ xmlt.toBase64(false);
+
+ QString cmd = "sh templates/xml_transform.sh svg " + tmp.fileName() + "
" + argv[4];
+ return system (cmd.toAscii().constData());
}
- else if (pdf_no_crop.compare(argv[1]) == 0)
+ else if (open.compare(argv[1]) == 0)
{
- XmlTransform xmlt(argv[2], argv[3], argv[4]);
- xmlt.createPDF(false, false);
+ QString dir = QDir::tempPath() + "/xml_transform." + argv[4];
+ XmlTransform xmlt(argv[2], argv[3], dir);
+ xmlt.createOpen();
+
+ QString cmd = "sh templates/xml_transform.sh oo-doc " + dir + " "
+ argv[4];
+ return system (cmd.toAscii().constData());
}
else if (to_base64.compare(argv[1]) == 0)
{
@@ -78,31 +129,25 @@ int main(int argc, char **argv)
}
else if (argc > 3)
{
- std::string pdfbase64 = "--pdf-base64";
- std::string svg = "--svg";
- std::string pdfbase64nocrop = "--pdf-base64-no-crop";
- std::string htmlbase64 = "--html-base64";
+ std::string pdf_base64 = "--pdf-base64";
+ std::string svg_base64 = "--svg-base64";
+ std::string html_base64 = "--html-base64";
std::string from_base64 = "--from-base64";
- if (pdfbase64.compare(argv[1]) == 0)
- {
- XmlTransform xmlt(argv[2], QString::Null(), argv[3]);
- xmlt.createPDF(true, true);
- }
- else if (svg.compare(argv[1]) == 0)
+ if (svg_base64.compare(argv[1]) == 0)
{
- XmlTransform xmlt(argv[2], QString::Null(), argv[3]);
- xmlt.createSVG();
+ QString cmd = "sh templates/xml_transform.sh svg " + QString(argv[2]) +
" " + QString(argv[3]);
+ return system (cmd.toAscii().constData());
}
- else if (pdfbase64nocrop.compare(argv[1]) == 0)
+ else if (pdf_base64.compare(argv[1]) == 0)
{
- XmlTransform xmlt(argv[2], QString::Null(), argv[3]);
- xmlt.createPDF(false, true);
+ QString cmd = "sh templates/xml_transform.sh pdf " + QString(argv[2]) +
" " + QString(argv[3]);
+ return system (cmd.toAscii().constData());
}
- else if (htmlbase64.compare(argv[1]) == 0)
+ else if (html_base64.compare(argv[1]) == 0)
{
- XmlTransform xmlt(argv[2], QString::Null(), argv[3]);
- xmlt.createHTML(true);
+ QString cmd = "sh templates/xml_transform.sh html-base64 " +
QString(argv[2]) + " " + QString(argv[3]);
+ return system (cmd.toAscii().constData());
}
else if (from_base64.compare(argv[1]) == 0)
{
diff --git a/scribo/sandbox/arthur/xml_transform/templates/html/html_generator.sh
b/scribo/sandbox/arthur/xml_transform/templates/html/html_generator.sh
deleted file mode 100644
index bb24305..0000000
--- a/scribo/sandbox/arthur/xml_transform/templates/html/html_generator.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-xsltproc xsl.xsl output.xml > output.html
\ No newline at end of file
diff --git a/scribo/sandbox/arthur/xml_transform/templates/html/xsl.xsl
b/scribo/sandbox/arthur/xml_transform/templates/html/main.xsl
similarity index 89%
rename from scribo/sandbox/arthur/xml_transform/templates/html/xsl.xsl
rename to scribo/sandbox/arthur/xml_transform/templates/html/main.xsl
index 1f29044..9c90970 100644
--- a/scribo/sandbox/arthur/xml_transform/templates/html/xsl.xsl
+++ b/scribo/sandbox/arthur/xml_transform/templates/html/main.xsl
@@ -6,7 +6,37 @@
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" />
<title>SCRIBO</title>
- <link rel="stylesheet" type="text/css" href="css.css"
/>
+ <style type="text/css">
+ .line
+ {
+ position:absolute;
+ z-index:7;
+ display:inline;
+ white-space:pre;
+
+ <!-- FIXME -->
+ letter-spacing:-2px;
+
+ padding:0px;
+ margin:0px;
+ font-family:"Times New Roman", Times, serif;
+ }
+ .para
+ {
+ position:absolute;
+ z-index:6;
+ }
+ .region
+ {
+ position:absolute;
+ z-index:5;
+ }
+ .image
+ {
+ position:absolute;
+ border:0;
+ }
+ </style>
</head>
<body>
@@ -129,10 +159,8 @@
</xsl:choose>
</xsl:variable>
- <div class="line"
onmouseover="this.style.opacity=0.2;this.filters.alpha.opacity=20"
- onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100">
+ <div class="line">
<xsl:attribute name="style">
- opacity:1;
height:auto;
font-size:<xsl:value-of select="$a+$d" />px;
width:<xsl:value-of select="$x2 - $x1" />px;
@@ -146,7 +174,7 @@
<!-- ENF OF TEXT LINE -->
<!-- TEXT REGION -->
- <xsl:if test="name() = 'text_region'">
+<!-- <xsl:if test="name() = 'text_region'">
<div class="region">
<xsl:attribute name="style">
height:<xsl:value-of select="$y2 - $y1" />px;
@@ -155,11 +183,11 @@
top:<xsl:value-of select="$y1" />px;
</xsl:attribute>
</div>
- </xsl:if>
+ </xsl:if>-->
<!-- ENF OF TEXT REGION -->
<!-- PARAGRAPH -->
- <xsl:if test="name() = 'paragraph'">
+<!-- <xsl:if test="name() = 'paragraph'">
<div class="para">
<xsl:attribute name="style">
height:<xsl:value-of select="$y2 - $y1" />px;
@@ -168,7 +196,7 @@
top:<xsl:value-of select="$y1" />px;
</xsl:attribute>
</div>
- </xsl:if>
+ </xsl:if>-->
<!-- ENF OF PARAGRAPH -->
<!-- NON-TEXT REGIONS -->
@@ -209,7 +237,7 @@
<xsl:attribute name="height">
<xsl:value-of select="$y2 - $y1" />
</xsl:attribute>
- <xsl:attribute name="src">img/<xsl:value-of
select="$id"/>.png</xsl:attribute>
+ <xsl:attribute name="src"><xsl:value-of
select="$id"/>.png</xsl:attribute>
</img>
</div>
diff --git a/scribo/sandbox/arthur/xml_transform/templates/html/xsl_base64.xsl
b/scribo/sandbox/arthur/xml_transform/templates/html/main_base64.xsl
similarity index 75%
rename from scribo/sandbox/arthur/xml_transform/templates/html/xsl_base64.xsl
rename to scribo/sandbox/arthur/xml_transform/templates/html/main_base64.xsl
index 1c25e42..b24f02d 100644
--- a/scribo/sandbox/arthur/xml_transform/templates/html/xsl_base64.xsl
+++ b/scribo/sandbox/arthur/xml_transform/templates/html/main_base64.xsl
@@ -6,7 +6,40 @@
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" />
<title>SCRIBO</title>
- <link rel="stylesheet" type="text/css" href="css.css"
/>
+ <style type="text/css">
+ .line
+ {
+ position:absolute;
+ background-color:white;
+ z-index:7;
+ display:inline;
+ white-space:pre;
+
+ /* FIXME */
+ letter-spacing:-2px;
+
+ padding:0px;
+ margin:0px;
+ filter:alpha(opacity=100);
+ font-family:"Times New Roman", Times, serif;
+ }
+ .para
+ {
+ position:absolute;
+ z-index:6;
+ }
+ .region
+ {
+ position:absolute;
+ z-index:5;
+ }
+ .image
+ {
+ position:absolute;
+ border:0;
+ }
+ </style>
+<!-- <link rel="stylesheet" type="text/css"
href="css.css" /> -->
</head>
<body>
@@ -174,46 +207,48 @@
<!-- NON-TEXT REGIONS -->
<xsl:if test="name() = 'image_region' or name() =
'separator_region' or name() = 'graphic_region' or name() =
'chart_region' or name() = 'table_region'">
- <!-- data -->
- <xsl:variable name="data">
- <xsl:value-of select="container/data" />
- </xsl:variable>
+ <xsl:if test="container">
+ <!-- data -->
+ <xsl:variable name="data">
+ <xsl:value-of select="container/data" />
+ </xsl:variable>
- <!-- depth -->
- <xsl:variable name="depth">
- <xsl:choose>
- <xsl:when test="name() = 'separator_region'">
- 1
- </xsl:when>
- <xsl:otherwise>
- 4
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
+ <!-- depth -->
+ <xsl:variable name="depth">
+ <xsl:choose>
+ <xsl:when test="name() = 'separator_region'">
+ 1
+ </xsl:when>
+ <xsl:otherwise>
+ 4
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
- <div class="image">
- <xsl:attribute name="style">
- top:<xsl:value-of select="$y1" />px;
- left:<xsl:value-of select="$x1" />px;
- width:<xsl:value-of select="$x2 - $x1"/>px;
- height:<xsl:value-of select="$y2 - $y1"/>px;
- z-index:<xsl:value-of select="$depth"/>;
- </xsl:attribute>
- <img>
- <xsl:attribute name="alt">
- <xsl:value-of select="name()" />
+ <div class="image">
+ <xsl:attribute name="style">
+ top:<xsl:value-of select="$y1" />px;
+ left:<xsl:value-of select="$x1" />px;
+ width:<xsl:value-of select="$x2 - $x1"/>px;
+ height:<xsl:value-of select="$y2 - $y1"/>px;
+ z-index:<xsl:value-of select="$depth"/>;
</xsl:attribute>
- <xsl:attribute name="width">
- <xsl:value-of select="$x2 - $x1" />
- </xsl:attribute>
- <xsl:attribute name="height">
- <xsl:value-of select="$y2 - $y1" />
- </xsl:attribute>
- <xsl:attribute name="src">
- data:image/png;base64,<xsl:value-of select="$data"/>
- </xsl:attribute>
- </img>
- </div>
+ <img>
+ <xsl:attribute name="alt">
+ <xsl:value-of select="name()" />
+ </xsl:attribute>
+ <xsl:attribute name="width">
+ <xsl:value-of select="$x2 - $x1" />
+ </xsl:attribute>
+ <xsl:attribute name="height">
+ <xsl:value-of select="$y2 - $y1" />
+ </xsl:attribute>
+ <xsl:attribute name="src">
+ data:image/png;base64,<xsl:value-of select="$data"/>
+ </xsl:attribute>
+ </img>
+ </div>
+ </xsl:if>
</xsl:if>
<!-- END NON-TEXT REGIONS -->
diff --git a/scribo/sandbox/arthur/xml_transform/templates/ooconvert
b/scribo/sandbox/arthur/xml_transform/templates/ooconvert
new file mode 100755
index 0000000..6c81550
--- /dev/null
+++ b/scribo/sandbox/arthur/xml_transform/templates/ooconvert
@@ -0,0 +1,517 @@
+#!/bin/bash
+
+# ooconvert: convert openoffice documents to other formats
+# Copyright (C) 2007, Metaladder, Inc.
+
+# Developers:
+#
+# Nathan Coulter
+# Andrey Plotnikov
+#
+# 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 2
+# of the License, or (at your option) 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+##############################################################################
+##############################################################################
+# This script should be run with the same python interpreter that openoffice
+# uses, which is usually included with openoffice:
+#
+# /path/to/openoffice-2.0.1/program/python.sh
+#
+# However, under debian, ubuntu, etc, openoffice uses the system-installed
+# python interpreter. To find which interpreter is being used, look in
+#
+# /path/to/openoffice/program/pythonloader.unorc
+#
+# If openoffice is using an external python interpreter, modify the following
+# LD_LIBRARY_PATH to reflect your openoffice environment and to import uno
+# without errors
+
+
+# If $DISPLAY does not point to a working X server, or is unset, this program
+# tries to start Xvfb. Bypass all this nonsense by having DISPLAY point to a
+# working X Server.
+#
+#
+# NOTE! - If OpenOffice has never been started interactively, this program will
+# fail silently because the license agreement has not been accepted.
+
+##############################################################################
+##############################################################################
+
+shopt -s -o nounset
+
+### site configuration
+#OO_LOGLEVEL=20
+#USE_OO_INTERNAL_PYTHON=0 #set to 1 if python is embedded in openoffice
+#OOPROGRAM=/usr/lib/openoffice/program #directory containing soffice
+#OOPYTHON=${OOPROGRAM}/python.sh"
+#OO_EXTERNAL_PYTHON=/usr/bin/python
+#OOXVFB="Xvfb"
+#OOXWININFO=xwininfo
+#OOXVFB_START=0} #first port to try Xvfb on
+#OOXVFB_RETRIES:="1000"} #how many successive port to try
+#alternatively, put site details in one of these files
+[ -r /etc/ooconvert ] && source /etc/ooconvert
+[ -r ~/etc/ooconvert ] && source ~/etc/ooconvert
+### site configuration end
+
+### configuration defaults start
+# Choose openoffice internal python (1) or external python (0)
+: ${OO_LOGLEVEL:=20}
+: ${USE_OO_INTERNAL_PYTHON:=0}
+: ${OOPROGRAM:="/usr/lib/openoffice/program"}
+: ${OOPYTHON:="${OOPROGRAM}/python.sh"}
+: ${OO_EXTERNAL_PYTHON:="/usr/bin/python"}
+: ${OOXVFB:="Xvfb"}
+: ${OOXWININFO:="xwininfo"}
+: ${OOXVFB_START:=0}
+: ${OOXVFB_RETRIES:="100"}
+### configuration defaults end
+
+LOG_NOTSET=0
+LOG_DEBUG=10
+LOG_INFO=20
+LOG_WARNING=30
+LOG_ERROR=40
+LOG_CRITICAL=50
+
+OOXVFBJOB=
+
+oo_log () {
+ if [ "$OO_LOGLEVEL" -le "$1" ]; then
+ shift
+ printf '%s\n' "$@" >&2
+ fi
+}
+
+oo_err () {
+ exit_status="$1"
+ shift
+ oo_log $LOG_ERROR "$@"
+ exit "$exit_status"
+}
+
+### If an X Server is not detected, try to use Xvfb
+if [ ! "${DISPLAY:-}" ]; then
+ oo_log $LOG_INFO "\"DISPLAY\" variable is not set. Attempting
Xvfb."
+ for i in "$OOXVFB" /usr/X11/bin/Xvfb /usr/X11R6/bin/Xvfb; do
+ oo_log "$LOG_INFO" "Trying to invoke $i"
+ $i >& /dev/null
+ if [ $? != 127 ]; then #127 is the bash shell code for "not found"
+ OOXVFB="$i"
+ break
+ fi
+ OOXVFB=
+ done
+ unset i
+ if [ "$OOXVFB" ]; then
+ oo_log $LOG_INFO "Xvfb is installed."
+ for i in "$OOXWININFO" /usr/X11/bin/xwininfo \
+ /usr/X11R6/bin/xwininfo "$(dirname "$OOXVFB")/xwininfo"
+ do
+ $i >& /dev/null
+ if [ $? != 127 ]; then #127 is the bash shell code for "not found"
+ OOXWININFO="$i"
+ break
+ fi
+ OOXWININFO=
+ done
+ [ "$OOXWININFO" ] || oo_err 130 "ooxwininfo not found"
+ unset i
+ ((last=$OOXVFB_START+$OOXVFB_RETRIES))
+ while :; do
+ "$OOXVFB" :$OOXVFB_START -screen scrn 1280x1024x16 &
+ OOXVFBJOB=$!
+ export DISPLAY=":$OOXVFB_START"
+ sleep 1
+ ps "$OOXVFBJOB" && "$OOXWININFO" -root &&
break
+ ps "$OOXVFBJOB" && kill "$OOXVFBJOB"
+ oo_log $LOG_INFO "Failed to start Xvfb on display $OOXVFB_START"
+ ((OOXVFB_START++))
+ [ $OOXVFB_START -ge $last ] && \
+ oo_err 129 "Xvfb attempts exceeded $OOXVFB_RETRIES"
+ done
+ oo_log $LOG_INFO "Xvfb started. Process id: $OOXVFBJOB"
+ oo_log $LOG_INFO "Setting \"Display\" to $DISPLAY for Xvfb"
+ fi
+fi
+
+case "$USE_OO_INTERNAL_PYTHON" in
+ 0)
+ OOPYTHON="$OO_EXTERNAL_PYTHON"
+ export
LD_LIBRARY_PATH="$OOPROGRAM${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
+ ;;
+esac
+
+
+"$OOPYTHON" - "$@" <<EOF
+# OpenOffice1.1 comes with its own python interpreter.
+# This Script needs to be run with the python from
OpenOffice.org:
+# /opt/OpenOffice.org/program/python or python.sh
+
+#pythonloader.unorc
+
+__doc__="Document converter which uses OO for actual converting"
+
+import sys, os, time, signal
+from optparse import OptionParser
+
+#how long should we wait for openoffice to start
+OOCONV_MAX_STARTUP_TIME = os.getenv("OOCONV_MAX_STARTUP_TIME")
+if not OOCONV_MAX_STARTUP_TIME: OOCONV_MAX_STARTUP_TIME=60
+OOCONV_MAX_STARTUP_TIME=int(OOCONV_MAX_STARTUP_TIME)
+
+#what port should openoffice listen on
+OOCONV_PORT = os.getenv("OOCONV_PORT")
+if not OOCONV_PORT: OOCONV_PORT=2002
+OOCONV_PORT = int(OOCONV_PORT)
+
+def importUNO():
+ """
+ Import UNO modules
+ """
+ import uno
+ globals()['uno'] = uno
+ from com.sun.star.beans import PropertyValue
+ globals()['PropertyValue'] = PropertyValue
+ from com.sun.star.container import NoSuchElementException
+ globals()['NoSuchElementException'] = NoSuchElementException
+
+
+class OOConverter:
+ """
+ Convert documents by means of Open Office.
+ """
+
+ def __init__(self, desktop):
+ self.desktop = desktop
+
+ def convert(self, fromFile, toFile, format):
+ """
+ fromFile -- source file name
+ toFile -- destination file name
+ format -- sequence of propery values
+ """
+ desktop = self.desktop
+ fromFile=os.path.abspath(fromFile)
+ url = fromFile
+ #url="file://%s" % fromFile
+ url=uno.systemPathToFileUrl(fromFile)
+ context = uno.getComponentContext()
+ properties=[]
+ p=PropertyValue()
+ p.Name="Hidden"
+ p.Value=True
+ properties.append(p)
+ doc=desktop.loadComponentFromURL(
+ url, "_blank", 0, tuple(properties));
+ if not doc:
+ print "Failed to open '%s'" % type(file)
+ return False
+ # Save File
+ properties=[]
+ p=PropertyValue()
+ p.Name="Overwrite"
+ p.Value=True
+ properties.append(p)
+ p=PropertyValue()
+ p.Name="FilterName"
+ p.Value=property(format, 'Name').Value
+ properties.append(p)
+ p=PropertyValue()
+ p.Name="Hidden"
+ p.Value=True
+ url_save="file://%s" % os.path.abspath(toFile)
+ try:
+ doc.storeToURL(
+ url_save, tuple(properties))
+ except:
+ print "Failed while writing: '%s'" % file
+ doc.dispose()
+ return True
+
+
+
+class FileIterator:
+ """
+ Iterate over each conversion task.
+ A conversion task consists of source file name,
+ destination file name and format
+ """
+ def __init__(self, sources, dest, format, ext, keep):
+ self.sources = sources
+ self.dest = dest
+ if not ext: ext = ''
+ self.ext = ext
+ self.keep = keep
+ self.isDestDir = False
+ if os.path.isdir(dest):
+ self.isDestDir = True
+ self.format = format
+ self.siter = iter(self.sources)
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ src = self.siter.next()
+ return (src, self._getDestFN(src), self.format)
+
+ def _getDestFN(self, src):
+ if not self.isDestDir:
+ return self.dest
+ base = os.path.basename(src)
+ if not self.keep:
+ base, ext = os.path.splitext(base)
+ return os.path.join(self.dest, base) + self.ext
+
+ def _getFormatExt(self):
+ return self.format.ext
+
+
+
+def expandSources(sources):
+ result = []
+ for src in sources:
+ if os.path.isdir(src):
+ result.extend([os.path.join(src,entry) for entry in os.listdir(src) if
os.path.isfile(os.path.join(src,entry))])
+ elif os.path.isfile(src):
+ result.append(src)
+ return result
+
+def property(properties, which, default=None):
+ '''value: property p from a set of properties'''
+ for p in properties:
+ if p.Name == which: return p
+ return default
+
+def format(attribute, value):
+ for fmt in formats()[0]:
+ if value == property(fmt, attribute).Value:
+ return fmt
+
+def formats():
+ resolve = filterFactory.getElementNames()
+ installed = []
+ missing = []
+ for name in resolve:
+ try:
+ installed.append(filterFactory.getByName(name))
+ except NoSuchElementException, e:
+ print >> sys.stderr, 'Warning: NoSuchElementException: ',
+ print >> sys.stderr, e.Message
+ missing.append(name)
+ return iter(installed), iter(missing)
+
+
+def fileformat(fileName):
+ url=uno.systemPathToFileUrl(fileName)
+ type_ = typeDetection.queryTypeByURL(url)
+ fmt = format('Type', type_)
+ return fmt
+
+
+def componentContext():
+ """
+ Start OO in child process and connect to them.
+ Return OO component context object.
+ """
+ pid = os.fork()
+ if not pid:
+ pid = os.getpid()
+ os.setpgid(pid,pid)
+ os.system("soffice -headless -norestore
'-accept=socket,host=localhost,port=%s;urp;' &" % OOCONV_PORT)
+ while 1:
+ time.sleep(1)
+ else:
+ limit = time.time() + OOCONV_MAX_STARTUP_TIME
+ context = None
+ contextproxy = uno.getComponentContext()
+ resolver=contextproxy.ServiceManager.createInstanceWithContext(
+ "com.sun.star.bridge.UnoUrlResolver", contextproxy)
+
+ while time.time() < limit:
+ try:
+ context = resolver.resolve(
+
"uno:socket,host=localhost,port=%s;urp;StarOffice.ComponentContext" %
OOCONV_PORT)
+ break
+ except:
+ pass
+ time.sleep(5)
+ if context is None:
+ pgid = os.getpgid(pid)
+ os.killpg(pgid, signal.SIGTERM)
+ return None, None
+ return context, pid
+
+
+def connect(host='localhost', port=OOCONV_PORT):
+ """
+ Try to connect to the running OO instance
+ """
+ context = uno.getComponentContext()
+ resolver=context.ServiceManager.createInstanceWithContext(
+ "com.sun.star.bridge.UnoUrlResolver", context)
+ try:
+ return resolver.resolve(
+ "uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext" %
(host, port))
+ except:
+ pass
+ return None
+
+def options():
+ usage1 = "usage: $(basename $0) [options] <source file> <destination
file>"
+ usage2 = " or: $(basename $0) --format=<format> [options] sources...
<destination dir>"
+ usage3 = " or: $(basename $0) --list"
+ usage4 = " or: $(basename $0) --help"
+ parser =
OptionParser(usage1+'\n'+usage2+'\n'+usage3+'\n'+usage4)
+ parser.add_option('-e', '--ext', dest='ext',
+ help='Output extension', metavar='ext')
+ parser.add_option('-f','--format', dest='format',
+ help='Output file format', metavar='format')
+ parser.add_option('-k', '--keep', dest='keep',
+ help='Keep original extension', metavar='keep')
+ parser.add_option('-p','--oopath', dest='oopath',
metavar='path',
+ help='Path to OO program directory')
+ parser.add_option('-l','--list', dest='listFormats',
action="store_true",
+ default=False,
+ help='List all available formats')
+ parser.add_option('-a' ,'--laddr', dest='listener',
metavar='host[:port]',
+ help='If this option exists then try to connect to given OO
listener address')
+ return parser
+
+def listFormats():
+ installed, missing = formats()
+ if installed:
+ print '\n\nAvailable formats: '
+ for i in installed:
+ print property(i, 'Name').Value
+ if missing:
+ print '\n\nFormats not currently installed: '
+ for i in missing:
+ print i
+
+def services():
+ smgr=context.ServiceManager
+ globals()['desktop'] = \
+ smgr.createInstanceWithContext("com.sun.star.frame.Desktop",context)
+ globals()['typeDetection'] = \
+ smgr.createInstance('com.sun.star.document.TypeDetection')
+ globals()['filterFactory'] = \
+ smgr.createInstance('com.sun.star.document.FilterFactory')
+
+def opts_format(parser, opts, dest, isDestDir):
+ ## if destination is directory then format option is required
+ if isDestDir:
+ if not opts.format:
+ parser.error('format option is required')
+ return format('Name', opts.format)
+ elif not opts.format:
+ ## try to guess format by the output filename extension
+ format1 = fileformat(dest)
+ if not format1:
+ parser.error("can't guess output format for %s" % dest)
+ else:
+ format1 = format('Name', opts.format)
+ if not format1:
+ err = 'Unknown format: %s. ' % opts.format
+ err += 'Please use --list to see formats'
+ parser.error(err)
+ return format1
+
+
+def main():
+ parser = options()
+ opts, args = parser.parse_args()
+ pid = None
+ try:
+ importUNO()
+ if opts.listener:
+ parts = opts.listener.split(':')
+ host = parts[0]
+ port=OOCONV_PORT
+ if len(parts)>1:
+ port = int(parts[1])
+ context = connect(host, port)
+ else:
+ context, pid = componentContext()
+
+ if context is None:
+ print "Could not connect to running openoffice"
+ sys.exit(1)
+ globals()['context'] = context
+
+ services()
+
+ if opts.listFormats:
+ listFormats()
+ sys.exit(0)
+
+ if len(args)<1:
+ parser.error('incorrect number of arguments')
+
+ if len(args) == 1:
+ dest = os.getcwd()
+ sources = [os.path.abspath(args[0])]
+ isDestDir = True
+ else:
+ dest = os.path.abspath(args[-1])
+ sources = [os.path.abspath(src) for src in args[:-1]]
+ isDestDir = os.path.isdir(dest)
+ ## if we have more than one input files then last argument must be output
directory
+ if len(args) > 2 and not isDestDir:
+ parser.error('last argument must be directory')
+ if not isDestDir and len(args)==2:
+ src = sources[0]
+ if not os.path.isfile(src):
+ parser.error('first argument must be a path to the file in this
case')
+
+ format1 = opts_format(parser, opts, dest, isDestDir)
+
+ if opts.oopath:
+ os.environ['PATH'] = '%s:%s' % (os.environ['PATH'],
opts.oopath)
+ sys.path.append(opts.oopath)
+
+ sources = expandSources(sources)
+
+ converter = OOConverter(desktop)
+ iterator = FileIterator(sources, dest, format1, opts.ext, opts.keep)
+ for fromFile, toFile, format1 in iterator:
+ print 'Converting %s to %s (format: %s)...' % (
+ os.path.basename(fromFile),
+ os.path.basename(toFile),
+ property(format1, 'Name').Value),
+ converter.convert(fromFile, toFile, format1)
+ print 'successfully.'
+ finally:
+ if pid:
+ pgid = os.getpgid(pid)
+ os.killpg(pgid, signal.SIGTERM)
+ time.sleep(2)
+ os.killpg(pgid, signal.SIGKILL)
+
+
+if __name__ == '__main__':
+ main()
+
+EOF
+
+if [ "$OOXVFBJOB" ]; then
+ oo_log $LOG_INFO "Killing Xvfb, running as process number $OOXVFBJOB"
+ kill "$OOXVFBJOB"
+ #necessary when process is headless
+ kill -s 9 $OOXVFBJOB
+ rm -f /tmp/.X$OOXVFB_START-lock
+fi
diff --git a/scribo/sandbox/arthur/xml_transform/templates/opendoc/opendoc_generator.sh
b/scribo/sandbox/arthur/xml_transform/templates/opendoc/opendoc_generator.sh
deleted file mode 100755
index c2d9e6f..0000000
--- a/scribo/sandbox/arthur/xml_transform/templates/opendoc/opendoc_generator.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-if [ -z "$1" ]
-then
- echo "opendoc_generator <odt|odf>";
-else
- if [ "$1" == "odt" ]
- then
- echo "saving to output.odt";
- xsltproc xsl.xsl output.xml > output.html
- ooconvert output.html output.odt
- rm output.html
- elif [ "$1" == "odf" ]
- then
- echo "saving to output.odf";
- xsltproc xsl.xsl output.xml > output.html
- ooconvert output.html output.odf;
- rm output.html
- else
- echo "opendoc_generator <odt|odf>";
- fi
-fi
-
-#rm output.html
\ No newline at end of file
diff --git a/scribo/sandbox/arthur/xml_transform/templates/opendoc/xsl.xsl
b/scribo/sandbox/arthur/xml_transform/templates/opendoc/xsl.xsl
index bf1cc30..e9266d7 100755
--- a/scribo/sandbox/arthur/xml_transform/templates/opendoc/xsl.xsl
+++ b/scribo/sandbox/arthur/xml_transform/templates/opendoc/xsl.xsl
@@ -6,7 +6,38 @@
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" />
<title>SCRIBO</title>
- <link rel="stylesheet" type="text/css" href="css.css"
/>
+ <style type="text/css">
+ .line
+ {
+ position:absolute;
+ z-index:7;
+ display:inline;
+ white-space:pre;
+
+ /* FIXME */
+ letter-spacing:-2px;
+
+ padding:0px;
+ margin:0px;
+ filter:alpha(opacity=100);
+ font-family:"Times New Roman", Times, serif;
+ }
+ .para
+ {
+ position:absolute;
+ z-index:6;
+ }
+ .region
+ {
+ position:absolute;
+ z-index:5;
+ }
+ .image
+ {
+ position:absolute;
+ border:0;
+ }
+ </style>
</head>
<body>
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/main.xsl
b/scribo/sandbox/arthur/xml_transform/templates/pdf/main.xsl
index 065831e..0dbb673 100644
--- a/scribo/sandbox/arthur/xml_transform/templates/pdf/main.xsl
+++ b/scribo/sandbox/arthur/xml_transform/templates/pdf/main.xsl
@@ -4,6 +4,7 @@
<!-- FILE: main.xsl
DESCRIPTION: produce pdf output -->
+ <xsl:import href="regions.xsl"/>
<xsl:import href="line.xsl"/>
<xsl:template match="/">
@@ -31,28 +32,7 @@
<fo:page-sequence master-reference="page">
<fo:flow flow-name="xsl-region-body">
-
<xsl:apply-imports />
-
- <fo:block-container position="absolute" z-index="-3">
-
- <xsl:attribute name="left">
- 0px
- </xsl:attribute>
- <xsl:attribute name="top">
- 0px
- </xsl:attribute>
-
- <fo:block>
- <fo:external-graphic>
- <xsl:attribute name="src">
- url('img/image.png')
- </xsl:attribute>
- </fo:external-graphic>
- </fo:block>
-
- </fo:block-container>
-
</fo:flow>
</fo:page-sequence>
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/main64.xsl
b/scribo/sandbox/arthur/xml_transform/templates/pdf/main64.xsl
deleted file mode 100644
index ecc7443..0000000
--- a/scribo/sandbox/arthur/xml_transform/templates/pdf/main64.xsl
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
-
- <!-- FILE: main.xsl
- DESCRIPTION: produce pdf output -->
-
- <xsl:import href="line.xsl"/>
-
- <xsl:template match="/">
- <fo:root>
-
- <fo:layout-master-set>
- <fo:simple-page-master master-name="page" margin-left="0cm"
margin-right="0cm" margin-bottom="0cm" margin-top="0cm">
-
- <!-- Output will be sized with image size -->
- <xsl:attribute name="page-width">
- <xsl:value-of select="pcGts/page/@image_width" />px
- </xsl:attribute>
- <xsl:attribute name="page-height">
- <xsl:value-of select="pcGts/page/@image_height" />px
- </xsl:attribute>
-
- <fo:region-body
- margin-top="0mm" margin-bottom="0mm"
- margin-left="0mm" margin-right="0mm"/>
- <fo:region-after extent="0mm"/>
-
- </fo:simple-page-master>
- </fo:layout-master-set>
-
- <fo:page-sequence master-reference="page">
-
- <fo:flow flow-name="xsl-region-body">
-
- <xsl:apply-imports />
-
- <fo:block-container position="absolute" z-index="-3">
-
- <xsl:attribute name="left">
- 0px
- </xsl:attribute>
- <xsl:attribute name="top">
- 0px
- </xsl:attribute>
-
- <fo:block>
- <fo:external-graphic>
- <xsl:attribute name="src">
- data:image/png;base64,<xsl:value-of
select="pcGts/page/image_region/container/data" />
- </xsl:attribute>
- </fo:external-graphic>
- </fo:block>
-
- </fo:block-container>
-
- </fo:flow>
-
- </fo:page-sequence>
- </fo:root>
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/pdf_generator.sh
b/scribo/sandbox/arthur/xml_transform/templates/pdf/pdf_generator.sh
deleted file mode 100644
index c6339a5..0000000
--- a/scribo/sandbox/arthur/xml_transform/templates/pdf/pdf_generator.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-fop -xsl main.xsl -xml output.xml -pdf output.pdf
\ No newline at end of file
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/regions_base64.xsl
b/scribo/sandbox/arthur/xml_transform/templates/pdf/regions.xsl
similarity index 100%
rename from scribo/sandbox/arthur/xml_transform/templates/pdf/regions_base64.xsl
rename to scribo/sandbox/arthur/xml_transform/templates/pdf/regions.xsl
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/regions_png.xsl
b/scribo/sandbox/arthur/xml_transform/templates/pdf/regions_png.xsl
deleted file mode 100644
index 65a8c79..0000000
--- a/scribo/sandbox/arthur/xml_transform/templates/pdf/regions_png.xsl
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
-
- <!-- FILE: regions.xsl
- DESCRIPTION: Match all regions that are not text to display them -->
-
- <xsl:template match="pcGts/page/image_region|
- pcGts/page/graphic_region|
- pcGts/page/chart_region|
- pcGts/page/table_region|
- pcGts/page/separator_region">
-
- <!-- ID of the region, used to display id.png -->
- <xsl:variable name="id">
- <xsl:value-of select="@id" />
- </xsl:variable>
-
- <!-- Regions coordinates -->
- <xsl:variable name="y1">
- <xsl:for-each select="coords/point">
- <xsl:sort select="@y" order="ascending"
data-type="number"/>
- <xsl:if test="position() = 1">
- <xsl:value-of select="@y" />
- </xsl:if>
- </xsl:for-each>
- </xsl:variable>
-
- <xsl:variable name="x1">
- <xsl:for-each select="coords/point">
- <xsl:sort select="@x" order="ascending"
data-type="number"/>
- <xsl:if test="position() = 1">
- <xsl:value-of select="@x" />
- </xsl:if>
- </xsl:for-each>
- </xsl:variable>
- <!-- END OF regions coordinates -->
-
- <fo:block-container position="absolute">
-
- <xsl:attribute name="left">
- <xsl:value-of select="$x1" />px
- </xsl:attribute>
- <xsl:attribute name="top">
- <xsl:value-of select="$y1" />px
- </xsl:attribute>
-
- <fo:block>
- <fo:external-graphic>
- <xsl:attribute name="src">
- url('img/<xsl:value-of select="$id" />.png')
- </xsl:attribute>
- </fo:external-graphic>
- </fo:block>
-
- </fo:block-container>
-
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/svg_generator.sh
b/scribo/sandbox/arthur/xml_transform/templates/pdf/svg_generator.sh
deleted file mode 100644
index 0d4907c..0000000
--- a/scribo/sandbox/arthur/xml_transform/templates/pdf/svg_generator.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-fop -xsl main.xsl -xml output.xml -svg output.svg
\ No newline at end of file
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/line.xsl
b/scribo/sandbox/arthur/xml_transform/templates/svg/line.xsl
similarity index 100%
copy from scribo/sandbox/arthur/xml_transform/templates/pdf/line.xsl
copy to scribo/sandbox/arthur/xml_transform/templates/svg/line.xsl
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/main_crop.xsl
b/scribo/sandbox/arthur/xml_transform/templates/svg/main.xsl
similarity index 100%
rename from scribo/sandbox/arthur/xml_transform/templates/pdf/main_crop.xsl
rename to scribo/sandbox/arthur/xml_transform/templates/svg/main.xsl
diff --git a/scribo/sandbox/arthur/xml_transform/templates/pdf/regions_svg.xsl
b/scribo/sandbox/arthur/xml_transform/templates/svg/regions.xsl
similarity index 100%
rename from scribo/sandbox/arthur/xml_transform/templates/pdf/regions_svg.xsl
rename to scribo/sandbox/arthur/xml_transform/templates/svg/regions.xsl
diff --git a/scribo/sandbox/arthur/xml_transform/templates/xml_transform.sh
b/scribo/sandbox/arthur/xml_transform/templates/xml_transform.sh
new file mode 100755
index 0000000..05e9569
--- /dev/null
+++ b/scribo/sandbox/arthur/xml_transform/templates/xml_transform.sh
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+SRC_DIR=`dirname $0`;
+
+if [ -z "$1" ]
+then
+ echo "Please give an output type !"
+else
+ if [ -z "$2" ]
+ then
+ echo "Please give input XML file !"
+ else
+
+# HTML
+ if [ "$1" = "html" ]
+ then
+ which xsltproc > /dev/null;
+ if [ $? -eq 0 ]
+ then
+ out="$3";
+ if [ -z "$out" ]
+ then
+ out="output.html"
+ fi
+ out=`readlink -f $out`
+
+ echo "HTML output : $out"
+ xsltproc "$SRC_DIR/html/main.xsl" "$2" > "$out"
+
+ rm -f $2;
+ fi
+# HTML BASE 64
+ elif [ "$1" = "html-base64" ]
+ then
+ which xsltproc > /dev/null;
+ if [ $? -eq 0 ]
+ then
+ out="$3";
+ if [ -z "$out" ]
+ then
+ out="output.html"
+ fi
+ out=`readlink -f $out`
+
+ echo "HTML output : $out"
+ xsltproc "$SRC_DIR/html/main_base64.xsl" "$2" >
"$out"
+ fi
+
+# PDF/SVG
+ elif [ -n "`echo $1 | grep -E 'pdf(\-base64)?|svg'`" ]
+ then
+ which fop > /dev/null;
+ if [ $? -eq 0 ]
+ then
+ out="$3";
+
+# PDF
+ if [ "$1" = "pdf" ]
+ then
+ if [ -z "$out" ]
+ then
+ out="output.pdf"
+ fi
+ out=`readlink -f $out`
+
+ echo "PDF output : $out"
+ fop -xsl "$SRC_DIR/pdf/main.xsl" -xml "$2" -pdf
"$out";
+
+# SVG
+ elif [ "$1" = "svg" ]
+ then
+ if [ -z "$out" ]
+ then
+ out="output.svg"
+ fi
+ out=`readlink -f $out`
+
+ echo "SVG output : $out"
+ fop -xsl "$SRC_DIR/svg/main.xsl" -xml "$2" -svg
"$out"
+ else
+ echo "Wrong output format !";
+ fi
+ else
+ echo "fop >= 0.95 required !"
+ fi
+
+# Open Document
+ elif [ "$1" = "oo-doc" ]
+ then
+ which xsltproc > /dev/null;
+ if [ $? -eq 0 ]
+ then
+
+ out="$3";
+ if [ -z "$out" ]
+ then
+ out="output.odt"
+ fi
+ out=`readlink -f $out`
+
+ xsltproc "$SRC_DIR/html/main.xsl" "$2/output.xml" >
"$2/out.html"
+
+ echo "Open Document output : $out"
+ "$SRC_DIR/ooconvert" "$2/out.html" "$2/out.odt" >
/dev/null
+
+ cur_dir=`pwd`;
+ tmp_dir="$2/oo_tmp"
+
+ mkdir $tmp_dir
+ unzip $tmp_dir/../out.odt -d $tmp_dir > /dev/null
+
+ cat $tmp_dir/content.xml | sed -re 's!\.\./([a-zA-Z0-9])!Pictures/\1!g'
>> $tmp_dir/tmp.xml
+
+ mkdir $tmp_dir/Pictures
+
+ mv $2/*.png $tmp_dir/Pictures/
+
+ mv $tmp_dir/tmp.xml $tmp_dir/content.xml
+
+ cd $tmp_dir
+ zip zip.odt -r * > /dev/null
+ cp zip.odt "$out"
+ cd $cur_dir;
+
+ rm -r $2;
+ else
+ echo "xsltproc required !"
+ fi
+
+ else
+ echo "Wrong output format !";
+ fi
+ fi
+fi
\ No newline at end of file
diff --git a/scribo/sandbox/arthur/xml_transform/xml_transform.cc
b/scribo/sandbox/arthur/xml_transform/xml_transform.cc
index 90af5a5..be5a137 100644
--- a/scribo/sandbox/arthur/xml_transform/xml_transform.cc
+++ b/scribo/sandbox/arthur/xml_transform/xml_transform.cc
@@ -39,9 +39,15 @@ XmlTransform::XmlTransform(QString xml_file, QString image_file,
QString output,
QFile fx(xml_file_);
if (file_ != QString::Null())
- output_dir_ = "/tmp/xml_transform";
+ {
+ output_dir_ = QDir::tempPath() + "/xml_transform/";
+ tmp_ = true;
+ }
else
- output_dir_ = output;
+ {
+ tmp_ = false;
+ output_dir_ = output;
+ }
if (output_dir_ != QString::Null() && !loader_->set_output(output_dir_))
{
@@ -68,29 +74,15 @@ XmlTransform::~XmlTransform()
void XmlTransform::fromBase64()
{
- QString output = output_dir_;
- output.append("img");
-
- if (loader_->set_output(output))
- crop_->from_base64();
- else
- abort();
+ crop_->from_base64();
}
-void XmlTransform::toBase64(bool crop)
+void XmlTransform::toBase64(bool nocrop)
{
- QString output = output_dir_;
- output.append("img");
-
- if (loader_->set_output(output))
- {
- if (!crop)
- crop_->crop_regions();
+ if (!nocrop)
+ crop_->crop_regions(tmp_);
- crop_->to_base64(file_, crop);
- }
- else
- abort();
+ crop_->to_base64(file_, nocrop);
}
void XmlTransform::createPDF (bool crop, bool base64)
@@ -99,16 +91,10 @@ void XmlTransform::createPDF (bool crop, bool base64)
{
if (!base64)
{
- QString output = output_dir_;
- output.append("img");
-
- if (loader_->set_output(output))
- {
- if (crop)
- crop_->crop_regions();
- else
- crop_->save_image("image");
- }
+ if (crop)
+ crop_->crop_regions(tmp_);
+ else
+ crop_->save_image(output_dir_ + "image.png");
}
loader_->add_pdf_templates(crop, base64, output_dir_);
@@ -120,18 +106,7 @@ void XmlTransform::createPDF (bool crop, bool base64)
void XmlTransform::createOpen ()
{
if (loader_->xml_output(xml_file_, false, output_dir_))
- {
- QString output = output_dir_;
- output.append("img");
-
- if (loader_->set_output(output))
- {
- crop_->crop_regions();
- loader_->add_open_templates(output_dir_);
- }
- else
- abort();
- }
+ crop_->crop_regions(tmp_);
else
abort();
}
@@ -139,9 +114,7 @@ void XmlTransform::createOpen ()
void XmlTransform::createSVG ()
{
if (loader_->xml_output(xml_file_, false, output_dir_))
- {
- loader_->add_svg_templates(output_dir_);
- }
+ loader_->add_svg_templates(output_dir_);
else
abort();
}
@@ -151,15 +124,8 @@ void XmlTransform::createHTML(bool base64)
if (loader_->xml_output(xml_file_, true, output_dir_))
{
if (!base64)
- {
- QString output = output_dir_;
- output.append("img");
- if (loader_->set_output(output))
- crop_->crop_regions();
- else
- abort();
- }
- loader_->add_html_templates(base64, output_dir_);
+ crop_->crop_regions(tmp_);
+ // loader_->add_html_templates(base64, output_dir_);
}
else
abort();
diff --git a/scribo/sandbox/arthur/xml_transform/xml_transform.hh
b/scribo/sandbox/arthur/xml_transform/xml_transform.hh
index ad83fd5..ee06907 100644
--- a/scribo/sandbox/arthur/xml_transform/xml_transform.hh
+++ b/scribo/sandbox/arthur/xml_transform/xml_transform.hh
@@ -40,6 +40,7 @@ class XmlTransform : public QObject
XmlTransform(QString xml_file, QString image_file, QString output, QString file =
QString::Null());
~XmlTransform();
+ QString out() { return output_dir_; }
void createHTML(bool base64);
void createPDF(bool crop, bool base64);
void createSVG();
@@ -54,6 +55,7 @@ private:
Loader* loader_;
ImageCrop* crop_;
QString file_;
+ bool tmp_;
};
#endif // !XML_TRANFORM_HH
diff --git a/scribo/sandbox/arthur/xml_transform/xml_transform.pro
b/scribo/sandbox/arthur/xml_transform/xml_transform.pro
index c038cf6..608ce64 100644
--- a/scribo/sandbox/arthur/xml_transform/xml_transform.pro
+++ b/scribo/sandbox/arthur/xml_transform/xml_transform.pro
@@ -3,14 +3,14 @@
######################################################################
TEMPLATE = app
-TARGET =
+TARGET =
DEPENDPATH += .
INCLUDEPATH += .
QMAKE_CXXFLAGS += -I/amd/beyrouth/home/lrde/stage/crepin/git/olena/milena
-I/amd/beyrouth/home/lrde/stage/crepin/git/olena/
QT += xml
LIBS += `Magick++-config --libs`
-
-
-# Input
HEADERS += common.hh image_crop.hh loader.hh xml_transform.hh
SOURCES += common.cc image_crop.cc loader.cc main.cc xml_transform.cc
+PWD +=
+
+QMAKE_POST_LINK += cp -r $$PWD/templates $$OUT_PWD
--
1.5.6.5