diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..be03a72 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +on: + push: + branches: + - master + pull_request: + branches: + - master +env: + DOTNET_NOLOGO: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: true +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Build All + if: matrix.os == 'ubuntu-latest' + run: dotnet build --configuration Release + - name: Build Library + run: dotnet build FB2Library --configuration Release \ No newline at end of file diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml new file mode 100644 index 0000000..f1a9164 --- /dev/null +++ b/.github/workflows/release-preview.yml @@ -0,0 +1,50 @@ +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+-preview[0-9]+" +env: + DOTNET_NOLOGO: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: true +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set VERSION variable from tag + run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV + - name: Pack + run: | + dotnet pack FB2Library/FB2Library.csproj \ + -p:NuspecFile=../nuget/FB2Library.nuspec \ + -p:NuspecProperties="version=${VERSION}" \ + --configuration Release \ + --verbosity normal \ + --include-symbols \ + --include-source \ + --output . + - name: Upload Artifact + uses: actions/upload-artifact@v2 + with: + name: nupkg + path: '*.nupkg' + + deploy-github: + needs: build + runs-on: ubuntu-latest + steps: + - name: Download Artifact + uses: actions/download-artifact@v1 + with: + name: nupkg + - name: Push to GitHub + run: | + dotnet nuget push ./nupkg/FB2Library.*.nupkg \ + --source ${FEED_URL} \ + --api-key ${FEED_KEY} \ + --skip-duplicate + env: + FEED_URL: https://nuget.pkg.github.com/wcoder/index.json \ + FEED_KEY: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..808a0f6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" +env: + DOTNET_NOLOGO: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: true +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Verify commit exists in origin/master + run: | + git fetch --no-tags --prune --depth=1 origin '+refs/heads/*:refs/remotes/origin/*' + git branch --remote --contains | grep origin/master + - name: Set VERSION variable from tag + run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV + - name: Pack + run: | + dotnet pack FB2Library/FB2Library.csproj \ + -p:NuspecFile=../nuget/FB2Library.nuspec \ + -p:NuspecProperties="version=${VERSION}" \ + --configuration Release \ + --verbosity normal \ + --include-symbols \ + --include-source \ + --output . + - name: Upload Artifact + uses: actions/upload-artifact@v2 + with: + name: nupkg + path: '*.nupkg' + + deploy-nuget: + needs: build + runs-on: ubuntu-latest + steps: + - name: Download Artifact + uses: actions/download-artifact@v1 + with: + name: nupkg + - name: Push to NuGet + run: | + dotnet nuget push ./nupkg/FB2Library.*.nupkg \ + --source ${FEED_URL} \ + --api-key ${FEED_KEY} + env: + FEED_URL: https://api.nuget.org/v3/index.json + FEED_KEY: ${{ secrets.NUGET_KEY }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3804ca0..d560e43 100644 --- a/.gitignore +++ b/.gitignore @@ -116,7 +116,7 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings +# TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj @@ -193,3 +193,6 @@ _Pvt_Extensions bin/ obj/ *.userprefs + +# Idea +.idea/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..16b1cac --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Launch (ConsoleApp)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/bin/Debug/net6.0/FBLibrary.Sample.ConsoleApp.dll", + "args": [], + "cwd": "${workspaceFolder}/FBLibrary.Sample.ConsoleApp", + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..aadd597 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/FB2Library.sln b/FB2Library.sln index fbe0658..fc2de19 100644 --- a/FB2Library.sln +++ b/FB2Library.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FB2Library", "FB2Library\FB EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FB2Library.Sample.UWP", "FB2Library.Sample.UWP\FB2Library.Sample.UWP.csproj", "{9E25F85E-486A-4B68-AF44-3E47CA962433}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FBLibrary.Sample.ConsoleApp", "FBLibrary.Sample.ConsoleApp\FBLibrary.Sample.ConsoleApp.csproj", "{6D8B892A-DDE9-4860-94DD-B567D431CA7D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,6 +59,22 @@ Global {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x86.ActiveCfg = Release|x86 {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x86.Build.0 = Release|x86 {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x86.Deploy.0 = Release|x86 + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|ARM.ActiveCfg = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|ARM.Build.0 = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x64.ActiveCfg = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x64.Build.0 = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x86.ActiveCfg = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x86.Build.0 = Debug|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|Any CPU.Build.0 = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|ARM.ActiveCfg = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|ARM.Build.0 = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x64.ActiveCfg = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x64.Build.0 = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x86.ActiveCfg = Release|Any CPU + {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FB2Library.sln.DotSettings b/FB2Library.sln.DotSettings new file mode 100644 index 0000000..2a6f4d1 --- /dev/null +++ b/FB2Library.sln.DotSettings @@ -0,0 +1,4 @@ + + FB + XML + \ No newline at end of file diff --git a/FB2Library/Elements/AnnotationItem.cs b/FB2Library/Elements/AnnotationItem.cs index 6658185..ad27243 100644 --- a/FB2Library/Elements/AnnotationItem.cs +++ b/FB2Library/Elements/AnnotationItem.cs @@ -1,22 +1,12 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Xml.Linq; -using FB2Library.Elements.Poem; -using FB2Library.Elements.Table; - -namespace FB2Library.Elements +namespace FB2Library.Elements { public class AnnotationItem : AnnotationType { + internal const string Fb2AnnotationItemName = "annotation"; + public AnnotationItem() { ElementName = Fb2AnnotationItemName; } - internal const string Fb2AnnotationItemName = "annotation"; - } } diff --git a/FB2Library/Elements/AnnotationType.cs b/FB2Library/Elements/AnnotationType.cs index 15babf1..1af576d 100644 --- a/FB2Library/Elements/AnnotationType.cs +++ b/FB2Library/Elements/AnnotationType.cs @@ -11,7 +11,7 @@ namespace FB2Library.Elements { public class AnnotationType : IFb2TextItem { - private readonly List content = new List(); + private readonly List _content = new List(); protected string GetElementName() { @@ -20,14 +20,14 @@ protected string GetElementName() public string ElementName { get; set; } - public List Content { get { return content; } } + public List Content => _content; - public string ID { set; get; } + public string ID { get; set; } public override string ToString() { StringBuilder builder = new StringBuilder(); - foreach (var textItem in content) + foreach (var textItem in _content) { builder.Append(textItem.ToString()); builder.Append(" "); @@ -36,21 +36,19 @@ public override string ToString() } - - internal void Load(XElement xAnnotation) { if (xAnnotation == null) { - throw new ArgumentNullException("xAnnotation"); + throw new ArgumentNullException(nameof(xAnnotation)); } if (xAnnotation.Name.LocalName != GetElementName()) { - throw new ArgumentException("Element of wrong type passed", "xAnnotation"); + throw new ArgumentException("Element of wrong type passed", nameof(xAnnotation)); } - content.Clear(); + _content.Clear(); IEnumerable xItems = xAnnotation.Elements(); foreach (var xItem in xItems) { @@ -61,7 +59,7 @@ internal void Load(XElement xAnnotation) try { paragraph.Load(xItem); - content.Add(paragraph); + _content.Add(paragraph); } catch (Exception) { @@ -72,7 +70,7 @@ internal void Load(XElement xAnnotation) try { poem.Load(xItem); - content.Add(poem); + _content.Add(poem); } catch (Exception) { @@ -83,7 +81,7 @@ internal void Load(XElement xAnnotation) try { cite.Load(xItem); - content.Add(cite); + _content.Add(cite); } catch (Exception) { @@ -94,7 +92,7 @@ internal void Load(XElement xAnnotation) try { subtitle.Load(xItem); - content.Add(subtitle); + _content.Add(subtitle); } catch (Exception) { @@ -105,7 +103,7 @@ internal void Load(XElement xAnnotation) try { table.Load(xItem); - content.Add(table); + _content.Add(table); } catch (Exception) { @@ -113,7 +111,7 @@ internal void Load(XElement xAnnotation) break; case EmptyLineItem.Fb2EmptyLineElementName: EmptyLineItem eline = new EmptyLineItem(); - content.Add(eline); + _content.Add(eline); break; default: Debug.WriteLine(string.Format("AnnotationItem:Load - invalid element <{0}> encountered in annotation ."), xItem.Name.LocalName); @@ -136,7 +134,7 @@ public XNode ToXML() { xAnnotation.Add(new XAttribute("id",ID)); } - foreach (IFb2TextItem Item in content) + foreach (IFb2TextItem Item in _content) { xAnnotation.Add(Item.ToXML()); } diff --git a/FB2Library/Elements/AuthorItem.cs b/FB2Library/Elements/AuthorItem.cs index c2587bd..f1baa93 100644 --- a/FB2Library/Elements/AuthorItem.cs +++ b/FB2Library/Elements/AuthorItem.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - - -namespace FB2Library.HeaderItems +namespace FB2Library.HeaderItems { class AuthorItem : AuthorType { diff --git a/FB2Library/Elements/AuthorType.cs b/FB2Library/Elements/AuthorType.cs index 3a8a4d2..c24d4ae 100644 --- a/FB2Library/Elements/AuthorType.cs +++ b/FB2Library/Elements/AuthorType.cs @@ -1,13 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; using FB2Library.Elements; namespace FB2Library.HeaderItems { - public class AuthorType { public const string AuthorElementName = "author"; @@ -64,10 +60,7 @@ public XNamespace Namespace /// public TextFieldType UID { - get - { - return uid; - } + get => uid; set { if (!string.IsNullOrEmpty(value.Text)) @@ -121,6 +114,7 @@ internal void Load(XElement xElement) } catch (Exception) { + // ignore } } @@ -136,7 +130,7 @@ internal void Load(XElement xElement) } catch(Exception) { - + // ignore } } @@ -152,6 +146,7 @@ internal void Load(XElement xElement) } catch (Exception) { + // ignore } } @@ -168,6 +163,7 @@ internal void Load(XElement xElement) } catch (Exception) { + // ignore } } @@ -183,6 +179,7 @@ internal void Load(XElement xElement) } catch (Exception) { + // ignore } } @@ -199,6 +196,7 @@ internal void Load(XElement xElement) } catch (Exception) { + // ignore } } @@ -215,9 +213,9 @@ internal void Load(XElement xElement) } catch (Exception) { + // ignore } } - } public override string ToString() @@ -252,7 +250,7 @@ public override string ToString() uid = UID.Text; } - return string.Format("{0} {1} {2} ({3}): {4}",lastName,firstName,midName,nickName,uid); + return $"{lastName} {firstName} {midName} ({nickName}): {uid}"; } public override int GetHashCode() @@ -265,7 +263,7 @@ public override bool Equals(object obj) return ToString().Equals(obj.ToString()); } - public XElement ToXML( ) + public XElement ToXML() { XElement xPerson = new XElement(Fb2Const.fb2DefaultNamespace + ElementName); if (FirstName != null) @@ -296,7 +294,8 @@ public XElement ToXML( ) { xPerson.Add(UID.ToXML(IdElementName)); } + return xPerson; } - }//class + } } diff --git a/FB2Library/Elements/BinaryItem.cs b/FB2Library/Elements/BinaryItem.cs index 6517d3c..699bd3b 100644 --- a/FB2Library/Elements/BinaryItem.cs +++ b/FB2Library/Elements/BinaryItem.cs @@ -16,28 +16,28 @@ public class BinaryItem private const string ContentTypeAttributeName = "content-type"; private const string IdAttributeName = "id"; - public ContentTypeEnum ContentType{get;set;} - public Byte[] BinaryData { get; set; } - public string Id { get; set; } - + internal const string Fb2BinaryItemName = "binary"; + public static Func DetectContentType { get; set; } - internal const string Fb2BinaryItemName = "binary"; + public ContentTypeEnum ContentType { get; set; } + public byte[] BinaryData { get; set; } + public string Id { get; set; } internal void Load(XElement binarye) { if (binarye == null) { - throw new ArgumentNullException("binarye"); + throw new ArgumentNullException(nameof(binarye)); } if (binarye.Name.LocalName != Fb2BinaryItemName) { - throw new ArgumentException("Element of wrong type passed", "binarye"); + throw new ArgumentException("Element of wrong type passed", nameof(binarye)); } XAttribute xContentType = binarye.Attribute(ContentTypeAttributeName); - if ((xContentType == null) || (xContentType.Value == null)) + if (xContentType?.Value == null) { throw new NullReferenceException("content type not defined/present"); } @@ -58,59 +58,35 @@ internal void Load(XElement binarye) } XAttribute idAttribute = binarye.Attribute(IdAttributeName); - if ((idAttribute == null) || (idAttribute.Value == null)) - { - throw new NullReferenceException("ID not defined/present"); - } - Id = idAttribute.Value; + + Id = idAttribute?.Value ?? throw new NullReferenceException("ID not defined/present"); if (BinaryData != null) { - BinaryData= null; + BinaryData = null; } BinaryData = Convert.FromBase64String(binarye.Value); - //ContentTypeEnum content; - // try to detect type , this will detect for unknown and fix for wrongly set - //DetectContentType(out content, BinaryData); - // if we were not able to detect type and type was not set - //if (content == ContentTypeEnum.ContentTypeUnknown && ContentType == ContentTypeEnum.ContentTypeUnknown) - //{ - // // then we throw exception - // throw new Exception("Unknown image content type passed"); - //} - ContentType = ContentTypeEnum.ContentTypeUnknown; // TODO + + // try to detect type, this will detect for unknown and fix for wrongly set + if (DetectContentType == null) + { + ContentType = ContentTypeEnum.ContentTypeUnknown; + } + else + { + var contentType = DetectContentType(BinaryData); + + // if we were not able to detect type and type was not set + if (contentType == ContentTypeEnum.ContentTypeUnknown + && ContentType == ContentTypeEnum.ContentTypeUnknown) + { + // then we throw exception + throw new Exception("Unknown image content type passed"); + } + + ContentType = contentType; + } } - - // private void DetectContentType(out ContentTypeEnum contentType, byte[] binaryData) - // { - // contentType = ContentTypeEnum.ContentTypeUnknown; - // try - // { - // using (MemoryStream imgStream = new MemoryStream(binaryData)) - // { - // using (Bitmap bitmap = new Bitmap(imgStream)) - // { - // if (bitmap.RawFormat.Equals(ImageFormat.Jpeg)) - // { - // contentType = ContentTypeEnum.ContentTypeJpeg; - // } - // else if (bitmap.RawFormat.Equals(ImageFormat.Png)) - // { - // contentType = ContentTypeEnum.ContentTypePng; - // } - // else if (bitmap.RawFormat.Equals(ImageFormat.Gif)) - // { - // contentType = ContentTypeEnum.ContentTypeGif; - // } - // } - //} - // } - // catch (Exception ex) - // { - // throw new Exception(string.Format("Error during image type detection: {0}",ex),ex); - // } - - // } protected string GetXContentType() { @@ -122,9 +98,9 @@ protected string GetXContentType() return "image/png"; case ContentTypeEnum.ContentTypeGif: return "image/gif"; + case ContentTypeEnum.ContentTypeUnknown: default: return ""; - } } @@ -136,7 +112,6 @@ public XElement ToXML() xBinary.Value=Convert.ToBase64String(BinaryData); return xBinary; - } } } diff --git a/FB2Library/Elements/BodyItem.cs b/FB2Library/Elements/BodyItem.cs index 70a441d..b76e6ad 100644 --- a/FB2Library/Elements/BodyItem.cs +++ b/FB2Library/Elements/BodyItem.cs @@ -1,9 +1,6 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements diff --git a/FB2Library/Elements/CiteItem.cs b/FB2Library/Elements/CiteItem.cs index d746e64..b5174ea 100644 --- a/FB2Library/Elements/CiteItem.cs +++ b/FB2Library/Elements/CiteItem.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; using System.Xml.Linq; using FB2Library.Elements.Poem; using FB2Library.Elements.Table; @@ -11,31 +9,30 @@ namespace FB2Library.Elements { public class CiteItem : IFb2TextItem { - private readonly List citeData = new List(); - private readonly List textAuthors = new List(); + internal const string Fb2CiteElementName = "cite"; - public List TextAuthors { get { return textAuthors; } } + private readonly List _citeData = new List(); + private readonly List _textAuthors = new List(); + public string ID { get; set; } - public List CiteData { get { return citeData; } } + public List CiteData => _citeData; + public List TextAuthors => _textAuthors; public string Lang { get; set; } - internal const string Fb2CiteElementName = "cite"; - - internal void Load(XElement xCite) { - citeData.Clear(); + _citeData.Clear(); if (xCite == null) { - throw new ArgumentNullException("xCite"); + throw new ArgumentNullException(nameof(xCite)); } if (xCite.Name.LocalName != Fb2CiteElementName) { - throw new ArgumentException("Element of wrong type passed", "xCite"); + throw new ArgumentException("Element of wrong type passed", nameof(xCite)); } - textAuthors.Clear(); + _textAuthors.Clear(); IEnumerable xItems = xCite.Elements(); foreach (var element in xItems) { @@ -46,7 +43,7 @@ internal void Load(XElement xCite) try { paragraph.Load(element); - citeData.Add(paragraph); + _citeData.Add(paragraph); } catch (Exception) { @@ -57,7 +54,7 @@ internal void Load(XElement xCite) try { poem.Load(element); - citeData.Add(poem); + _citeData.Add(poem); } catch (Exception) { @@ -67,7 +64,7 @@ internal void Load(XElement xCite) EmptyLineItem emptyLine = new EmptyLineItem(); try { - citeData.Add(emptyLine); + _citeData.Add(emptyLine); } catch (Exception) { @@ -78,7 +75,7 @@ internal void Load(XElement xCite) try { subtitle.Load(element); - citeData.Add(subtitle); + _citeData.Add(subtitle); } catch (Exception) { @@ -89,7 +86,7 @@ internal void Load(XElement xCite) try { table.Load(element); - citeData.Add(table); + _citeData.Add(table); } catch (Exception) @@ -102,28 +99,29 @@ internal void Load(XElement xCite) try { author.Load(element); - textAuthors.Add(author); + _textAuthors.Add(author); } catch (Exception) { } break; default: - Debug.WriteLine(string.Format("CiteItem:Load - invalid element <{0}> encountered in title ."), element.Name.LocalName); + Debug.WriteLine( + $"CiteItem:Load - invalid element <{element.Name.LocalName}> encountered in title ."); break; } } Lang = null; XAttribute xLang = xCite.Attribute(XNamespace.Xml + "lang"); - if ((xLang != null)&&(xLang.Value != null)) + if (xLang != null && xLang.Value != null) { Lang = xLang.Value; } ID = null; XAttribute xID = xCite.Attribute("id"); - if ((xID != null) && (xID.Value != null)) + if (xID != null && xID.Value != null) { ID = xID.Value; } @@ -142,13 +140,13 @@ public XNode ToXML() xCite.Add(new XAttribute(XNamespace.Xml + "lang", Lang)); } - foreach (IFb2TextItem CiteItem in citeData) + foreach (IFb2TextItem citeItem in _citeData) { - xCite.Add(CiteItem.ToXML()); + xCite.Add(citeItem.ToXML()); } - foreach (ParagraphItem AuthorItem in textAuthors) + foreach (ParagraphItem authorItem in _textAuthors) { - xCite.Add(AuthorItem.ToXML()); + xCite.Add(authorItem.ToXML()); } return xCite; diff --git a/FB2Library/Elements/CustomTextFieldType.cs b/FB2Library/Elements/CustomTextFieldType.cs index bb44097..3643cf3 100644 --- a/FB2Library/Elements/CustomTextFieldType.cs +++ b/FB2Library/Elements/CustomTextFieldType.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements @@ -11,8 +8,7 @@ public class CustomTextFieldType : TextFieldType /// /// Get/Set info-type attribute /// - public string InfoType { get; set; } - + public string InfoType { get; private set; } public override void Load(XElement xElement) { @@ -24,13 +20,8 @@ public override void Load(XElement xElement) { throw new Exception("info-type attribute required for custom info element"); } - else - { - InfoType = xInfoType.Value; - } - - } - + InfoType = xInfoType.Value; + } } } diff --git a/FB2Library/Elements/DateItem.cs b/FB2Library/Elements/DateItem.cs index 337a1ec..cb28cc1 100644 --- a/FB2Library/Elements/DateItem.cs +++ b/FB2Library/Elements/DateItem.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements @@ -11,6 +8,8 @@ namespace FB2Library.Elements /// public class DateItem : IFb2TextItem { + internal const string Fb2DateElementName = "date"; + /// /// Get/Set Date as Text /// @@ -26,19 +25,16 @@ public class DateItem : IFb2TextItem /// public string Language { get; set; } - - internal const string Fb2DateElementName = "date"; - internal void Load(XElement xDate) { if (xDate == null) { - throw new ArgumentNullException("xDate"); + throw new ArgumentNullException(nameof(xDate)); } if (xDate.Name.LocalName != Fb2DateElementName) { - throw new ArgumentException("Element of wrong type passed", "xDate"); + throw new ArgumentException("Element of wrong type passed", nameof(xDate)); } if (xDate.Value != null) @@ -47,7 +43,7 @@ internal void Load(XElement xDate) } XAttribute xDateValue = xDate.Attribute("value"); - if ((xDateValue != null)&&(xDateValue.Value != null)) + if (xDateValue != null && xDateValue.Value != null) { try { @@ -55,7 +51,7 @@ internal void Load(XElement xDate) } catch (Exception) { - + // ignore } } diff --git a/FB2Library/Elements/EmptyLineItem.cs b/FB2Library/Elements/EmptyLineItem.cs index 8fe278e..3e8d606 100644 --- a/FB2Library/Elements/EmptyLineItem.cs +++ b/FB2Library/Elements/EmptyLineItem.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml; -using System.Xml.Linq; +using System.Xml.Linq; namespace FB2Library.Elements { @@ -19,6 +14,5 @@ public XNode ToXML() { return new XElement(Fb2Const.fb2DefaultNamespace + Fb2EmptyLineElementName); } - } } diff --git a/FB2Library/Elements/EpigraphItem.cs b/FB2Library/Elements/EpigraphItem.cs index 99c2ac9..11cddb5 100644 --- a/FB2Library/Elements/EpigraphItem.cs +++ b/FB2Library/Elements/EpigraphItem.cs @@ -1,9 +1,6 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; using System.Xml.Linq; using FB2Library.Elements.Poem; @@ -11,32 +8,29 @@ namespace FB2Library.Elements { public class EpigraphItem : IFb2TextItem { - private readonly List epigraphData = new List(); - private readonly List textAuthors = new List(); - - public List TextAuthors { get { return textAuthors; } } - public List EpigraphData { get { return epigraphData; } } - public string ID { get; set; } + internal const string Fb2EpigraphElementName = "epigraph"; + private readonly List _epigraphData = new List(); + private readonly List _textAuthors = new List(); - internal const string Fb2EpigraphElementName = "epigraph"; + public string ID { get; set; } + public List EpigraphData => _epigraphData; + public List TextAuthors => _textAuthors; internal void Load(XElement xEpigraph) { - epigraphData.Clear(); + _epigraphData.Clear(); if (xEpigraph == null) { - throw new ArgumentNullException("xEpigraph"); + throw new ArgumentNullException(nameof(xEpigraph)); } - - if (xEpigraph.Name.LocalName != Fb2EpigraphElementName) { - throw new ArgumentException("Element of wrong type passed", "xEpigraph"); + throw new ArgumentException("Element of wrong type passed", nameof(xEpigraph)); } IEnumerable xItems = xEpigraph.Elements(); - textAuthors.Clear(); + _textAuthors.Clear(); foreach (var element in xItems) { switch (element.Name.LocalName) @@ -46,11 +40,11 @@ internal void Load(XElement xEpigraph) try { paragraph.Load(element); - epigraphData.Add(paragraph); + _epigraphData.Add(paragraph); } catch (Exception ex) { - Debug.WriteLine(string.Format("Failed to load paragraph: {0}.", ex.Message)); + Debug.WriteLine($"Failed to load paragraph: {ex.Message}."); } break; case PoemItem.Fb2PoemElementName: @@ -58,11 +52,11 @@ internal void Load(XElement xEpigraph) try { poem.Load(element); - epigraphData.Add(poem); + _epigraphData.Add(poem); } catch (Exception ex) { - Debug.WriteLine(string.Format("Failed to load poem: {0}.", ex.Message)); + Debug.WriteLine($"Failed to load poem: {ex.Message}."); } break; case CiteItem.Fb2CiteElementName: @@ -70,22 +64,22 @@ internal void Load(XElement xEpigraph) try { cite.Load(element); - epigraphData.Add(cite); + _epigraphData.Add(cite); } catch (Exception ex) { - Debug.WriteLine(string.Format("Failed to load citation: {0}.", ex.Message)); + Debug.WriteLine($"Failed to load citation: {ex.Message}."); } break; case EmptyLineItem.Fb2EmptyLineElementName: EmptyLineItem emptyLine = new EmptyLineItem(); try { - epigraphData.Add(emptyLine); + _epigraphData.Add(emptyLine); } catch (Exception ex) { - Debug.WriteLine(string.Format("Failed to load empty line: {0}.", ex.Message)); + Debug.WriteLine($"Failed to load empty line: {ex.Message}."); } break; case TextAuthorItem.Fb2TextAuthorElementName: @@ -94,21 +88,22 @@ internal void Load(XElement xEpigraph) try { author.Load(element); - textAuthors.Add(author); + _textAuthors.Add(author); } catch (Exception ex) { - Debug.WriteLine(string.Format("Failed to load text author: {0}.", ex.Message)); + Debug.WriteLine($"Failed to load text author: {ex.Message}."); } break; default: - Debug.WriteLine(string.Format("EpigraphItem:Load - invalid element <{0}> encountered in title ."), element.Name.LocalName); + Debug.WriteLine( + $"EpigraphItem:Load - invalid element <{element.Name.LocalName}> encountered in title."); break; } } XAttribute xID = xEpigraph.Attribute("id"); - if ((xID != null) &&(xID.Value != null)) + if (xID != null && xID.Value != null) { ID = xID.Value; } @@ -122,17 +117,16 @@ public XNode ToXML() xEpigraph.Add(new XAttribute("id", ID)); } - foreach (IFb2TextItem EpigrafItem in epigraphData) + foreach (IFb2TextItem epigrafItem in _epigraphData) { - xEpigraph.Add(EpigrafItem.ToXML()); + xEpigraph.Add(epigrafItem.ToXML()); } - foreach (IFb2TextItem EpigrafAuthor in textAuthors) + foreach (IFb2TextItem epigrafAuthor in _textAuthors) { - xEpigraph.Add(EpigrafAuthor.ToXML()); + xEpigraph.Add(epigrafAuthor.ToXML()); } return xEpigraph; - } } } diff --git a/FB2Library/Elements/FB2Const.cs b/FB2Library/Elements/FB2Const.cs index 96734c0..19dbfad 100644 --- a/FB2Library/Elements/FB2Const.cs +++ b/FB2Library/Elements/FB2Const.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; +using System.Xml.Linq; namespace FB2Library.Elements { diff --git a/FB2Library/Elements/FB2TextItem.cs b/FB2Library/Elements/FB2TextItem.cs index 01a6ebc..5183331 100644 --- a/FB2Library/Elements/FB2TextItem.cs +++ b/FB2Library/Elements/FB2TextItem.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Linq; +using System.Xml.Linq; namespace FB2Library.Elements { diff --git a/FB2Library/Elements/GenreType.cs b/FB2Library/Elements/GenreType.cs index 815fd27..21bc1f3 100644 --- a/FB2Library/Elements/GenreType.cs +++ b/FB2Library/Elements/GenreType.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements @@ -23,23 +20,23 @@ public class GenreType /// public class TitleGenreType : GenreType { - private int match = 100; + private int _match = 100; /// /// Get/Set matching value , can be from 1 to 100% /// public int Match { - get { return match; } + get => _match; set { if (value > 0 && value <= 100) { - match = value; + _match = value; } else { - match = 100; + _match = 100; } } } @@ -50,10 +47,11 @@ public XElement ToXML() { throw new ArgumentException("Genre is empty"); } + XElement xGenre = new XElement(Fb2Const.fb2DefaultNamespace + "genre", Genre); - if (match > 0 && match < 100) + if (_match > 0 && _match < 100) { - xGenre.Add(new XAttribute("match",match.ToString())); + xGenre.Add(new XAttribute("match",_match.ToString())); } return xGenre; } diff --git a/FB2Library/Elements/ImageItem.cs b/FB2Library/Elements/ImageItem.cs index 8cfa0c3..90e6569 100644 --- a/FB2Library/Elements/ImageItem.cs +++ b/FB2Library/Elements/ImageItem.cs @@ -1,14 +1,13 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements { public class ImageItem : IFb2TextItem { - private readonly XNamespace xLinkNamespace = @"http://www.w3.org/1999/xlink"; + internal const string Fb2ImageElementName = "image"; + + private readonly XNamespace _xLinkNamespace = @"http://www.w3.org/1999/xlink"; public string ImageType { get; set; } public string HRef { get; set; } @@ -16,52 +15,48 @@ public class ImageItem : IFb2TextItem public string Title { get; set; } public string ID { get; set; } - - internal const string Fb2ImageElementName = "image"; - internal void Load(XElement xImage) { if (xImage == null) { - throw new ArgumentNullException("xImage"); + throw new ArgumentNullException(nameof(xImage)); } if (xImage.Name.LocalName != Fb2ImageElementName) { - throw new ArgumentException("Element of wrong type passed", "xImage"); + throw new ArgumentException("Element of wrong type passed", nameof(xImage)); } - XAttribute xType = xImage.Attribute(xLinkNamespace + "type"); - if ((xType != null) && (xType.Value != null)) + XAttribute xType = xImage.Attribute(_xLinkNamespace + "type"); + if (xType != null && xType.Value != null) { ImageType = xType.Value; } - XAttribute xHRef = xImage.Attribute(xLinkNamespace + "href"); - if ((xHRef != null) && (xHRef.Value != null)) + XAttribute xHRef = xImage.Attribute(_xLinkNamespace + "href"); + if (xHRef != null && xHRef.Value != null) { HRef = xHRef.Value; } XAttribute xAlt = xImage.Attribute("alt"); - if ((xAlt != null) && (xAlt.Value != null)) + if (xAlt != null && xAlt.Value != null) { AltText = xAlt.Value; } XAttribute xTitle = xImage.Attribute("title"); - if ((xTitle != null) && (xTitle.Value != null)) + if (xTitle != null && xTitle.Value != null) { Title = xTitle.Value; } XAttribute xID = xImage.Attribute("id"); - if ((xID != null) && (xID.Value != null)) + if (xID != null && xID.Value != null) { ID = xID.Value; } - } public XNode ToXML() @@ -69,11 +64,11 @@ public XNode ToXML() XElement xImage = new XElement(Fb2Const.fb2DefaultNamespace + Fb2ImageElementName); if (!string.IsNullOrEmpty(ImageType)) { - xImage.Add(new XAttribute(xLinkNamespace + "type", ImageType)); + xImage.Add(new XAttribute(_xLinkNamespace + "type", ImageType)); } if (!string.IsNullOrEmpty(HRef)) { - xImage.Add(new XAttribute(xLinkNamespace + "href", HRef)); + xImage.Add(new XAttribute(_xLinkNamespace + "href", HRef)); } if (!string.IsNullOrEmpty(AltText)) { @@ -89,6 +84,5 @@ public XNode ToXML() } return xImage; } - } } diff --git a/FB2Library/Elements/InlineImageItem.cs b/FB2Library/Elements/InlineImageItem.cs index 4498950..4c5f27b 100644 --- a/FB2Library/Elements/InlineImageItem.cs +++ b/FB2Library/Elements/InlineImageItem.cs @@ -5,6 +5,8 @@ namespace FB2Library.Elements { public class InlineImageItem : StyleType { + internal const string Fb2InlineImageElementName = "image"; + private readonly XNamespace xLinkNamespace = @"http://www.w3.org/1999/xlink"; protected virtual string GetElementName() @@ -12,29 +14,25 @@ protected virtual string GetElementName() return Fb2InlineImageElementName; } - public string ImageType { get; set;} public string HRef { get; set;} public string AltText { get; set;} - internal const string Fb2InlineImageElementName = "image"; - public override string ToString() { return HRef; } - internal void Load(XElement xImage) { if (xImage == null) { - throw new ArgumentNullException("xImage"); + throw new ArgumentNullException(nameof(xImage)); } if (xImage.Name.LocalName != GetElementName()) { - throw new ArgumentException("Element of wrong type passed", "xImage"); + throw new ArgumentException("Element of wrong type passed", nameof(xImage)); } XAttribute xType = xImage.Attribute(xLinkNamespace + "type"); @@ -98,6 +96,5 @@ public XNode ToXML() } return xImage; } - } } diff --git a/FB2Library/Elements/InternalLinkItem.cs b/FB2Library/Elements/InternalLinkItem.cs index feb4700..1fc9e8c 100644 --- a/FB2Library/Elements/InternalLinkItem.cs +++ b/FB2Library/Elements/InternalLinkItem.cs @@ -1,86 +1,164 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; +using System.Xml; using System.Xml.Linq; namespace FB2Library.Elements { public class InternalLinkItem : StyleType { + internal const string Fb2InternalLinkElementName = "a"; + private readonly XNamespace lNamespace = @"http://www.w3.org/1999/xlink"; - public string Type { get; set; } + private readonly List _linkData = new List(); + public string Type { get; set; } public string HRef { get; set; } - - public SimpleText LinkText { get; set; } - - internal const string Fb2InternalLinkElementName = "a"; - + + public List LinkData => _linkData; public override string ToString() { - return LinkText.ToString(); + StringBuilder builder = new StringBuilder(); + builder.Append(""); + foreach (var item in _linkData) + { + builder.Append(item.ToString()); + builder.Append(" "); + } + builder.Append(""); + return builder.ToString(); } internal void Load(XElement xLink) { if (xLink == null) { - throw new ArgumentNullException("xLink"); + throw new ArgumentNullException(nameof(xLink)); } - if (xLink.Name.LocalName != Fb2InternalLinkElementName) { - throw new ArgumentException("Element of wrong type passed", "xLink"); + throw new ArgumentException("Element of wrong type passed", nameof(xLink)); } - LinkText = null; - //if (xLink.Value != null) + if (xLink.HasElements) { - LinkText = new SimpleText(); - try - { - LinkText.Load(xLink); - } - catch (Exception) + IEnumerable childElements = xLink.Nodes(); + foreach (var element in childElements) { - LinkText = null; + if ((element.NodeType == XmlNodeType.Element) && !IsSimpleText(element)) + { + XElement xElement = (XElement)element; + if (xElement.Name.LocalName == InlineImageItem.Fb2InlineImageElementName) + { + InlineImageItem image = new InlineImageItem(); + try + { + image.Load(xElement); + _linkData.Add(image); + } + catch (Exception) + { + // ignored + } + } + else if (xElement.Name.LocalName == StyleItem.StyleItemName) + { + StyleItem styleItem = new StyleItem(); + try + { + styleItem.Load(xElement); + _linkData.Add(styleItem); + } + catch (Exception) + { + // ignored + } + } + } + else + { + SimpleText text = new SimpleText(); + try + { + text.Load(element); + _linkData.Add(text); + } + catch (Exception) + { + // ignored + } + } } } + else if (!string.IsNullOrEmpty(xLink.Value)) + { + SimpleText text = new SimpleText(); + text.Load(xLink); + _linkData.Add(text); + } XAttribute xTypeAttr = xLink.Attribute("type"); - if ((xTypeAttr != null)&& (xTypeAttr.Value != null)) + if (xTypeAttr != null && xTypeAttr.Value != null) { Type = xTypeAttr.Value; } XAttribute xHRefAttr = xLink.Attribute(lNamespace + "href"); - if ((xHRefAttr != null) && (xHRefAttr.Value != null)) + if (xHRefAttr != null && xHRefAttr.Value != null) { HRef = xHRefAttr.Value; } + } + private bool IsSimpleText(XNode element) + { + // if not element than we assume simple text + if (element.NodeType != XmlNodeType.Element) + { + return true; + } + XElement xElement = (XElement)element; + if (xElement.Name.LocalName == Fb2InternalLinkElementName) + { + throw new ArgumentException("Schema doesn't support nested links"); + } + switch (xElement.Name.LocalName) + { + case InlineImageItem.Fb2InlineImageElementName: + case StyleItem.StyleItemName: + return false; + } + return true; } public XNode ToXML() { XElement xLink = new XElement(Fb2Const.fb2DefaultNamespace + Fb2InternalLinkElementName); if (!string.IsNullOrEmpty(Type)) - { - xLink.Add(new XAttribute("type",Type)); + { + xLink.Add(new XAttribute("type", Type)); } - if(!string.IsNullOrEmpty(HRef)) + if (!string.IsNullOrEmpty(HRef)) { - xLink.Add(new XAttribute(lNamespace + "href",HRef)); + xLink.Add(new XAttribute(lNamespace + "href", HRef)); } - if (LinkText != null) + foreach (StyleType childElements in _linkData) { - xLink.Add(LinkText.ToXML()); + xLink.Add(childElements.ToXML()); } return xLink; } - } } diff --git a/FB2Library/Elements/OutPutDocumentType.cs b/FB2Library/Elements/OutPutDocumentType.cs index 8aa915d..1517ddd 100644 --- a/FB2Library/Elements/OutPutDocumentType.cs +++ b/FB2Library/Elements/OutPutDocumentType.cs @@ -1,33 +1,31 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements { public class OutPutDocumentType : IShareInstructionElement { - private readonly List parts = new List(); - public const string OutputDocumentElementName = "output-document-class"; - private XNamespace fileNameSpace = XNamespace.None; + private readonly List _parts = new List(); + + private XNamespace _fileNameSpace = XNamespace.None; /// /// XML namespace used to read the document /// public XNamespace Namespace { - set { fileNameSpace = value; } - get { return fileNameSpace; } + set { _fileNameSpace = value; } + get { return _fileNameSpace; } } /// /// Get list of the instruction parts /// - public List Parts { get { return parts; } } + public List Parts => _parts; /// /// Get/Set Name attribute @@ -39,7 +37,6 @@ public XNamespace Namespace /// public GenerationInstructionEnum Create { get; set; } - /// /// Get/Set price /// @@ -49,22 +46,22 @@ public void Load(XElement xElement) { if (xElement == null) { - throw new ArgumentNullException("xElement"); + throw new ArgumentNullException(nameof(xElement)); } - parts.Clear(); - IEnumerable xParts = xElement.Elements(fileNameSpace + "part"); + _parts.Clear(); + IEnumerable xParts = xElement.Elements(_fileNameSpace + "part"); foreach (var xPart in xParts) { - ShareInstructionType part = new ShareInstructionType {Namespace = fileNameSpace}; + ShareInstructionType part = new ShareInstructionType {Namespace = _fileNameSpace}; try { part.Load(xPart); - parts.Add(part); + _parts.Add(part); } catch (Exception) { - continue; + // ignored } } @@ -93,17 +90,16 @@ public void Load(XElement xElement) Create = GenerationInstructionEnum.Deny; break; default: - Debug.WriteLine(string.Format("Invalid instruction type : {0}", xCreate.Value)); + Debug.WriteLine($"Invalid instruction type : {xCreate.Value}"); break; } } Price = null; XAttribute xPrice = xElement.Attribute("price"); - if ((xPrice != null) && !string.IsNullOrEmpty(xPrice.Value)) + if (xPrice != null && !string.IsNullOrEmpty(xPrice.Value)) { - float val; - if (float.TryParse(xPrice.Value, out val)) + if (float.TryParse(xPrice.Value, out var val)) { Price = val; } @@ -139,9 +135,9 @@ public XElement ToXML() { xOutputDocumentClass.Add(new XAttribute("price", Price.ToString())); } - foreach (ShareInstructionType PartElement in parts) + foreach (ShareInstructionType partElement in _parts) { - xOutputDocumentClass.Add(PartElement.ToXML()); + xOutputDocumentClass.Add(partElement.ToXML()); } return xOutputDocumentClass; } diff --git a/FB2Library/Elements/ParagraphItem.cs b/FB2Library/Elements/ParagraphItem.cs index d14980c..d18083f 100644 --- a/FB2Library/Elements/ParagraphItem.cs +++ b/FB2Library/Elements/ParagraphItem.cs @@ -22,9 +22,9 @@ protected virtual string GetElementName() { return Fb2ParagraphElementName; } - + internal const string Fb2ParagraphElementName = "p"; - + public override string ToString() { @@ -78,24 +78,36 @@ protected void LoadData(XElement xParagraph) } catch (Exception) { - } + } } - } - else //if ( element.NodeType != XmlNodeType.Whitespace) - { - SimpleText text = new SimpleText(); + else if (xElement.Name.LocalName == StyleItem.StyleItemName) + { + StyleItem styleItem = new StyleItem(); try { - text.Load(element); - paragraphData.Add(text); + styleItem.Load(xElement); + paragraphData.Add(styleItem); } catch (Exception) { - continue; } + } + } + else //if ( element.NodeType != XmlNodeType.Whitespace) + { + SimpleText text = new SimpleText(); + try + { + text.Load(element); + paragraphData.Add(text); + } + catch (Exception) + { + continue; + } } } - + } else if (!string.IsNullOrEmpty(xParagraph.Value)) { @@ -122,7 +134,7 @@ protected void LoadData(XElement xParagraph) { Lang = xLang.Value; } - + } internal virtual void Load(XElement xParagraph) @@ -153,8 +165,9 @@ private bool IsSimpleText(XNode element) { case InternalLinkItem.Fb2InternalLinkElementName: case InlineImageItem.Fb2InlineImageElementName: + case StyleItem.StyleItemName: return false; - + } return true; } diff --git a/FB2Library/Elements/Poem/PoemItem.cs b/FB2Library/Elements/Poem/PoemItem.cs index 82400b4..b486e92 100644 --- a/FB2Library/Elements/Poem/PoemItem.cs +++ b/FB2Library/Elements/Poem/PoemItem.cs @@ -9,19 +9,17 @@ namespace FB2Library.Elements.Poem { public class PoemItem : IFb2TextItem { - private readonly List epigraphs = new List(); - private readonly List content = new List(); - private readonly List authors = new List(); + private readonly List _epigraphs = new List(); + private readonly List _content = new List(); + private readonly List _authors = new List(); public TitleItem Title { get; set; } - public List Content { get { return content; } } - public List Authors { get { return authors; } } - public List Epigraphs { get { return epigraphs; } } + public List Content => _content; + public List Authors => _authors; + public List Epigraphs => _epigraphs; public string Lang { get; set; } - public string ID { set; get; } - public DateItem Date { set; get; } - - + public string ID { get; set; } + public DateItem Date { get; set; } internal const string Fb2PoemElementName = "poem"; @@ -39,9 +37,9 @@ internal void Load(XElement xPoem) Title = null; Date = null; - epigraphs.Clear(); - content.Clear(); - authors.Clear(); + _epigraphs.Clear(); + _content.Clear(); + _authors.Clear(); IEnumerable xElements = xPoem.Elements(); foreach (var xElement in xElements) @@ -52,7 +50,7 @@ internal void Load(XElement xPoem) try { stanza.Load(xElement); - content.Add(stanza); + _content.Add(stanza); } catch (Exception) { @@ -65,7 +63,7 @@ internal void Load(XElement xPoem) try { subtitle.Load(xElement); - content.Add(subtitle); + _content.Add(subtitle); } catch (Exception) { @@ -83,7 +81,7 @@ internal void Load(XElement xPoem) try { epigraphItem.Load(xElement); - epigraphs.Add(epigraphItem); + _epigraphs.Add(epigraphItem); } catch (Exception) { @@ -96,7 +94,7 @@ internal void Load(XElement xPoem) try { author.Load(xElement); - authors.Add(author); + _authors.Add(author); } catch (Exception) { @@ -150,11 +148,11 @@ public XNode ToXML() { xPoem.Add(PoemEpigraph.ToXML()); } - foreach (IFb2TextItem PoemStanza in content) + foreach (IFb2TextItem PoemStanza in _content) { xPoem.Add(PoemStanza.ToXML()); } - foreach (TextAuthorItem TextAuthor in authors) + foreach (TextAuthorItem TextAuthor in _authors) { xPoem.Add(TextAuthor.ToXML()); } diff --git a/FB2Library/Elements/Poem/StanzaItem.cs b/FB2Library/Elements/Poem/StanzaItem.cs index 564d27e..36aa781 100644 --- a/FB2Library/Elements/Poem/StanzaItem.cs +++ b/FB2Library/Elements/Poem/StanzaItem.cs @@ -1,33 +1,30 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements.Poem { public class StanzaItem : IFb2TextItem { - private readonly List lines = new List(); + internal const string Fb2StanzaElementName = "stanza"; + + private readonly List _lines = new List(); public TitleItem Title { get; set; } public SubTitleItem SubTitle { get; set; } - public List Lines { get { return lines; } } + public List Lines => _lines; public string Lang { get; set; } - internal const string Fb2StanzaElementName = "stanza"; - internal void Load(XElement xStanza) { if (xStanza == null) { - throw new ArgumentNullException("xStanza"); + throw new ArgumentNullException(nameof(xStanza)); } if (xStanza.Name.LocalName != Fb2StanzaElementName) { - throw new ArgumentException("Element of wrong type passed", "xStanza"); + throw new ArgumentException("Element of wrong type passed", nameof(xStanza)); } Title = null; @@ -41,6 +38,7 @@ internal void Load(XElement xStanza) } catch (Exception) { + // ignored } } @@ -55,10 +53,11 @@ internal void Load(XElement xStanza) } catch (Exception) { + // ignored } } - lines.Clear(); + _lines.Clear(); IEnumerable xLines = xStanza.Elements(xStanza.Name.Namespace + VPoemParagraph.Fb2VParagraphItemName); foreach (var xLine in xLines) { @@ -66,17 +65,17 @@ internal void Load(XElement xStanza) try { vline.Load(xLine); - lines.Add(vline); + _lines.Add(vline); } catch (Exception) { - continue; + // ignored } } Lang = null; XAttribute xLang = xStanza.Attribute(XNamespace.Xml + "lang"); - if ((xLang != null) && (xLang.Value != null)) + if (xLang != null && xLang.Value != null) { Lang = xLang.Value; } @@ -98,12 +97,12 @@ public XNode ToXML() { xStanza.Add(SubTitle.ToXML()); } - foreach (VPoemParagraph PoemLine in lines) + foreach (VPoemParagraph poemLine in _lines) { - xStanza.Add(PoemLine.ToXML()); + xStanza.Add(poemLine.ToXML()); } + return xStanza; - } } } diff --git a/FB2Library/Elements/Poem/VPoemParagraph.cs b/FB2Library/Elements/Poem/VPoemParagraph.cs index 7e396f0..25843ec 100644 --- a/FB2Library/Elements/Poem/VPoemParagraph.cs +++ b/FB2Library/Elements/Poem/VPoemParagraph.cs @@ -1,18 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace FB2Library.Elements.Poem +namespace FB2Library.Elements.Poem { public class VPoemParagraph : ParagraphItem { + internal const string Fb2VParagraphItemName = "v"; + protected override string GetElementName() { return Fb2VParagraphItemName; } - - - internal const string Fb2VParagraphItemName = "v"; } } diff --git a/FB2Library/Elements/SequenceType.cs b/FB2Library/Elements/SequenceType.cs index bd7d9d4..be3820f 100644 --- a/FB2Library/Elements/SequenceType.cs +++ b/FB2Library/Elements/SequenceType.cs @@ -1,30 +1,23 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements { public class SequenceType { - public const string SequenceElementName = "sequence"; - - private readonly List content = new List(); + private const string NameAttributeName = "name"; + private const string NumberAttributeName = "number"; - private XNamespace fileNameSpace = XNamespace.None; + public const string SequenceElementName = "sequence"; + private readonly List _content = new List(); /// /// XML namespace used to read the document /// - public XNamespace Namespace - { - set { fileNameSpace = value; } - get { return fileNameSpace; } - } + public XNamespace Namespace { get; set; } = XNamespace.None; /// /// Get/Set name of the sequence @@ -36,52 +29,42 @@ public XNamespace Namespace /// public int? Number { get; set; } - /// /// Get/Set language /// public string Language { get; set; } - - /// - /// Get subsection list - /// - public List SubSections { get { return content; } } - public void Load(XElement xElement) { if (xElement == null) { - throw new ArgumentNullException("xElement"); + throw new ArgumentNullException(nameof(xElement)); } - if (xElement.Name.LocalName != SequenceElementName) { - throw new ArgumentException("Element of wrong type passed", "xElement"); + throw new ArgumentException("Element of wrong type passed", nameof(xElement)); } - // read all subsecquences - content.Clear(); - IEnumerable subElements = xElement.Elements(fileNameSpace + SequenceElementName); - foreach (var element in subElements) + // read all subsequences + _content.Clear(); + foreach (var element in xElement.Elements(Namespace + SequenceElementName)) { var subElement = new SequenceType(); try { subElement.Load(element); - content.Add(subElement); + _content.Add(subElement); } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading sequence element: {0}",ex.Message)); - continue; + Debug.WriteLine($"Error reading sequence element: {ex.Message}"); } } // read "name" attribute Name = null; - XAttribute xName = xElement.Attribute("name"); - if (xName != null &&(!string.IsNullOrEmpty(xName.Value))) + XAttribute xName = xElement.Attribute(NameAttributeName); + if (xName != null && !string.IsNullOrEmpty(xName.Value)) { Name = xName.Value; } @@ -92,23 +75,22 @@ public void Load(XElement xElement) // read number attribute Number = null; - XAttribute xNumber = xElement.Attribute("number"); - if ((xNumber != null)&&(!string.IsNullOrEmpty(xNumber.Value))) + XAttribute xNumber = xElement.Attribute(NumberAttributeName); + if (xNumber != null && !string.IsNullOrEmpty(xNumber.Value)) { - int value; - if (int.TryParse(xNumber.Value,out value)) + if (int.TryParse(xNumber.Value, out var value)) { Number = value; } } + // read lang attribute Language = null; XAttribute xLang = xElement.Attribute(XNamespace.Xml + "lang"); if (xLang != null && string.IsNullOrEmpty(xLang.Value)) { Language = xLang.Value; } - } public XElement ToXML() @@ -116,19 +98,19 @@ public XElement ToXML() XElement xSequence = new XElement(Fb2Const.fb2DefaultNamespace + SequenceElementName); if (!string.IsNullOrEmpty(Name)) { - xSequence.Add(new XAttribute("name", Name)); + xSequence.Add(new XAttribute(NameAttributeName, Name)); } if (Number != null) { - xSequence.Add(new XAttribute("number",Number)); + xSequence.Add(new XAttribute(NumberAttributeName, Number)); } if (!string.IsNullOrEmpty(Language)) { xSequence.Add(new XAttribute(XNamespace.Xml + "lang", Language)); } - foreach(SequenceType SubSeq in content) + foreach (SequenceType subSequence in _content) { - xSequence.Add(SubSeq.ToXML()); + xSequence.Add(subSequence.ToXML()); } return xSequence; diff --git a/FB2Library/Elements/ShareInstructionType.cs b/FB2Library/Elements/ShareInstructionType.cs index 30dfd71..bec9a50 100644 --- a/FB2Library/Elements/ShareInstructionType.cs +++ b/FB2Library/Elements/ShareInstructionType.cs @@ -1,9 +1,6 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements @@ -14,7 +11,6 @@ public interface IShareInstructionElement XElement ToXML(); } - public enum GenerationInstructionEnum { Unknown, @@ -28,22 +24,24 @@ public enum GenerationInstructionEnum /// public class ShareInstructionType { + public const string ShareInstructionElementName = "output"; + public enum ShareModeEnum { Unknown, Free, Paid, } - - private List content = new List(); + private readonly List _content = new List(); + + private XNamespace _fileNameSpace = XNamespace.None; /// /// Get/Set Modes for document sharing /// public ShareModeEnum SharedMode { get; set; } - /// /// Get/Set instructions to process sections /// @@ -59,73 +57,70 @@ public enum ShareModeEnum /// public string Currency { get; set; } - public const string ShareInstructionElementName = "output"; - - private XNamespace fileNameSpace = XNamespace.None; - /// /// XML namespace used to read the document /// public XNamespace Namespace { - set { fileNameSpace = value; } - get { return fileNameSpace; } + set { _fileNameSpace = value; } + get { return _fileNameSpace; } } /// /// Get list of content elements /// - public List Content { get { return content; } } + public List Content => _content; public void Load(XElement xElement) { if (xElement == null) { - throw new ArgumentNullException("xElement"); + throw new ArgumentNullException(nameof(xElement)); } if (xElement.Name.LocalName != ShareInstructionElementName) { - throw new ArgumentException(string.Format("Wrong element name: {0} instead of {1}",xElement.Name.LocalName,ShareInstructionElementName)); + throw new ArgumentException( + $"Wrong element name: {xElement.Name.LocalName} instead of {ShareInstructionElementName}"); } - content.Clear(); + _content.Clear(); IEnumerable xElements = xElement.Elements(); foreach (var element in xElements) { if (element.Name.LocalName == PartShareInstructionType.PartElementName) { - PartShareInstructionType part = new PartShareInstructionType{Namespace = fileNameSpace}; + PartShareInstructionType part = new PartShareInstructionType{Namespace = _fileNameSpace}; try { part.Load(element); - content.Add(part); + _content.Add(part); } catch (Exception ex) { - Debug.WriteLine(string.Format("Error loading part type: {0}",ex.Message)); + Debug.WriteLine($"Error loading part type: {ex.Message}"); } } else if (element.Name.LocalName == OutPutDocumentType.OutputDocumentElementName) { - OutPutDocumentType doc = new OutPutDocumentType{Namespace = fileNameSpace}; + OutPutDocumentType doc = new OutPutDocumentType{Namespace = _fileNameSpace}; try { doc.Load(element); - content.Add(doc); + _content.Add(doc); } catch (Exception ex) { - Debug.WriteLine(string.Format("Error loading output document type: {0}", ex.Message)); + Debug.WriteLine($"Error loading output document type: {ex.Message}"); } } else { - Debug.WriteLine(string.Format("Invalid element type encoutered {0}", element.Name.LocalName)); + Debug.WriteLine($"Invalid element type encoutered {element.Name.LocalName}"); } } XAttribute xSharedMode = xElement.Attribute("mode"); - if ((xSharedMode == null) || string.IsNullOrEmpty(xSharedMode.Value) ) + if (xSharedMode == null || string.IsNullOrEmpty(xSharedMode.Value)) { Debug.WriteLine("mode attribute is required attribute"); } @@ -140,14 +135,14 @@ public void Load(XElement xElement) SharedMode = ShareModeEnum.Paid; break; default: - Debug.WriteLine(string.Format("Invalid shared mode type : {0}", xSharedMode.Value)); + Debug.WriteLine($"Invalid shared mode type : {xSharedMode.Value}"); break; } } XAttribute xIncludeAll = xElement.Attribute("include-all"); - if ((xIncludeAll == null) || string.IsNullOrEmpty(xIncludeAll.Value)) + if (xIncludeAll == null || string.IsNullOrEmpty(xIncludeAll.Value)) { Debug.WriteLine("mode attribute is required attribute"); } @@ -165,7 +160,7 @@ public void Load(XElement xElement) Instruction = GenerationInstructionEnum.Deny; break; default: - Debug.WriteLine(string.Format("Invalid instruction type : {0}", xIncludeAll.Value)); + Debug.WriteLine($"Invalid instruction type : {xIncludeAll.Value}"); break; } } @@ -235,12 +230,11 @@ public XElement ToXML() { xShareInstruction.Add(new XAttribute("currency", Currency)); } - foreach (IShareInstructionElement ShareElement in content) + foreach (IShareInstructionElement shareElement in _content) { - xShareInstruction.Add(ShareElement.ToXML()); + xShareInstruction.Add(shareElement.ToXML()); } - return xShareInstruction; } } diff --git a/FB2Library/Elements/StyleItem.cs b/FB2Library/Elements/StyleItem.cs new file mode 100644 index 0000000..b3fca92 --- /dev/null +++ b/FB2Library/Elements/StyleItem.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Xml.Linq; + +namespace FB2Library.Elements +{ + /// + /// Represents FB2 style tag + /// + public class StyleItem : IFb2TextItem, StyleType + { + internal const string StyleItemName = "style"; + + /// + /// Get/Set name of the sequence + /// + public string Name { get; set; } + /// + /// Get/Set language + /// + public string Lang { get; set; } + public List StyleData { get; set; } = new List(); + protected virtual string GetElementName() + { + return StyleItemName; + } + public override string ToString() + { + StringBuilder builder = new StringBuilder($""); + return builder.ToString(); + } + /// + /// Load element data from the node + /// + /// + public void Load(XElement xStyle) + { + if (xStyle == null) + { + throw new ArgumentNullException("style"); + } + if (xStyle.Name.LocalName != StyleItemName) + { + throw new ArgumentException(string.Format("The element is of type {0} while StyleItem accepts only {1} types", xStyle.Name.LocalName, StyleItemName)); + } + + Lang = null; + XAttribute xLang = xStyle.Attribute(XNamespace.Xml + "lang"); + if (xLang != null) + { + Lang = xLang.Value; + } + + Name = string.Empty; + XAttribute xName = xStyle.Attribute("name"); + if (xName != null && xName.Value != null) + { + Name = xName.Value; + } + + if (xStyle.HasElements) + { + IEnumerable childElements = xStyle.Nodes(); + foreach (var element in childElements) + { + if ((element.NodeType == XmlNodeType.Element) && !IsSimpleText(element)) + { + XElement xElement = (XElement)element; + if (xElement.Name.LocalName == InlineImageItem.Fb2InlineImageElementName) + { + InlineImageItem image = new InlineImageItem(); + try + { + image.Load(xElement); + StyleData.Add(image); + } + catch (Exception) + { + } + } + else if (xElement.Name.LocalName == InternalLinkItem.Fb2InternalLinkElementName) + { + InternalLinkItem linkItem = new InternalLinkItem(); + try + { + linkItem.Load(xElement); + StyleData.Add(linkItem); + } + catch (Exception) + { + } + } + else if (xElement.Name.LocalName == StyleItemName) + { + StyleItem styleItem = new StyleItem(); + try + { + styleItem.Load(xElement); + StyleData.Add(styleItem); + } + catch (Exception) + { + } + } + } + else + { + SimpleText text = new SimpleText(); + try + { + text.Load(element); + StyleData.Add(text); + } + catch (Exception) + { + } + } + } + + } + else if (!string.IsNullOrEmpty(xStyle.Value)) + { + SimpleText text = new SimpleText(); + text.Load(xStyle); + StyleData.Add(text); + } + } + private bool IsSimpleText(XNode element) + { + // if not element than we assume simple text + if (element.NodeType != XmlNodeType.Element) + { + return true; + } + XElement xElement = (XElement)element; + switch (xElement.Name.LocalName) + { + case InternalLinkItem.Fb2InternalLinkElementName: + case InlineImageItem.Fb2InlineImageElementName: + case StyleItem.StyleItemName: + return false; + } + return true; + } + public XNode ToXML() + { + if (Name == null || string.IsNullOrEmpty(Name)) + { + throw new Exception("Name attribute is required by standard"); + } + XElement xStyle = new XElement(Fb2Const.fb2DefaultNamespace + StyleItemName, new XAttribute("name", Name)); + if (!string.IsNullOrEmpty(Lang)) + { + xStyle.Add(new XAttribute(XNamespace.Xml + "lang", Lang)); + } + foreach (StyleType childElements in StyleData) + { + xStyle.Add(childElements.ToXML()); + } + return xStyle; + } + } +} diff --git a/FB2Library/Elements/SubTitleItem.cs b/FB2Library/Elements/SubTitleItem.cs index 0b4ff73..d35da9c 100644 --- a/FB2Library/Elements/SubTitleItem.cs +++ b/FB2Library/Elements/SubTitleItem.cs @@ -1,17 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace FB2Library.Elements +namespace FB2Library.Elements { public class SubTitleItem : ParagraphItem { + internal const string Fb2SubtitleElementName = "subtitle"; + protected override string GetElementName() { return Fb2SubtitleElementName; } - - internal const string Fb2SubtitleElementName = "subtitle"; } } diff --git a/FB2Library/Elements/TextAuthorItem.cs b/FB2Library/Elements/TextAuthorItem.cs index 2f759ed..25e59c2 100644 --- a/FB2Library/Elements/TextAuthorItem.cs +++ b/FB2Library/Elements/TextAuthorItem.cs @@ -1,17 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace FB2Library.Elements +namespace FB2Library.Elements { public class TextAuthorItem : ParagraphItem { + internal const string Fb2TextAuthorElementName = "text-author"; + protected override string GetElementName() { return Fb2TextAuthorElementName; } - - internal const string Fb2TextAuthorElementName = "text-author"; } } \ No newline at end of file diff --git a/FB2Library/Elements/TextFieldType.cs b/FB2Library/Elements/TextFieldType.cs index 39c89f7..4878be5 100644 --- a/FB2Library/Elements/TextFieldType.cs +++ b/FB2Library/Elements/TextFieldType.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Linq; namespace FB2Library.Elements @@ -32,7 +29,7 @@ public virtual void Load(XElement xElement) { if (xElement == null) { - throw new ArgumentNullException("xElement"); + throw new ArgumentNullException(nameof(xElement)); } Text = string.Empty; if (!string.IsNullOrEmpty(xElement.Value)) @@ -41,7 +38,7 @@ public virtual void Load(XElement xElement) } Language = null; - //глянуть + // TODO: глянуть XAttribute xLang = xElement.Attribute(XNamespace.Xml + "lang"); if (xLang != null && string.IsNullOrEmpty(xLang.Value)) { @@ -49,9 +46,9 @@ public virtual void Load(XElement xElement) } } - public virtual XElement ToXML(string NameElement) + public virtual XElement ToXML(string nameElement) { - XElement xText = new XElement(Fb2Const.fb2DefaultNamespace + NameElement, Text); + XElement xText = new XElement(Fb2Const.fb2DefaultNamespace + nameElement, Text); if (Language != null) { xText.Add(new XAttribute(XNamespace.Xml + "lang",Language)); diff --git a/FB2Library/Elements/TitleItem.cs b/FB2Library/Elements/TitleItem.cs index e97a580..0e6f886 100644 --- a/FB2Library/Elements/TitleItem.cs +++ b/FB2Library/Elements/TitleItem.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Text; using System.Xml.Linq; @@ -9,19 +8,17 @@ namespace FB2Library.Elements { public class TitleItem : IFb2TextItem { - private readonly List titleData = new List(); + internal const string Fb2TitleElementName = "title"; - public List TitleData - { - get { return titleData; } - } + private readonly List _titleData = new List(); + + public List TitleData => _titleData; /// /// Language attribute /// public string LangAttribute { get; set; } - public override string ToString() { StringBuilder builder = new StringBuilder(); @@ -33,53 +30,49 @@ public override string ToString() return builder.ToString(); } - - internal const string Fb2TitleElementName = "title"; - internal void Load(XElement xTitle) { - titleData.Clear(); + _titleData.Clear(); if (xTitle == null) { - throw new ArgumentNullException("xTitle"); + throw new ArgumentNullException(nameof(xTitle)); } if (xTitle.Name.LocalName != Fb2TitleElementName) { - throw new ArgumentException("Element of wrong type passed", "xTitle"); + throw new ArgumentException("Element of wrong type passed", nameof(xTitle)); } - IEnumerable subElements = xTitle.Elements(); foreach (var element in subElements) { switch (element.Name.LocalName) { case EmptyLineItem.Fb2EmptyLineElementName: - titleData.Add(new EmptyLineItem()); + _titleData.Add(new EmptyLineItem()); break; case ParagraphItem.Fb2ParagraphElementName: ParagraphItem paragraph = new ParagraphItem(); try { paragraph.Load(element); - titleData.Add(paragraph); + _titleData.Add(paragraph); } catch (Exception ex) { - Debug.WriteLine(string.Format("Failed to load paragraph: {0}.",ex.Message)); + Debug.WriteLine($"Failed to load paragraph: {ex.Message}."); } break; default: - Debug.WriteLine(string.Format("TitleItem:Load - invalid element <{0}> encountered in title ."), element.Name.LocalName); + Debug.WriteLine( + $"TitleItem:Load - invalid element <{element.Name.LocalName}> encountered in title ."); break; } - } LangAttribute = null; XAttribute xLang = xTitle.Attribute(XNamespace.Xml + "lang"); - if ((xLang != null) && !string.IsNullOrEmpty(xLang.Value)) + if (xLang != null && !string.IsNullOrEmpty(xLang.Value)) { LangAttribute = xLang.Value; } @@ -92,9 +85,9 @@ public XNode ToXML() xTitle.Add(new XAttribute(XNamespace.Xml + "lang", LangAttribute)); } - foreach (IFb2TextItem TitleItem in titleData) + foreach (IFb2TextItem titleItem in _titleData) { - xTitle.Add(TitleItem.ToXML()); + xTitle.Add(titleItem.ToXML()); } return xTitle; } diff --git a/FB2Library/FB2File.cs b/FB2Library/FB2File.cs index ba53dd7..01d6267 100644 --- a/FB2Library/FB2File.cs +++ b/FB2Library/FB2File.cs @@ -10,8 +10,6 @@ namespace FB2Library { public class FB2File { - private XNamespace _fileNameSpace = XNamespace.None; - private const string TitleInfoElementName = "title-info"; private const string SrcTitleInfoElementName = "src-title-info"; private const string DocumentInfoElementName = "document-info"; @@ -19,67 +17,63 @@ public class FB2File private const string Fb2TextBodyElementName = "body"; private const string Fb2BinaryElementName = "binary"; - private readonly ItemTitleInfo _titleInfo = new ItemTitleInfo(); private readonly ItemTitleInfo _srcTitleInfo = new ItemTitleInfo(); private readonly ItemDocumentInfo _documentInfo = new ItemDocumentInfo(); private readonly ItemPublishInfo _publishInfo = new ItemPublishInfo(); private readonly List _customInfo = new List(); - private BodyItem _mainBody; private readonly List _bodiesList = new List(); private readonly Dictionary _binaryObjects = new Dictionary(); private readonly List _styles = new List(); private readonly List _output = new List(); - - + private BodyItem _mainBody; + private XNamespace _fileNameSpace = XNamespace.None; + /// /// Get list of images (the image data itself) stored as binary objects /// - public Dictionary Images { get { return _binaryObjects;} } - + public Dictionary Images => _binaryObjects; /// /// Get list of bodies in document (including main) /// - public List Bodies { get { return _bodiesList;}} + public List Bodies => _bodiesList; /// /// Get Document TitleInfo structure /// - public ItemTitleInfo TitleInfo { get { return _titleInfo; } } + public ItemTitleInfo TitleInfo => _titleInfo; /// /// Get Document DocumentInfo structure /// - public ItemDocumentInfo DocumentInfo { get { return _documentInfo; } } + public ItemDocumentInfo DocumentInfo => _documentInfo; /// /// Get Document SourceTitleInfo structure /// - public ItemTitleInfo SourceTitleInfo { get { return _srcTitleInfo; } } - + public ItemTitleInfo SourceTitleInfo => _srcTitleInfo; /// /// Get custom added information (if available) /// - public List CustomInfo { get { return _customInfo; } } + public List CustomInfo => _customInfo; /// /// Get Document PublishInfo structure /// - public ItemPublishInfo PublishInfo { get { return _publishInfo; } } + public ItemPublishInfo PublishInfo => _publishInfo; /// /// Get main body structure (book itself) /// - public BodyItem MainBody { get { return _mainBody; } } + public BodyItem MainBody => _mainBody; /// /// Get styles applied to the book /// - public List StyleSheets { get { return _styles; } } - + public List StyleSheets => _styles; /// /// Loads the file as data from XML data @@ -90,20 +84,18 @@ public void Load(XDocument fileDocument,bool loadHeaderOnly) { if (fileDocument == null) { - throw new ArgumentNullException("fileDocument"); + throw new ArgumentNullException(nameof(fileDocument)); } if (fileDocument.Root == null) { throw new ArgumentException("Document's root is NULL (empty document passed)"); } - // theoretically the namespace should be "http://www.gribuser.ru/xml/fictionbook/2.0" but just to be sure with invalid files _fileNameSpace = fileDocument.Root.GetDefaultNamespace(); - _styles.Clear(); - IEnumerable xStyles = fileDocument.Elements(_fileNameSpace + StyleElement.StyleElementName).ToArray(); + IEnumerable xStyles = fileDocument.Root.Elements(_fileNameSpace + StyleElement.StyleElementName).ToArray(); // attempt to load some bad FB2 with wrong namespace if (!xStyles.Any()) { @@ -131,16 +123,16 @@ public void Load(XDocument fileDocument,bool loadHeaderOnly) // Load body elements (first is main text) if (fileDocument.Root != null) { - IEnumerable xBodys = fileDocument.Root.Elements(_fileNameSpace + Fb2TextBodyElementName).ToArray(); + IEnumerable xBodyElements = fileDocument.Root.Elements(_fileNameSpace + Fb2TextBodyElementName).ToArray(); // try to read some badly formatted FB2 files - if (!xBodys.Any()) + if (!xBodyElements.Any()) { namespaceUsed = ""; - xBodys = fileDocument.Root.Elements(namespaceUsed + Fb2TextBodyElementName); + xBodyElements = fileDocument.Root.Elements(namespaceUsed + Fb2TextBodyElementName); } - foreach (var body in xBodys) + foreach (var body in xBodyElements) { - var bodyItem = new BodyItem() { NameSpace = namespaceUsed }; + var bodyItem = new BodyItem { NameSpace = namespaceUsed }; try { bodyItem.Load(body); @@ -161,17 +153,17 @@ public void Load(XDocument fileDocument,bool loadHeaderOnly) // Load binaries sections (currently images only) if (fileDocument.Root != null) { - IEnumerable xBinaryes = fileDocument.Root.Elements(namespaceUsed + Fb2BinaryElementName).ToArray(); - if (!xBinaryes.Any()) + IEnumerable xBinaryElements = fileDocument.Root.Elements(namespaceUsed + Fb2BinaryElementName).ToArray(); + if (!xBinaryElements.Any()) { - xBinaryes = fileDocument.Root.Elements(Fb2BinaryElementName); + xBinaryElements = fileDocument.Root.Elements(Fb2BinaryElementName); } - foreach (var binarye in xBinaryes) + foreach (var binaryElement in xBinaryElements) { var item = new BinaryItem(); try { - item.Load(binarye); + item.Load(binaryElement); } catch { @@ -192,7 +184,7 @@ private void LoadDescriptionSection(XDocument fileDocument, bool loadBinaryItems { if (fileDocument == null) { - throw new ArgumentNullException("fileDocument"); + throw new ArgumentNullException(nameof(fileDocument)); } if (fileDocument.Root == null) { @@ -312,23 +304,22 @@ private void LoadDescriptionSection(XDocument fileDocument, bool loadBinaryItems if (loadBinaryItems && _titleInfo.Cover != null) { - foreach (InlineImageItem coverImag in _titleInfo.Cover.CoverpageImages) { if (string.IsNullOrEmpty(coverImag.HRef)) { continue; } - string coverref = coverImag.HRef.Substring(0, 1) == "#" ? coverImag.HRef.Substring(1) : coverImag.HRef; - IEnumerable xBinaryes = + string coverRef = coverImag.HRef.Substring(0, 1) == "#" ? coverImag.HRef.Substring(1) : coverImag.HRef; + IEnumerable xBinaryElements = fileDocument.Root.Elements(_fileNameSpace + Fb2BinaryElementName).Where( - cov => ((cov.Attribute("id") != null) && (cov.Attribute("id").Value == coverref))); - foreach (var binarye in xBinaryes) + cov => ((cov.Attribute("id") != null) && (cov.Attribute("id").Value == coverRef))); + foreach (var binaryElement in xBinaryElements) { var item = new BinaryItem(); try { - item.Load(binarye); + item.Load(binaryElement); } catch (Exception) { @@ -432,8 +423,8 @@ public XDocument ToXML(bool bExportHeaderOnly) { continue; } - string coverref = coverImag.HRef.Substring(0, 1) == "#" ? coverImag.HRef.Substring(1) : coverImag.HRef; - xFictionBook.Add(_binaryObjects[coverref].ToXML()); + string coverRef = coverImag.HRef.Substring(0, 1) == "#" ? coverImag.HRef.Substring(1) : coverImag.HRef; + xFictionBook.Add(_binaryObjects[coverRef].ToXML()); } } diff --git a/FB2Library/HeaderItems/CoverPage.cs b/FB2Library/HeaderItems/CoverPage.cs index 2d1d877..4fb9782 100644 --- a/FB2Library/HeaderItems/CoverPage.cs +++ b/FB2Library/HeaderItems/CoverPage.cs @@ -7,67 +7,66 @@ namespace FB2Library.HeaderItems { public class CoverPage { - private readonly List coverimages = new List(); + internal const string Fb2CoverPageImageElementName = "coverpage"; - private XNamespace fileNameSpace = XNamespace.None; + private readonly List _coverImages = new List(); - internal const string Fb2CoverpageImageElementName = "coverpage"; + private XNamespace _fileNameSpace = XNamespace.None; protected string GetElementName() { - return Fb2CoverpageImageElementName; + return Fb2CoverPageImageElementName; } + public List CoverpageImages => _coverImages; - public List CoverpageImages { get { return coverimages; } } - - public bool HasImages() { return (coverimages.Count > 0); } + public bool HasImages() => _coverImages.Count > 0; /// /// XML namespace used to read the document /// public XNamespace Namespace { - set { fileNameSpace = value; } - get { return fileNameSpace; } + set { _fileNameSpace = value; } + get { return _fileNameSpace; } } - internal void Load(XElement xCoverpage) + internal void Load(XElement xCoverPage) { - if (xCoverpage == null) + if (xCoverPage == null) { - throw new ArgumentNullException("xCoverpage"); + throw new ArgumentNullException(nameof(xCoverPage)); } - if (xCoverpage.Name.LocalName != GetElementName()) + if (xCoverPage.Name.LocalName != GetElementName()) { - throw new ArgumentException("Element of wrong type passed", "xCoverpage"); + throw new ArgumentException("Element of wrong type passed", nameof(xCoverPage)); } - coverimages.Clear(); - IEnumerable xImages = xCoverpage.Elements(fileNameSpace +InlineImageItem.Fb2InlineImageElementName); + _coverImages.Clear(); + IEnumerable xImages = xCoverPage.Elements(_fileNameSpace +InlineImageItem.Fb2InlineImageElementName); foreach (var xImage in xImages) { InlineImageItem image = new InlineImageItem(); try { image.Load(xImage); - coverimages.Add(image); + _coverImages.Add(image); } catch (Exception) { + // ignore } - } } public XElement ToXML() { - XElement xCover = new XElement(Fb2Const.fb2DefaultNamespace + Fb2CoverpageImageElementName); - foreach (InlineImageItem ImageItem in coverimages) + XElement xCover = new XElement(Fb2Const.fb2DefaultNamespace + Fb2CoverPageImageElementName); + foreach (InlineImageItem imageItem in _coverImages) { - xCover.Add(ImageItem.ToXML()); + xCover.Add(imageItem.ToXML()); } return xCover; diff --git a/FB2Library/HeaderItems/ItemDocumentInfo.cs b/FB2Library/HeaderItems/ItemDocumentInfo.cs index 61f85ef..2fbfb3c 100644 --- a/FB2Library/HeaderItems/ItemDocumentInfo.cs +++ b/FB2Library/HeaderItems/ItemDocumentInfo.cs @@ -5,7 +5,6 @@ using FB2Library.Elements; using System.Globalization; - namespace FB2Library.HeaderItems { /// @@ -55,28 +54,22 @@ public IEnumerable SourceURLs /// List of document authors, /// note this is NOT book authors but document creators /// - public List DocumentAuthors - { - get { return this._documentAuthors; } - } + public List DocumentAuthors => _documentAuthors; /// /// Owners of the fb2 document copyrights /// - public List DocumentPublishers - { - get { return this._documentPublishers; } - } + public List DocumentPublishers => _documentPublishers; /// /// Text specifiying program used to create the document /// - public TextFieldType ProgramUsed2Create { set; get; } + public TextFieldType ProgramUsed2Create { get; set; } /// /// Date of the document creation /// - public DateItem DocumentDate { set; get; } + public DateItem DocumentDate { get; set; } /// /// Document's UID @@ -119,7 +112,7 @@ internal void Load(XElement xDocumentInfo) { if (xDocumentInfo == null) { - throw new ArgumentNullException("xDocumentInfo"); + throw new ArgumentNullException(nameof(xDocumentInfo)); } @@ -138,7 +131,7 @@ internal void Load(XElement xDocumentInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading document authors : {0}",ex.Message)); + Debug.WriteLine($"Error reading document authors : {ex.Message}"); continue; } } @@ -156,7 +149,7 @@ internal void Load(XElement xDocumentInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading program used to create : {0}", ex.Message)); + Debug.WriteLine($"Error reading program used to create : {ex.Message}"); } } @@ -172,7 +165,7 @@ internal void Load(XElement xDocumentInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading document date : {0}", ex.Message)); + Debug.WriteLine($"Error reading document date : {ex.Message}"); } } @@ -203,7 +196,7 @@ internal void Load(XElement xDocumentInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading source OCR : {0}", ex.Message)); + Debug.WriteLine($"Error reading source OCR : {ex.Message}"); } } diff --git a/FB2Library/HeaderItems/ItemInfoBase.cs b/FB2Library/HeaderItems/ItemInfoBase.cs index 6d42bfe..08a50ab 100644 --- a/FB2Library/HeaderItems/ItemInfoBase.cs +++ b/FB2Library/HeaderItems/ItemInfoBase.cs @@ -10,11 +10,10 @@ public class ItemInfoBase protected XNamespace FileNameSpace = XNamespace.None; - /// /// Get list of sequences /// - public List Sequences { get { return ItemSequences; } } + public List Sequences => ItemSequences; /// /// XML namespace used to read the document @@ -28,7 +27,6 @@ public XNamespace Namespace /// /// Book Title /// - public TextFieldType BookTitle { set; get; } - + public TextFieldType BookTitle { get; set; } } } diff --git a/FB2Library/HeaderItems/ItemPublishInfo.cs b/FB2Library/HeaderItems/ItemPublishInfo.cs index 59b5472..105e79c 100644 --- a/FB2Library/HeaderItems/ItemPublishInfo.cs +++ b/FB2Library/HeaderItems/ItemPublishInfo.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Xml.Linq; using FB2Library.Elements; @@ -19,7 +18,6 @@ public class ItemPublishInfo : ItemInfoBase public const string PublishInfoElementName = "publish-info"; - /// /// ISBN of original book /// @@ -40,18 +38,17 @@ public class ItemPublishInfo : ItemInfoBase /// public TextFieldType Publisher { get; set; } - internal void Load(XElement xPublishInfo) { if (xPublishInfo == null) { - throw new ArgumentNullException("xPublishInfo"); + throw new ArgumentNullException(nameof(xPublishInfo)); } // Load book name BookTitle = null; XElement xBookName = xPublishInfo.Element(FileNameSpace + BookNameElementName); - if ( xBookName != null) + if (xBookName != null) { BookTitle = new TextFieldType(); try @@ -60,7 +57,7 @@ internal void Load(XElement xPublishInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading publisher book name : {0}", ex.Message)); + Debug.WriteLine($"Error reading publisher book name : {ex.Message}"); } } @@ -76,7 +73,7 @@ internal void Load(XElement xPublishInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading publishers : {0}", ex.Message)); + Debug.WriteLine($"Error reading publishers : {ex.Message}"); } } @@ -92,21 +89,19 @@ internal void Load(XElement xPublishInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading publishers' City: {0}", ex.Message)); + Debug.WriteLine($"Error reading publishers' City: {ex.Message}"); } } // Load year Year = null; XElement xYear = xPublishInfo.Element(FileNameSpace + YearElementName); - if ( (xYear != null)) + if (xYear != null) { - int year; - if ( int.TryParse( xYear.Value,out year) ) + if (int.TryParse( xYear.Value, out var year)) { Year = year; } - } // Load ISBN @@ -121,27 +116,25 @@ internal void Load(XElement xPublishInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading publishers' ISBN: {0}", ex.Message)); + Debug.WriteLine($"Error reading publishers' ISBN: {ex.Message}"); } } // Load sequence here ItemSequences.Clear(); - IEnumerable xSequences = xPublishInfo.Elements(FileNameSpace + SequenceType.SequenceElementName); - foreach (var xSequence in xSequences) + foreach (var xSequence in xPublishInfo.Elements(FileNameSpace + SequenceType.SequenceElementName)) { var sec = new SequenceType(); try { sec.Load(xSequence); + ItemSequences.Add(sec); } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading publisher sequence data: {0}", ex.Message)); - continue; + Debug.WriteLine($"Error reading publisher sequence data: {ex.Message}"); } } - } public XElement ToXML() @@ -175,6 +168,5 @@ public XElement ToXML() return xPublishInfo; } - - }// class + } } diff --git a/FB2Library/HeaderItems/ItemTitleInfo.cs b/FB2Library/HeaderItems/ItemTitleInfo.cs index 01998a8..30e4e93 100644 --- a/FB2Library/HeaderItems/ItemTitleInfo.cs +++ b/FB2Library/HeaderItems/ItemTitleInfo.cs @@ -25,88 +25,70 @@ public class ItemTitleInfo : ItemInfoBase private const string SourceLanguageElementName = "src-lang"; private readonly List _genres = new List(); - private readonly List _translators = new List(); - private readonly List _bookAuthors = new List(); - - - - /// /// Translators if this is a translation /// - public IEnumerable Translators - { - get { return _translators; } - } + public IEnumerable Translators => _translators; /// /// Book's source language if this is a translation /// - public string SrcLanguage { get; set; } + public string SrcLanguage { get; private set; } /// /// Keywords used by search engine /// - public TextFieldType Keywords { get; set; } + public TextFieldType Keywords { get; private set; } /// /// Genres of the item /// - public IEnumerable Genres - { - get { return _genres; } - } - + public IEnumerable Genres => _genres; /// /// Authors of this book /// - public IEnumerable BookAuthors - { - get { return _bookAuthors; } - } - + public IEnumerable BookAuthors => _bookAuthors; /// /// Book's annotation /// - public AnnotationItem Annotation { set; get; } + public AnnotationItem Annotation { set; private get; } /// /// Book date , can be a range like 1990-1991 /// - public DateItem BookDate { get; set; } + public DateItem BookDate { get; private set; } /// /// Book's language /// - public string Language { set; get; } + public string Language { set; private get; } - public CoverPage Cover { get; set; } + public CoverPage Cover { get; private set; } public void Load(XElement xTitleInfo) { - if ( xTitleInfo == null ) + if (xTitleInfo == null) { - throw new ArgumentNullException("xTitleInfo"); + throw new ArgumentNullException(nameof(xTitleInfo)); } // Load genres _genres.Clear(); IEnumerable xGenres = xTitleInfo.Elements(FileNameSpace + GenreElementName); - foreach ( XElement xGenre in xGenres ) + foreach (XElement xGenre in xGenres) { - if ( (xGenre != null) ) + if (xGenre != null) { - var genre = new TitleGenreType {Genre = xGenre.Value}; + var genre = new TitleGenreType { Genre = xGenre.Value }; XAttribute xMatch = xGenre.Attribute("match"); if (xMatch != null && !string.IsNullOrEmpty(xMatch.Value)) { - int percentage; - if (int.TryParse(xMatch.Value,out percentage)) + if (int.TryParse(xMatch.Value, out var percentage)) { genre.Match = percentage; } @@ -128,8 +110,7 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading author: {0}",ex.Message)); - continue; + Debug.WriteLine($"Error reading author: {ex.Message}"); } } @@ -146,7 +127,7 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading book title: {0}", ex.Message)); + Debug.WriteLine($"Error reading book title: {ex.Message}"); } } @@ -162,11 +143,10 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading annotation: {0}", ex.Message)); + Debug.WriteLine($"Error reading annotation: {ex.Message}"); } } - // Load keywords Keywords = null; XElement xKeywords = xTitleInfo.Element(FileNameSpace + KeywordsElementName); @@ -179,7 +159,7 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading keywords: {0}", ex.Message)); + Debug.WriteLine($"Error reading keywords: {ex.Message}"); } } @@ -195,7 +175,7 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading book date: {0}", ex.Message)); + Debug.WriteLine($"Error reading book date: {ex.Message}"); } } @@ -211,14 +191,14 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading cover: {0}", ex.Message)); + Debug.WriteLine($"Error reading cover: {ex.Message}"); } } // Load Language Language = null; XElement xLanguage = xTitleInfo.Element(FileNameSpace + LanguageElementName); - if ( (xLanguage != null)) + if (xLanguage != null) { Language = xLanguage.Value; } @@ -230,7 +210,7 @@ public void Load(XElement xTitleInfo) // Load source language SrcLanguage = null; XElement xSrcLanguage = xTitleInfo.Element(FileNameSpace + SourceLanguageElementName); - if ( (xSrcLanguage != null) ) + if (xSrcLanguage != null) { SrcLanguage = xSrcLanguage.Value; } @@ -248,8 +228,7 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading translator: {0}", ex.Message)); - continue; + Debug.WriteLine($"Error reading translator: {ex.Message}"); } } @@ -258,7 +237,7 @@ public void Load(XElement xTitleInfo) IEnumerable xSequences = xTitleInfo.Elements(FileNameSpace + SequenceType.SequenceElementName); foreach (var xSequence in xSequences) { - var sec = new SequenceType{ Namespace = FileNameSpace }; + var sec = new SequenceType { Namespace = FileNameSpace }; try { sec.Load(xSequence); @@ -266,8 +245,7 @@ public void Load(XElement xTitleInfo) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error reading sequence data: {0}",ex.Message)); - continue; + Debug.WriteLine($"Error reading sequence data: {ex.Message}"); } } } @@ -283,8 +261,7 @@ public XElement ToXML(string nameElement) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error converting genre data to XML: {0}", ex.Message)); - continue; + Debug.WriteLine($"Error converting genre data to XML: {ex.Message}"); } } foreach (AuthorType author in _bookAuthors) @@ -295,8 +272,7 @@ public XElement ToXML(string nameElement) } catch (Exception ex) { - Debug.WriteLine(string.Format("Error converting genre data to XML: {0}", ex.Message)); - continue; + Debug.WriteLine($"Error converting genre data to XML: {ex.Message}"); } } @@ -340,6 +316,5 @@ public XElement ToXML(string nameElement) return xTitleInfo; } - - } // class + } } diff --git a/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj b/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj new file mode 100644 index 0000000..2cf4206 --- /dev/null +++ b/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj @@ -0,0 +1,20 @@ + + + + Exe + net6.0 + enable + enable + 10.0 + + + + + + + + + + + + diff --git a/FBLibrary.Sample.ConsoleApp/Program.cs b/FBLibrary.Sample.ConsoleApp/Program.cs new file mode 100644 index 0000000..119cebc --- /dev/null +++ b/FBLibrary.Sample.ConsoleApp/Program.cs @@ -0,0 +1,53 @@ +using System.Drawing; +using System.Drawing.Imaging; +using System.Xml; +using FB2Library; +using FB2Library.Elements; + +var filePath = Path.Combine("..", "..", "..", "..", "files", "test.fb2"); +await using var fileStream = new FileStream(filePath, FileMode.Open); + +var readerSettings = new XmlReaderSettings +{ + DtdProcessing = DtdProcessing.Ignore +}; +var loadSettings = new XmlLoadSettings(readerSettings); + +BinaryItem.DetectContentType = binaryData => +{ + try + { + using var imgStream = new MemoryStream(binaryData); + + // For MacOS need native libgdiplus, more: + // https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only#recommended-action +#pragma warning disable CA1416 + using var bitmap = new Bitmap(imgStream); + + var rawFormat = bitmap.RawFormat; + + if (rawFormat.Equals(ImageFormat.Jpeg)) + return ContentTypeEnum.ContentTypeJpeg; + + if (rawFormat.Equals(ImageFormat.Png)) + return ContentTypeEnum.ContentTypePng; + + if (rawFormat.Equals(ImageFormat.Gif)) + return ContentTypeEnum.ContentTypeGif; + + return ContentTypeEnum.ContentTypeUnknown; + +#pragma warning restore CA1416 + } + catch (Exception ex) + { + throw new Exception($"Error during image type detection: {ex}", ex); + } +}; + + +var reader = new FB2Reader(); +var file = await reader.ReadAsync(fileStream, loadSettings); + + +Console.WriteLine("Done"); \ No newline at end of file diff --git a/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json b/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json new file mode 100644 index 0000000..40b04a7 --- /dev/null +++ b/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json @@ -0,0 +1,5 @@ +{ + "configProperties": { + "System.Drawing.EnableUnixSupport": true + } +} \ No newline at end of file diff --git a/README.md b/README.md index 8471fae..4ff1a6e 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,32 @@ This project provides .Net library to help developers load .FB2 (Fiction Book: h ``` Install-Package FB2Library ``` +or +``` +dotnet add package FB2Library +``` + ## Usage * [Gettings started](https://github.com/wcoder/FB2Library/wiki/Usage) * [How to make book for reading](https://github.com/wcoder/FB2Library/wiki/How-to-make-book) -## Supported -- [x] UWP -- [x] Universal Windows/WP 8.1 -- [x] Xamarin.iOS -- [x] Xamarin.Android +## Platform Support + +Everything that supports [.NET Standard 1.0](https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.0.md): +* .NET Core 1.0 +* .NET Framework 4.5 +* Mono +* Xamarin.iOS +* Xamarin.Android +* Universal Windows Platform 10 +* Windows 8.0 +* Windows Phone 8.1 +* Windows Phone Silverlight 8.0 ## Authors -* [lordkiron](https://code.google.com/u/103776563234380142031/) - developed original library -* [Yauheni Pakala](https://github.com/wcoder) - porting to PCL +* [lordkiron](https://github.com/lordkiron) - developed original library +* [Yauheni Pakala](https://github.com/wcoder) - porting to PCL/NetStandard --- Microsoft Public License diff --git a/files/test.fb2 b/files/test.fb2 new file mode 100644 index 0000000..5abf289 --- /dev/null +++ b/files/test.fb2 @@ -0,0 +1,1264 @@ + + + + + .body{font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;} + .p{margin:0.5em 0 0 0.3em; padding:0.2em; text-align:justify;} + + + + history_russia + romance_historical + literature_classics + literature_history + literature_war + literature_rus_classsic + computers + + Лев + Николаевич + Толстой + + Война и мир + +

