44using System . Collections . Generic ;
55using System . IO ;
66using System . Linq ;
7+ using System . Text ;
78
89namespace SupernoteSharp . Business
910{
@@ -104,6 +105,25 @@ public Notebook LoadNotebook(FileStream fileStream, Policy policy)
104105 int recognTextAddress = metadata . Pages [ i ] . ContainsKey ( "RECOGNTEXT" ) == true ? Int32 . Parse ( ( string ) metadata . Pages [ i ] [ "RECOGNTEXT" ] ) : 0 ;
105106 if ( recognTextAddress > 0 )
106107 notebook . Pages [ i ] . RecognText = GetContentAtAddress ( fileStream , recognTextAddress ) ;
108+
109+ // attach external link info
110+ int externalLinkInfoAddress = metadata . Pages [ i ] . ContainsKey ( "EXTERNALLINKINFO" ) == true ? Int32 . Parse ( ( string ) metadata . Pages [ i ] [ "EXTERNALLINKINFO" ] ) : 0 ;
111+ if ( externalLinkInfoAddress > 0 )
112+ notebook . Pages [ i ] . ExternalLinkInfo = GetContentAtAddress ( fileStream , externalLinkInfoAddress ) ;
113+ }
114+
115+ // attach template link data
116+ List < Page > pagesWithTemplateLinks = notebook . Pages . Where ( x => x . ExternalLinkInfo != null ) . ToList ( ) ;
117+ foreach ( Page page in pagesWithTemplateLinks )
118+ {
119+ // ExternalLinkInfo contains multiple links separated by a '|' character
120+ string [ ] links = Encoding . UTF8 . GetString ( page . ExternalLinkInfo ) . Split ( "|" , StringSplitOptions . RemoveEmptyEntries ) ;
121+ foreach ( string link in links )
122+ {
123+ // each link properties are separated by a ',' character
124+ string [ ] linkProperties = link . Split ( "," , StringSplitOptions . RemoveEmptyEntries ) ;
125+ notebook . TemplateLinks . AddRange ( GetTemplateLink ( linkProperties , notebook . FileId ) ) ;
126+ }
107127 }
108128
109129 return notebook ;
@@ -142,20 +162,11 @@ private List<int> GetPageNumberFromFooterProperty(Dictionary<string, object> foo
142162 IEnumerable < string > propertyKeys = footer . Keys . Where ( p => p . StartsWith ( propertyPrefix ) ) ;
143163 foreach ( string property in propertyKeys )
144164 {
145- if ( footer [ property ] . GetType ( ) != typeof ( string ) )
146- {
147- // TODO: Need Supernote A5 test note
148- /*
149- if type(footer[k]) == list:
150- for _ in range(len(footer[k])):
151- page_numbers.append(int(k[6:10]) - 1)
152- else:
153- page_numbers.append(int(k[6:10]) - 1) # e.g. get '0123' from 'TITLE_01234567'
154- */
155- throw new NotImplementedException ( ) ;
156- }
165+ // get '0123' from 'TITLE_01234567' or 'LINKI_01234567' or 'LINKO_01234567'
166+ if ( footer [ property ] is List < string > itemList )
167+ pageNumbers . AddRange ( itemList . Select ( p => Convert . ToInt32 ( property . Substring ( 6 , 4 ) ) ) ) ;
157168 else
158- pageNumbers . Add ( Int32 . Parse ( property . Substring ( 6 , 4 ) ) ) ; // get '0123' from 'TITLE_01234567'
169+ pageNumbers . Add ( Int32 . Parse ( property . Substring ( 6 , 4 ) ) ) ;
159170 }
160171
161172 return pageNumbers ;
@@ -182,5 +193,47 @@ private List<int> GetBitmapAddress(Metadata metadata, int pageNumber)
182193
183194 return bitmapAddresses ;
184195 }
196+
197+ private List < Link > GetTemplateLink ( string [ ] templateLink , string fileId )
198+ {
199+ List < Link > templateLinks = new List < Link > ( ) ;
200+
201+ Dictionary < string , object > metadata = new Dictionary < string , object >
202+ {
203+ [ "LINKRECT" ] = $ "{ Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 3 ] ) ) } ," +
204+ $ "{ Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 4 ] ) ) } ," +
205+ $ "{ Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 5 ] ) ) } ," +
206+ $ "{ Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 6 ] ) ) } ",
207+ [ "LINKTYPE" ] = Int32 . Parse ( Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 7 ] ) ) ) == 0 ? ( ( Int32 ) LinkType . Page ) . ToString ( ) : ( ( Int32 ) LinkType . Web ) . ToString ( ) ,
208+ [ "LINKINOUT" ] = ( ( Int32 ) LinkDirection . Out ) . ToString ( ) ,
209+ [ "LINKBITMAP" ] = DateTime . Now . Ticks . ToString ( ) ,
210+ [ "LINKTIMESTAMP" ] = DateTime . Now . Ticks . ToString ( ) ,
211+ [ "LINKFILE" ] = templateLink [ 8 ] ,
212+ [ "LINKFILEID" ] = fileId ,
213+ [ "PAGEID" ] = Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 1 ] ) )
214+ } ;
215+
216+ Link linkOut = new Link ( metadata )
217+ {
218+ PageNumber = Int32 . Parse ( Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 0 ] ) ) ) - 1 // link indexes are not 0 based
219+ } ;
220+
221+ templateLinks . Add ( linkOut ) ;
222+
223+ // in case we are building template page links, we need to ensure we have both IN and OUT links
224+ // they are the same structure, with the exception of the LINKINOUT attribute
225+ if ( linkOut . Type == ( Int32 ) LinkType . Page )
226+ {
227+ metadata [ "LINKINOUT" ] = ( ( Int32 ) LinkDirection . In ) . ToString ( ) ;
228+ Link linkIn = new Link ( metadata )
229+ {
230+ PageNumber = Int32 . Parse ( Encoding . UTF8 . GetString ( Convert . FromBase64String ( templateLink [ 2 ] ) ) ) - 1 // link indexes are not 0 based
231+ } ;
232+
233+ templateLinks . Add ( linkIn ) ;
234+ }
235+
236+ return templateLinks ;
237+ }
185238 }
186239}
0 commit comments