unihtml/unihtml.go

136 lines
14 KiB
Go
Raw Permalink Normal View History

2021-02-08 19:36:06 +00:00
//
// Copyright 2020 FoxyUtils ehf. All rights reserved.
//
// This is a commercial product and requires a license to operate.
// A trial license can be obtained at https://unidoc.io
//
// DO NOT EDIT: generated by unitwist Go source code obfuscator.
//
// Use of this source code is governed by the UniDoc End User License Agreement
// terms that can be accessed at https://unidoc.io/eula/
// Package unihtml contains a plugin for the UniDoc.
2024-12-22 09:15:36 +00:00
package unihtml ;import (_ee "bytes";_f "context";_a "errors";_ea "fmt";_fde "github.com/unidoc/unihtml/client";_fb "github.com/unidoc/unihtml/content";_eea "github.com/unidoc/unihtml/selector";_g "github.com/unidoc/unihtml/sizes";_eac "github.com/unidoc/unipdf/v3/common";
_fdd "github.com/unidoc/unipdf/v3/common/license";_cb "github.com/unidoc/unipdf/v3/creator";_ed "github.com/unidoc/unipdf/v3/model";_ab "github.com/unidoc/unipdf/v3/render";_b "image";_eg "image/color";_d "math";_e "net/url";_ff "os";_fd "time";);
2021-03-24 00:33:01 +00:00
2024-12-22 09:15:36 +00:00
// Options are the HTML Client options used for establishing the connection.
type Options struct{
2021-03-24 00:33:01 +00:00
2024-12-22 09:15:36 +00:00
// Hostname defines the hostname for the client. Default value: 'localhost'.
Hostname string ;
2022-05-05 21:25:46 +00:00
2024-12-22 09:15:36 +00:00
// Port defines the port at which the server works. Default value: '8080'
Port int ;
2023-02-10 16:57:05 +00:00
2024-12-22 09:15:36 +00:00
// Secure is the flag that states if the connection uses HTTPS protocol. Default Value: 'false'.
Secure bool ;
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// Prefix is an option setting used when the server is working with the URI prefix. Default Value: ''.
Prefix string ;};
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// ConnectOptions creates UniHTML HTTP Client and tries to establish connection with the server.
func ConnectOptions (o Options )error {_dd =_fde .New (_fde .Options {Hostname :o .Hostname ,Port :o .Port ,HTTPS :o .Secure });_ad ,_fe :=_f .WithTimeout (_f .Background (),_fd .Second *5);defer _fe ();if _gb :=_dd .HealthCheck (_ad );_gb !=nil {return _gb ;
};return nil ;};
2023-02-10 16:57:05 +00:00
2024-12-22 09:15:36 +00:00
// SetMarkedContentID sets the marked content id for the document.
func (_dcc *Document )SetMarkedContentID (id int64 )*_ed .KDict {return nil };
2021-05-09 11:11:57 +00:00
2024-12-22 09:15:36 +00:00
// SetPageSize sets the page default size.
func (_egg *Document )SetPageSize (pageSize _g .PageSize )error {if !pageSize .IsAPageSize (){return _a .New ("\u0070\u0072\u006f\u0076\u0069\u0064\u0065\u0064\u0020\u0069\u006ev\u0061\u006c\u0069\u0064\u0020\u0070\u0061\u0067\u0065\u0020s\u0069\u007a\u0065");
};_egg ._ffa =pageSize ;_egg ._bg =_cb .PositionAbsolute ;return nil ;};
2021-03-24 00:33:01 +00:00
2024-12-22 09:15:36 +00:00
// SetLandscapeOrientation sets document landscape page orientation.
func (_bffb *Document )SetLandscapeOrientation (){_bffb ._ced =_g .Landscape };
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// NewDocumentFromString creates a new Document from the provided HTML string.
func NewDocumentFromString (html string )(*Document ,error ){_adc ,_cd :=_fb .NewStringContent (html );if _cd !=nil {return nil ,_cd ;};_ef :=&Document {};_ef ._bf =_adc ;return _ef ,nil ;};
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// SetPos sets the absolute position. Changes object positioning to absolute.
func (_fgb *Document )SetPos (x ,y float64 ){_fgb ._bg =_cb .PositionAbsolute ;_fgb ._fbd =x ;_fgb ._fba =y ;};
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// TrimLastPageContent trims the last page content so that next creator blocks are located just at the end of given block.
func (_acd *Document )TrimLastPageContent (){_acd ._fdg =true };
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// GetPdfPages is a function that converts provided input content and
func (_fac *Document )GetPdfPages (ctx _f .Context )([]*_ed .PdfPage ,error ){if _gf :=_fac .validate ();_gf !=nil {return nil ,_gf ;};return _fac .extract (ctx ,_fac ._db ,_fac ._eb ,_fac .getMargins ());};
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// SetPageWidth sets the page width for given document.
func (_abg *Document )SetPageWidth (pageWidth _g .Length )error {_abg ._db =pageWidth ;_abg ._bg =_cb .PositionAbsolute ;return nil ;};var _ _cb .Drawable =(*Document )(nil );
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// SetMarginLeft sets the left margin.
func (_fgf *Document )SetMarginLeft (margin _g .Length ){_fgf ._fdb .Left =margin };
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// SetMarginRight sets the left margin.
func (_ddbf *Document )SetMarginRight (margin _g .Length ){_ddbf ._fdb .Right =margin };
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// WriteToFile writes the document to a file defined by the output path.
func (_ga *Document )WriteToFile (outputPath string )error {if _bc :=_ga .validate ();_bc !=nil {return _bc ;};_abd :=_fd .Second *20+_ga ._age ;_cf ,_fdbf :=_f .WithTimeout (_f .Background (),_abd );defer _fdbf ();_gc ,_agea :=_ga .extract (_cf ,_ga ._db ,_ga ._eb ,_ga .getMargins ());
if _agea !=nil {return _agea ;};_ece :=_cb .New ();for _ ,_ebf :=range _gc {if _agea =_ece .AddPage (_ebf );_agea !=nil {return _agea ;};};return _ece .WriteToFile (outputPath );};func _cg (_fda _b .Image )float64 {_cde :=_fda .Bounds ();var (_gef int ;
_abc _eg .Color ;_fbc ,_aeb ,_gdc uint32 ;);_af ,_dad :=_cde .Min .X ,_cde .Max .Y -1;_gfc :=_fda .At (_af ,_dad );_def ,_bca ,_ebg ,_ :=_gfc .RGBA ();_dbg :=_def ==_d .MaxUint16 &&_bca ==_d .MaxUint16 &&_ebg ==_d .MaxUint16 ;for _dad =_cde .Max .Y -1;
_dad >=_cde .Min .Y ;_dad --{var _fae bool ;for _af =_cde .Min .X ;_af < _cde .Max .X ;_af ++{_abc =_fda .At (_af ,_dad );_fbc ,_aeb ,_gdc ,_ =_abc .RGBA ();if (_dbg &&!(_fbc ==_def &&_aeb ==_bca &&_ebg ==_gdc ))||(!_dbg &&(_d .Abs (float64 (_fbc )-float64 (_def ))/float64 (_d .MaxUint16 )> 0.03||_d .Abs (float64 (_aeb )-float64 (_bca ))/float64 (_d .MaxUint16 )> 0.03||_d .Abs (float64 (_gdc )-float64 (_ebg ))/float64 (_d .MaxUint16 )> 0.03)){_fae =true ;
break ;};};if _fae {break ;};_gef =_dad ;};return float64 (_cde .Max .Y -_gef )/float64 (_cde .Max .Y );};type margins struct{Left ,Right ,Bottom ,Top _g .Length ;};var ErrNoClient =_a .New ("\u0055n\u0069\u0048\u0054\u004d\u004c\u0020\u0063\u006c\u0069\u0065\u006et\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");
2021-05-09 11:11:57 +00:00
2024-01-25 21:52:36 +00:00
// WaitTime sets the waiting time before the webpage is rendered to PDF.
2024-12-22 09:15:36 +00:00
func (_bce *Document )WaitTime (duration _fd .Duration ){_bce ._age =duration };func (_baa *Document )validate ()error {if _dd ==nil {return ErrNoClient ;};if _baa ._bf ==nil {return ErrContentNotDefined ;};return nil ;};
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// WaitVisible waits for the provided selector to be ready.
// A selector might be i.e. `#example` for id and `.example` for classes. The second parameter defines how to match given selector.
func (_gcg *Document )WaitVisible (sel string ,by ..._eea .ByType ){_gaf :=_eea .BySearch ;if len (by )> 0{_gaf =by [0];};_gcg ._da =append (_gcg ._da ,_fde .BySelector {Selector :sel ,By :_gaf });};
2024-01-25 21:52:36 +00:00
2024-12-22 09:15:36 +00:00
// Connect creates UniHTML HTTP Client and tries to establish connection with the server.
func Connect (path string )error {if _ddg :=_aa ();_ddg !=nil {return _ddg ;};_eda ,_ae :=_fde .ParseOptions (path );if _ae !=nil {return _ae ;};_dd =_fde .New (_eda );_ag ,_ce :=_f .WithTimeout (_f .Background (),_fd .Second *5);defer _ce ();if _ge :=_dd .HealthCheck (_ag );
_ge !=nil {return _ge ;};return nil ;};
2021-02-08 19:36:06 +00:00
2024-12-22 09:15:36 +00:00
// WaitReady waits for the provided selector to be ready.
// A selector might be i.e. `#example` for id and `.example` for classes. The second parameter defines how to match given selector.
func (_dfb *Document )WaitReady (sel string ,by ..._eea .ByType ){_dc :=_eea .BySearch ;if len (by )> 0{_dc =by [0];};_dfb ._ac =append (_dfb ._ac ,_fde .BySelector {Selector :sel ,By :_dc });};
2021-02-08 19:36:06 +00:00
2024-12-22 09:15:36 +00:00
// NewDocument creates new HTML Document used as an input for the creator.Drawable.
func NewDocument (path string )(*Document ,error ){_gd :=&Document {};_fa ,_eebf :=_e .Parse (path );if _eebf !=nil {return nil ,_eebf ;};switch _fa .Scheme {case "\u0068\u0074\u0074\u0070","\u0068\u0074\u0074p\u0073":_gd ._bf ,_eebf =_fb .NewWebURL (path );
if _eebf !=nil {return nil ,_eebf ;};return _gd ,nil ;};_cac ,_eebf :=_ff .Stat (path );if _eebf !=nil {return nil ,_eebf ;};if !_cac .IsDir (){_gd ._bf ,_eebf =_fb .NewHTMLFile (path );}else {_gd ._bf ,_eebf =_fb .NewZipDirectory (path );};if _eebf !=nil {return nil ,_eebf ;
};return _gd ,nil ;};var _dd *_fde .Client ;
2021-02-08 19:36:06 +00:00
2024-12-22 09:15:36 +00:00
// GeneratePageBlocks implements creator.Drawable interface.
func (_fcc *Document )GeneratePageBlocks (ctx _cb .DrawContext )([]*_cb .Block ,_cb .DrawContext ,error ){if _cec :=_fcc .validate ();_cec !=nil {return nil ,ctx ,_cec ;};var _eab []*_cb .Block ;_aae :=_fcc .getMargins ();_de ,_ec :=_fcc ._db ,_fcc ._eb ;
if _fcc ._bg .IsRelative (){_de ,_ec =_g .Point (ctx .Width ),_g .Point (ctx .Height );ctx .X -=float64 (_aae .Left .Points ());}else {ctx .X =_fcc ._fbd ;ctx .Y =_fcc ._fba ;};_ffd ,_faf :=_fcc .extract (_f .Background (),_de ,_ec ,_aae );if _faf !=nil {return nil ,_cb .DrawContext {},_faf ;
};for _df ,_ceg :=range _ffd {_efd ,_cab :=_cb .NewBlockFromPage (_ceg );if _cab !=nil {return nil ,_cb .DrawContext {},_cab ;};var _fed float64 ;if _fcc ._fdg &&_df ==len (_ffd )-1{_ba :=_ab .NewImageDevice ();_cbe ,_aac :=_ba .Render (_ceg );if _aac !=nil {return nil ,_cb .DrawContext {},_aac ;
};_cdg ,_aac :=_ceg .GetMediaBox ();if _aac !=nil {return nil ,_cb .DrawContext {},_aac ;};_ffda :=_fd .Now ();_bff :=_cg (_cbe );_fed =_cdg .Height ()*_bff ;_eac .Log .Trace ("\u0054\u0072i\u006d\u006d\u0069\u006eg\u0020\u006ca\u0073\u0074\u0020\u0064\u006f\u0063\u0075\u006de\u006e\u0074\u0020\u0070\u0061\u0067\u0065\u0020\u0074\u0061\u006b\u0065n\u003a\u0020\u0025\u0076",_fd .Since (_ffda ));
if _fcc ._fdb .Bottom !=nil {_fed -=float64 (_fcc ._fdb .Bottom .Points ());};if _fed < 0{_fed =0;};_eac .Log .Trace ("C\u0072\u006f\u0070\u0070\u0069\u006e\u0067\u0020\u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074\u0027\u0073\u0020\u0070\u0061\u0067\u0065\u0020\u0025\u002e2\u0066 \u0070\u006f\u0069\u006et\u0073\u0020o\u0066\u0066\u0020\u0062\u006f\u0074\u0074\u006f\u006d\u0020\u006f\u0066\u0020\u006d\u0065\u0064\u0069\u0061\u0020\u0062\u006f\u0078\u000a",_fed );
};_fg ,_be ,_cab :=_efd .GeneratePageBlocks (ctx );if _cab !=nil {return nil ,_cb .DrawContext {},_cab ;};ctx =_be ;ctx .Y -=_fed ;if _df !=len (_ffd )-1&&ctx .Y > (ctx .PageHeight -ctx .Margins .Bottom )*.95{ctx .X =ctx .Margins .Left ;ctx .Y =ctx .Margins .Top ;
ctx .Page ++;};_eab =append (_eab ,_fg ...);};return _eab ,ctx ,nil ;};func (_gfb *Document )getMargins ()margins {_daf :=_gfb ._fdb ;if _gfb ._bg .IsRelative (){_daf .Top =_g .Millimeter (1);_daf .Left =_g .Millimeter (1);_daf .Bottom =_g .Millimeter (1);
_daf .Right =_g .Millimeter (1);return _daf ;};if _daf .Top ==nil {_daf .Top =_g .Millimeter (10);};if _daf .Bottom ==nil {_daf .Bottom =_g .Millimeter (10);};if _daf .Left ==nil {_daf .Left =_g .Millimeter (10);};if _daf .Right ==nil {_daf .Right =_g .Millimeter (10);
};return _daf ;};func (_aed *Document )getTimeoutDuration ()_fd .Duration {if _aed ._fc !=nil {return *_aed ._fc ;};return 0;};
2021-02-08 19:36:06 +00:00
2024-12-22 09:15:36 +00:00
// GetContent returns the content of the document.
func (_eaf *Document )GetContent ()_fb .Content {return _eaf ._bf };
2021-02-08 19:36:06 +00:00
2024-12-22 09:15:36 +00:00
// SetTimeoutDuration sets the timeout duration
// the default timeout is 15 seconds.
func (_ggb *Document )SetTimeoutDuration (duration _fd .Duration ){_ggb ._fc =&duration };
2023-02-10 16:57:05 +00:00
2024-12-22 09:15:36 +00:00
// SetPageHeight sets the page height for given document.
func (_bgc *Document )SetPageHeight (pageHeight _g .Length )error {_bgc ._eb =pageHeight ;_bgc ._bg =_cb .PositionAbsolute ;return nil ;};
2022-05-05 21:25:46 +00:00
2024-12-22 09:15:36 +00:00
// Document is HTML document wrapper that is used for extracting and converting HTML document into PDF pages.
type Document struct{_bf _fb .Content ;_fdb margins ;_bg _cb .Positioning ;_fbd ,_fba float64 ;_ffa _g .PageSize ;_db ,_eb _g .Length ;_ced _g .Orientation ;_fdg bool ;_age _fd .Duration ;_ac []_fde .BySelector ;_da []_fde .BySelector ;_fc *_fd .Duration ;
};func (_edf *Document )extract (_gff _f .Context ,_fag ,_gaa _g .Length ,_feg margins )([]*_ed .PdfPage ,error ){_dbb :=_fde .BuildHTMLQuery ().SetContent (_edf ._bf ).PageSize (_edf ._ffa ).PaperWidth (_fag ).PaperHeight (_gaa ).Orientation (_edf ._ced ).MarginLeft (_feg .Left ).MarginRight (_feg .Right ).MarginTop (_feg .Top ).MarginBottom (_feg .Bottom ).TimeoutDuration (_edf .getTimeoutDuration ()).WaitTime (_edf ._age );
for _ ,_ade :=range _edf ._ac {_dbb .WaitReady (_ade .Selector ,_ade .By );};for _ ,_edb :=range _edf ._da {_dbb .WaitVisible (_edb .Selector ,_edb .By );};_fad ,_aag :=_dbb .Query ();if _aag !=nil {return nil ,_aag ;};var _ace _f .CancelFunc ;if _edf ._fc !=nil {_gff ,_ace =_f .WithTimeout (_gff ,*_edf ._fc );
}else {_gff ,_ace =_f .WithTimeout (_gff ,_fd .Second *15);};defer _ace ();_eff ,_aag :=_dd .ConvertHTML (_gff ,_fad );if _aag !=nil {return nil ,_aag ;};_fbf :=_ee .NewReader (_eff .Data );_dba ,_aag :=_ed .NewPdfReader (_fbf );if _aag !=nil {return nil ,_aag ;
};return _dba .PageList ,nil ;};
// ContainerComponent implements creator.containerElement interface.
func (_bd *Document )ContainerComponent (container _cb .Drawable )(_cb .Drawable ,error ){switch container .(type ){case *_cb .Chapter :default:return nil ,_ea .Errorf ("\u0075\u006e\u0069\u0068t\u006d\u006c\u002e\u0044\u006f\u0063\u0075\u006d\u0065n\u0074\u0020\u0063\u0061\u006e\u0027\u0074\u0020\u0062\u0065\u0020\u0061\u0020\u0063\u006f\u006d\u0070\u006fn\u0065\u006e\u0074\u0020\u006ff\u0020\u0074\u0068\u0065\u0020\u0025\u0054\u0020\u0063\u006f\u006e\u0074\u0061\u0069\u006e\u0065\u0072",container );
};return _bd ,nil ;};func _aa ()error {_ca :=_fdd .GetLicenseKey ();if _ca ==nil {return _a .New ("\u006e\u006f\u0020\u006cic\u0065\u006e\u0073\u0065\u0020\u0070\u0072\u006f\u0076\u0069\u0064\u0065\u0064");};if !_ca .IsLicensed (){return _a .New ("\u0069\u006e\u0076\u0061\u006c\u0069\u0064\u0020\u006f\u0072 \u006e\u006f\u0020\u006c\u0069\u0063\u0065n\u0073\u0065\u0020\u0070\u0072\u006f\u0076\u0069\u0064\u0065\u0064");
};return nil ;};
2023-02-10 16:57:05 +00:00
2024-01-25 21:52:36 +00:00
// SetMarginTop sets the left margin.
2024-12-22 09:15:36 +00:00
func (_gbe *Document )SetMarginTop (margin _g .Length ){_gbe ._fdb .Top =margin };
2022-05-05 21:25:46 +00:00
2024-12-22 09:15:36 +00:00
// SetMargins sets the Document Margins.
func (_aca *Document )SetMargins (left ,right ,top ,bottom float64 ){_aca ._fdb .Left =_g .Point (left );_aca ._fdb .Right =_g .Point (right );_aca ._fdb .Top =_g .Point (top );_aca ._fdb .Bottom =_g .Point (bottom );_aca ._bg =_cb .PositionAbsolute ;};
// SetMarginBottom sets the left margin.
func (_gg *Document )SetMarginBottom (margin _g .Length ){_gg ._fdb .Bottom =margin };var ErrContentNotDefined =_a .New ("\u0068\u0074\u006d\u006c\u0020\u0064o\u0063\u0075\u006d\u0065\u006e\u0074\u0020\u0063\u006f\u006e\u0074\u0065\u006et\u0020\u006e\u006f\u0074\u0020\u0064\u0065f\u0069\u006e\u0065\u0064");