Это тестовый файл FictionBook 2.0. Создан Грибовым Дмитрием + в демонстрационных целях и для экспериментов с библиотекой + FIctionBook.lib. К сожалению сам роман я в FB2 пока не перевел.

+ +

Роман Толстого «Война и мир» был написан в 1869 году. Это + произведение явилось, по словам многих известных писателей и + критиков, «величайшим романом в мире». Главная мысль в романе — + мысль народная. Из множества действующих лиц произведения + значительное место уделено изображению простого люда. Причиной + этого явилось глубокое понимание и правильная оценка Толстым + решающей роли народа в исходе войны 1812 года, где полностью + раскрылся «характер русского войска и народа». Немалое место в + романе занимают также картины жизни русского крестьянства. Ведь + в годы создания романа в центре общественного внимания стала + проблема «мужика».

+ + + <p>Название стиха</p> + + +

Стихотворение посвящается тегу "stanza"

+
+ + Типа тут стихи + В этой строфе + Типа тут стихи + В этой строфе + + + Здесь по новой стихи + В этой строфе + Обратно стихи стихи + В этой строфе + +
+ +

Здесь можно кого-нибудь процитировать

+ Автор/Источник Цитаты +
+

Большую часть романа занимают картины военных действий. В + этом произведении Толстым дано изображение двух войн: 1805 и + 1812 годов. В обеих войнах главным и решающим фактором явились + народные массы. Особенно большую роль сыграл народ в войне 1812 + года, которая велась в России и была агрессивной, захватнической + со стороны Франции, но народной, справедливой со стороны России. + Поэтому цель «русского народа была одна: очистить землю от + нашествия». Сознание справедливости своей борьбы придавало + русским людям огромную силу. Это, прежде всего, видно из + Бородинского сражения, где стал понятен «весь смысл и все + значение этой войны». Бородинская битва, по словам Толстого, + необыкновенное, не повторяющееся и не имевшее примеров событие, + и оно есть одно из самых поучительных явлений истории. Писатель + нисколько не сомневался в том, что на Бородинском поле русская + армия одержит победу, которая будет иметь огромные + последствия [источник]. +

+
+ 1912, война, роман, отечественная, наполеон, кутузов, + император, политика, нравственность, изыскания, великий, большой, + французский, родина, патриотизм, личность, роль личности в истории, + дворянство, свет, власть, безухов, болконский, должное, + крепостное право, крепостничество, подвиг, народ + 1863-1869 + + + + ru + ru + + Вообще-то + никакого переводчика нет + Это так, для примера + + + +
+ + + GribUser + http://www.gribuser.ru + grib@gribuser.ru + + ClearTXT, XMLSpy, HomeSite 5.0 + 15 ноября 2002г., 19:53 + http://www.magister.msk.ru/library/tolstoy/wp/wp00.htm + Oleg E. Kolesnikov + GribUser_WarAndPeace_D49FHSH8l0HS5 + 2.0 + +

Этот документ первоначально был создан для FictionBook 1.0 и позднее переделан для FB2.0

+
+
+ + Л.Н.Толстой, Полное Собрание Сочинений + ГИХЛ + Москва + 1957 + Тут пишем ISBN код книги, если есть + + + + Здесь можно расположить дополнительную информацию, не + укладывающуюся в заданную схему. Это может быть как описательная + информация, так и коммерческая информация, связанная с книгой - + например, информация о том, где можно купить бумажное издание + +
+ + + + <p>ТОМ 1</p> + +
+ + <p>ЧАСТЬ ПЕРВАЯ</p> + + +

На самом деле тут нет никакого эпиграфа. Эпиграф добавил Грибов Дмитрий в демонстрационных целях. Тут можно ставить пустые строки:

+ +

и любое другое форматирование.

+ Грибов Дмитрий +
+
+ + <p>I</p> + +

- поместья, мой верный раб, 1. + Ну, здравствуйте, здравствуйте. 2, садитесь и рассказывайте.

+

Так говорила в июле 1805 года известная Анна Павловна Шерер, фрейлина и приближенная императрицы Марии Феодоровны, встречая важного и чиновного князя Василия, первого приехавшего на ее вечер. Анна Павловна кашляла несколько дней, у нее был , как она говорила ( был тогда новое слово, употреблявшееся только редкими). В записочках, разосланных утром с красным лакеем, было написано без различия во всех:

+

"Si vous n'avez rien de mieux à faire, M. le comte (или mon prince), et si la perspective de passer la soirée chez une pauvre malade ne vous effraye pas trop, je serai charmée de vous voir chez moi entre 7 et 10 heures. Annette Scherer"3. +

+

- 4 - отвечал, нисколько не смутясь такою встречей, вошедший князь, в придворном, шитом мундире, в чулках, башмаках, при звездах, с светлым выражением плоского лица. Он говорил на том изысканном французском языке, на котором не только говорили, но и думали наши деды, и с теми тихими, покровительственными интонациями, которые свойственны состаревшемуся в свете и при дворе значительному человеку. Он подошел к Анне Павловне, поцеловал ее руку, подставив ей свою надушенную и сияющую лысину, и покойно уселся на диване.

+

- 5 Успокойте друга, - сказал он, не изменяя голоса и тоном, в котором из-за приличия и участия просвечивало равнодушие и даже насмешка.

+
+
+ + <p>Это пример глубоко вложенных частей</p> + +
+ + <p>Рыба (1.I)</p> + +

Представляется логичным, что искусство индуктивно - это напряженный закон внешнего мира. Преамбула иллюзорна. Постмодернизм может быть получен из опыта. Представление, как принято считать, раскладывает на элементы смысл жизни, условно. Универсальное рефлектирует себя через интеллект.

+

Частное, пренебрегая деталями, философски ассоциирует естественный объект деятельности. Отсюда естественно следует, что акция трансформирует онтологический конфликт. Класс эквивалентности, как следует из вышесказанного, нетривиален. Закон внешнего мира реально осмысляет непредвиденный структурализм. Отношение к современности, конечно, представляет постмодернизм.

+

Искусство решительно означает субъективный интеллект. Надо сказать, что ощущение мира оспособляет типичный мир, изменяя привычную реальность. Наряду с этим конфликт раскладывает на элементы постсовременный класс эквивалентности. Согласно мнению известных философов закон внешнего мира транспонирует примитивный структурализм. Общество, в рамках сегодняшних воззрений, преобразует мир.

+
+
+ + <p>Рыба (1.II)</p> + +

Интересно отметить, что врожденная интуиция ментально дискредитирует структурализм, открывая новые горизонты. Созерцание осмысляет трагический конфликт. Современная ситуация вырождена. Интеллект создает данный постмодернизм. Частное подрывает закон внешнего мира. Универсальное трогательно наивно. Объект деятельности, следовательно, ясен не всем. Напряжение, конечно, нетривиально.

+

Смысл жизни неоднозначен. Предметность ассоциирует класс эквивалентности, исходя из принятого мнения. Сомнение индуцирует интеллект. Любовь категорически осмысляет примитивный принцип восприятия.

+

Структурализм оспособляет постсовременный конфликт, изменяя привычную реальность. Поливалентность решительно подрывает субъективный смысл жизни, отрицая очевидное. Реальная власть, пренебрегая деталями, дискредитирует постмодернизм, учитывая известные обстоятельства. Искусство амбивалентно. Класс эквивалентности не так уж очевиден. Философия трансформирует неоднозначный мир. Структурализм - это типичный смысл жизни. Ощущение мира осмысленно фокусирует трагический объект деятельности.

+

Общество подрывает естественный интеллект. Согласно мнению известных философов принцип восприятия непредвзято заполняет постмодернизм. Конфликт может быть получен из опыта. Смысл жизни порождает и обеспечивает структурализм. Класс эквивалентности прост.

+

Созерцание оспособляет примитивный структурализм, отрицая очевидное. Страсть порождает и обеспечивает непредвиденный класс эквивалентности. Можно предположить, что смысл жизни не так уж очевиден. Закон внешнего мира абстрактен.

+
+
+ + <p>Рыба (1.III)</p> + +

Наряду с этим мир контролирует субъективный структурализм. Свобода ментально рассматривается через принцип восприятия. Представляется логичным, что частное профанирует интеллект. Универсальное создает закон внешнего мира. Согласно предыдущему, современная ситуация ассоциирует паллиативный объект деятельности, изменяя привычную реальность. Предметность подчеркивает смысл жизни, несмотря на мнение авторитетов.

+

Реальность означает принцип восприятия. Интеллект нетривиален. Реальная власть индуцирует сложный закон внешнего мира. Согласно мнению известных философов структурализм, пренебрегая деталями, индуктивно подрывает постмодернизм. Ощущение мира заполняет напряженный класс эквивалентности, учитывая известные обстоятельства. Можно предположить, что врожденная интуиция профанирует объект деятельности.

+
+
+ + <p>Рыба (1.IV)</p> + +
+ + <p>Рыба (1.IV.a)</p> + +

Сомнение, конечно, амбивалентно представляет принцип восприятия. Отношение к современности натурально индуцирует мир, исходя из принятого мнения. Интересно отметить, что любовь, как принято считать, дискредитирует данный структурализм, отрицая очевидное. Надо сказать, что поливалентность, как следует из вышесказанного, фокусирует постмодернизм. Представляется логичным, что интеллект контролирует класс эквивалентности. Смысл жизни ясен не всем. Страсть, в рамках сегодняшних воззрений, очевидна не для всех. Общество заполняет конфликт.

+

Объект деятельности, как следует из вышесказанного, рефлектирует себя через структурализм. Интересно отметить, что класс эквивалентности, как принято считать, фокусирует смысл жизни, изменяя привычную реальность. Общество непредсказуемо. Частное рассматривается через закон внешнего мира. Согласно предыдущему, преамбула, конечно, преобразует паллиативный конфликт, исходя из принятого мнения. Конвергенция профанирует постмодернизм. Современная ситуация представляет структурализм.

+
+
+ + <p>Рыба (1.IV.б)</p> + +

Реальность творит объект деятельности. Представляется логичным, что принцип восприятия дискредитирует типичный закон внешнего мира. Жизнь подчеркивает класс эквивалентности. Отсюда естественно следует, что напряжение транспонирует примитивный мир, условно. Ощущение мира непредвзято - это смысл жизни. Поливалентность философски принимает во внимание интеллект.

+
+
+ + <p>Рыба (1.IV.в)</p> + +
+ + <p>Рыба (1.IV.в.A)</p> + +
+ + <p>Рыба (1.IV.в.A.0)</p> + +
+ + <p>Рыба (1.IV.в.A.0.q)</p> + +

Конфликт, пренебрегая деталями, ментально дискредитирует напряженный объект деятельности. Реальная власть представляет мир. Можно предположить, что врожденная интуиция, в рамках сегодняшних воззрений, фокусирует трансцендентальный смысл жизни. Любовь категорически подрывает принцип восприятия. Постмодернизм ясен не всем.

+
+
+ + <p>Рыба (1.IV.в.A.0.q)</p> + +

Согласно мнению известных философов объект деятельности не так уж очевиден. Интеллект осмысленно рассматривается через закон внешнего мира, ломая рамки привычных представлений. Принцип восприятия принимает во внимание мир. Надо сказать, что отношение к современности профанирует из ряда вон выходящий постмодернизм. Философия оспособляет структурализм, отрицая очевидное. Класс эквивалентности, как следует из вышесказанного, порождает и обеспечивает паллиативный закон внешнего мира. Конфликт индуцирует данный смысл жизни.

+
+
+
+
+
+ + <p>Рыба (1.IV.в)</p> + +
+ + <p>Рыба (1.IV.в.A)</p> + +
+ + <p>Рыба (1.IV.в.A.0)</p> + +
+ + <p>Рыба (1.IV.в.A.0.q)</p> + +

Акция вырождена. Объект деятельности натурально подрывает из ряда вон выходящий класс эквивалентности, условно. Принцип восприятия, в рамках сегодняшних воззрений, ясен не всем. Освобождение амбивалентно.

+

+

+
+ + <p>Рыба (1.IV.в.A.0.q)</p> + +

Постмодернизм неоднозначен. Напряжение трансформирует конфликт. Созерцание осмысленно профанирует объект деятельности. Смысл жизни категорически раскладывает на элементы паллиативный интеллект. Жизнь принимает во внимание постмодернизм, отрицая очевидное. Свобода ментально порождает и обеспечивает типичный класс эквивалентности. Мир - это субъективный структурализм.

+
+
+
+
+
+
+
+ + <p>XX</p> + +

...

+ + + В приятну ночь, при лунном свете, + Представить счастливо себе, + Что некто есть еще на свете, + Кто думает и о тебе! + Что и она, рукой прекрасной, + По арфе золотой бродя, + Своей гармониею страстной + Зовет к себе, зовет тебя! + Еще день, два, и рай настанет... + Но ах! твой друг не доживет! + + +
+
+ + + + <p>Сноски</p> + +
+ + <p>Источник аннотации:</p> + +

Какое-то школьное сочинение

+
+
+ + <p>1</p> + +

Ну, что, князь, Генуа и Лукка стали не больше, как поместьями фамилии Бонапарте. Нет, я вас предупреждаю, если вы мне не скажете, что у нас война, если вы еще позволите себе защищать все гадости, все ужасы этого Антихриста (право, я верю, что он Антихрист)- я вас больше не знаю, вы уж не друг мой, вы уж не мой верный раб, как вы говорите.

+
+
+ + <p>2</p> + +

Я вижу, что я вас пугаю,

+
+
+ + <p>3</p> + +

Если y вас, граф (или князь), нет в виду ничего лучшего и если перспектива вечера у бедной больной не слишком вас пугает, то я буду очень рада видеть вас нынче у себя между семью и десятью часами. Анна Шерер.

+
+
+ + <p>4</p> + +

О! какое жестокое нападение!

+
+
+ + <p>5</p> + +

Прежде всего скажите, как ваше здоровье?

+
+ + /9j/4AAQSkZJRgABAgEAYABgAAD/7Qz8UGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAAYAAA +AAEAAgBgAAAAAQACOEJJTQQNAAAAAAAEAAAAeDhCSU0D8wAAAAAACAAAAAAAAAAAOEJJTQQK +AAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxmZgAG +AAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAG +AAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA//////// +/////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD///// +////////////////////////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklN +BBQAAAAAAAQAAAABOEJJTQQMAAAAAAtrAAAAAQAAAFgAAABwAAABCAAAc4AAAAtPABgAAf/Y +/+AAEEpGSUYAAQIBAEgASAAA//4AJkZpbGUgd3JpdHRlbiBieSBBZG9iZSBQaG90b3Nob3Co +IDUuMP/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoLERUPDAwPFRgTExUTExgR +DAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDQsLDQ4NEA4OEBQODg4UFA4O +Dg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAHAA +WAMBIgACEQEDEQH/3QAEAAb/xAE/AAABBQEBAQEBAQAAAAAAAAADAAECBAUGBwgJCgsBAAEF +AQEBAQEBAAAAAAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIxBUFR +YRMicYEyBhSRobFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXy +s4TD03Xj80YnlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQACAgEC +BAQDBAUGBwcGBTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKCkkNTFWNzNPEl +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 +AAAIDGdUUkMAAAQ8AAAIDGJUUkMAAAQ8AAAIDHRleHQAAAAAQ29weXJpZ2h0IChjKSAxOTk4 +IEhld2xldHQtUGFja2FyZCBDb21wYW55AABkZXNjAAAAAAAAABJzUkdCIElFQzYxOTY2LTIu +MQAAAAAAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAA +AAAAAAAAAAAAAAAAWFlaIAAAAAAAAG+iAAA49QAAA5BYWVogAAAAAAAAYpkAALeFAAAY2lhZ +WiAAAAAAAAAkoAAAD4QAALbPZGVzYwAAAAAAAAAWSUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAA +AAAAAAAAAAAWSUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRlc2MAAAAAAAAALklFQyA2MTk2Ni0yLjEgRGVmYXVs +dCBSR0IgY29sb3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAALklFQyA2MTk2Ni0yLjEgRGVm +YXVsdCBSR0IgY29sb3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNj +AAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5NjYtMi4xAAAA +AAAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2LTIuMQAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdmlldwAAAAAAE6T+ABRfLgAQzxQAA+3MAAQTCwAD +XJ4AAAABWFlaIAAAAAAATAlWAFAAAABXH+dtZWFzAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA +AAACjwAAAAJzaWcgAAAAAENSVCBjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAy +ADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3 +ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFS +AVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQIm +Ai8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4 +A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSM +BJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYn +BjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgL +CB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9 +ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzA +DNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+W +D7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLD +EuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJ +FmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoq +GlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5q +HpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMK +IzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgN +KD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12 +Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNG +M38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/ +Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAj +QGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1 +R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63 +TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFap +VvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8P +X2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fp +aD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6 +cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsE +e2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VH +hauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAG +kG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtC +m6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9 +p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4 +s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1 +wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01 +zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr7 +24DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG +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 +ZrBVPSz3FzWPI4YWMzIAzE7+r71PJcVRobT26Rp2aGqbXXwpTfPEcbXzWtTV8e+ea2lpcfye +vu8fW+7ube5potzv3JHk9eFBxLX7ZMYAMDgX4Yfb422BX2jW9W5qLY23SqtVuaGnqczyNfJV +UaHEbVfA8eNe7Xpe23ixXqzmKjvWXUMbEB877AFLEQuTZkxrCqrZXlrQz2kqnyf5HocTqcV8 +w3uSGzTVW/J7wWzZ2XYUfHqrzqfBuNWjkPjv+LZ8V5/ktXkglDHeo11GxY/kLCI+WDM5T3CL +MmA+VY1y8uBqO9vmjV+RfIt7meS8Wqr1dhbk5fXFV/G611lnFPXTfxu7QdOvUp2l5njbNHnO +MZLtT5HT7b7F6tZbb3Vwa3yZ4hrfD7msFNfI85paWv8AI/7q0NA73zj5LzvJ2al1r8HyNtmn +w9qHX2n93a1jWKF0BToam67a/E7CNbziXW2cXrDUt5+qzd1L8C20eUNRCHtOyv5ze/sX5ryN +25yWzfbbtGx1tFQ0Nkmzhtys18btftvytC3ccKVHKtRr6uxskPw/KbVtulvWbV2tbrPY9erV +p8h7I3EevBjKMlp5V5p17q4uol1FyIF2ARNLb8X4rbDWcbve1tgGrf4TkaQdv27qeX1tvx4/ +k7a7tLf9jX48X/4nPbPu6nyXlN7hNzifm3H7L07S213LkFCBj7ePIsXZ3/Ki1C1FrYlajype +lbON2K71q27bjo3Vi63ac6/J9rNzWerkPZut09Xc3aNCjYe/V+ffs7NyWV3fCeffc08FlSsk +e2POncor0xr+dDOtY2tUCsJbWdSx13+I2j/m6evStHB1rXbw+7RtjlrmTX5a01W8Vd7dLudm +jUOxrT5Feu8dg+Q4Dk7uN5HSvNtSJ+37b+5qg1ccWNaG+tdIrQF2ayhocizhLAN0b1lEOxQK +uLv9ivmOTtazkeRTa2eG26ilN6iu3Y3lHyndUchvo9F4JE+Fc89mv7g9nyOePPe+v2rbNkNN +i7vteLVghZp+yJTv+8vGlTri/wBteaaxadWrW1d3hLOOsWpdWlm5Jlp5Ki72OQeyx1ckcLyV +mlsfH+U19/V8U8tH2v8AMrRGeugLChEvCopqUKGIGmcWafIrdsalm283db/J0uTOwjcQHo0N +lhoX6O1Yx5XcWvidpi9thyzWEHged2OL2f8Av6v/ABihSbxavktS3zXesbzZfPVsQpZXjHuG +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 +2Q== + /9j/4AAQSkZJRgABAgEA4QDhAAD/7RWyUGhvdG9zaG9wIDMuMAA4QklNA+kAAAAAAHgAAwAAAEgA +SAAAAAAC2AIo/+H/4gL5AkYDRwUoA/wAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAAB +Jw8AAQABAAAAAAAAAAAAAAAAYAgAGQGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4 +QklNA+0AAAAAABAA4QAAAAEAAQDhAAAAAQABOEJJTQQNAAAAAAAEAAAAeDhCSU0D8wAAAAAACAAA +AAAAAAAAOEJJTQQKAAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9m +ZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAAB +AC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA//// +/////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD///// +////////////////////////A+gAADhCSU0ECAAAAAAAMwAAAAEAAAJAAAACQAAAAAcAAAEnAAAA +ANEAAAABnQEAAAxcAAAAAswBAAAT4AEAABUKAQA4QklNBBQAAAAAAAQAAABgOEJJTQQMAAAAABH8 +AAAAAQAAAE8AAABwAAAA8AAAaQAAABHgABgAAf/Y/+AAEEpGSUYAAQIBAEgASAAA//4AJkZpbGUg +d3JpdHRlbiBieSBBZG9iZSBQaG90b3Nob3CoIDUuMP/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJ +CAwJCQwRCwoLERUPDAwPFRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM +DAwBDQsLDQ4NEA4OEBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwM +DAwMDAwMDAwMDP/AABEIAHAATwMBIgACEQEDEQH/3QAEAAX/xAE/AAABBQEBAQEBAQAAAAAAAAAD +AAECBAUGBwgJCgsBAAEFAQEBAQEBAAAAAAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwz +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 +XGD+2/sx/afafg/oenzr0MXtzpL1737r3X//2Q== + +
\ No newline at end of file