├── .github
└── workflows
│ ├── ci.yml
│ ├── release-preview.yml
│ └── release.yml
├── .gitignore
├── .vscode
├── launch.json
└── tasks.json
├── FB2Library.sln
├── FB2Library.sln.DotSettings
├── LICENSE.md
├── README.md
├── files
└── test.fb2
├── images
└── icon.png
├── samples
├── FB2Library.Sample.UWP
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Assets
│ │ ├── LockScreenLogo.scale-200.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ ├── StoreLogo.png
│ │ └── Wide310x150Logo.scale-200.png
│ ├── FB2Library.Sample.UWP.csproj
│ ├── MainPage.xaml
│ ├── MainPage.xaml.cs
│ ├── Package.appxmanifest
│ └── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Default.rd.xml
├── FB2Sample.XF
│ ├── FB2Sample.XF.Droid
│ │ ├── Assets
│ │ │ └── AboutAssets.txt
│ │ ├── FB2Sample.XF.Droid.csproj
│ │ ├── MainActivity.cs
│ │ ├── Properties
│ │ │ ├── AndroidManifest.xml
│ │ │ └── AssemblyInfo.cs
│ │ ├── Resources
│ │ │ ├── AboutResources.txt
│ │ │ ├── Resource.Designer.cs
│ │ │ ├── drawable-hdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ └── icon.png
│ │ │ └── drawable
│ │ │ │ └── icon.png
│ │ └── packages.config
│ ├── FB2Sample.XF.UWP
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── Assets
│ │ │ ├── LockScreenLogo.scale-200.png
│ │ │ ├── SplashScreen.scale-200.png
│ │ │ ├── Square150x150Logo.scale-200.png
│ │ │ ├── Square44x44Logo.scale-200.png
│ │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ │ ├── StoreLogo.png
│ │ │ └── Wide310x150Logo.scale-200.png
│ │ ├── FB2Sample.XF.UWP.csproj
│ │ ├── FB2Sample.XF.UWP.nuget.targets
│ │ ├── MainPage.xaml
│ │ ├── MainPage.xaml.cs
│ │ ├── Package.appxmanifest
│ │ ├── Properties
│ │ │ ├── AssemblyInfo.cs
│ │ │ └── Default.rd.xml
│ │ └── project.json
│ ├── FB2Sample.XF.WinPhone
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── Assets
│ │ │ ├── Logo.scale-240.png
│ │ │ ├── SmallLogo.scale-240.png
│ │ │ ├── SplashScreen.scale-240.png
│ │ │ ├── Square71x71Logo.scale-240.png
│ │ │ ├── StoreLogo.scale-240.png
│ │ │ └── WideLogo.scale-240.png
│ │ ├── FB2Sample.XF.WinPhone.csproj
│ │ ├── MainPage.xaml
│ │ ├── MainPage.xaml.cs
│ │ ├── Package.appxmanifest
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ └── packages.config
│ ├── FB2Sample.XF.Windows
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── Assets
│ │ │ ├── Logo.scale-100.png
│ │ │ ├── SmallLogo.scale-100.png
│ │ │ ├── SplashScreen.scale-100.png
│ │ │ └── StoreLogo.scale-100.png
│ │ ├── FB2Sample.XF.Windows.csproj
│ │ ├── MainPage.xaml
│ │ ├── MainPage.xaml.cs
│ │ ├── Package.appxmanifest
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ └── packages.config
│ ├── FB2Sample.XF.iOS
│ │ ├── AppDelegate.cs
│ │ ├── Entitlements.plist
│ │ ├── FB2Sample.XF.iOS.csproj
│ │ ├── Info.plist
│ │ ├── Main.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── Resources
│ │ │ ├── Default-568h@2x.png
│ │ │ ├── Default-Portrait.png
│ │ │ ├── Default-Portrait@2x.png
│ │ │ ├── Default.png
│ │ │ ├── Default@2x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small-40.png
│ │ │ ├── Icon-Small-40@2x.png
│ │ │ ├── Icon-Small-40@3x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ └── LaunchScreen.storyboard
│ │ ├── iTunesArtwork
│ │ ├── iTunesArtwork@2x
│ │ └── packages.config
│ └── FB2Sample.XF
│ │ ├── App.cs
│ │ ├── FB2Sample.XF.csproj
│ │ ├── MainPage.xaml
│ │ ├── MainPage.xaml.cs
│ │ ├── Properties
│ │ └── AssemblyInfo.cs
│ │ └── packages.config
└── FBLibrary.Sample.ConsoleApp
│ ├── FBLibrary.Sample.ConsoleApp.csproj
│ ├── Program.cs
│ └── runtimeconfig.template.json
└── src
├── Elements
├── AnnotationItem.cs
├── AnnotationType.cs
├── AuthorItem.cs
├── AuthorType.cs
├── BinaryItem.cs
├── BodyItem.cs
├── CiteItem.cs
├── CustomTextFieldType.cs
├── DateItem.cs
├── EmptyLineItem.cs
├── EpigraphItem.cs
├── FB2Const.cs
├── FB2TextItem.cs
├── GenreType.cs
├── ImageItem.cs
├── InlineImageItem.cs
├── InternalLinkItem.cs
├── OutPutDocumentType.cs
├── ParagraphItem.cs
├── PartShareInstructionType.cs
├── Poem
│ ├── PoemItem.cs
│ ├── StanzaItem.cs
│ └── VPoemParagraph.cs
├── SectionItem.cs
├── SequenceType.cs
├── ShareInstructionType.cs
├── SimpleText.cs
├── StyleElement.cs
├── StyleItem.cs
├── SubTitleItem.cs
├── Table
│ ├── BaseCellElement.cs
│ ├── TableCellItem.cs
│ ├── TableHeadingItem.cs
│ ├── TableItem.cs
│ └── TableRowItem.cs
├── TextAuthorItem.cs
├── TextFieldType.cs
└── TitleItem.cs
├── FB2File.cs
├── FB2Library.csproj
├── FB2Reader.cs
├── HeaderItems
├── CoverPage.cs
├── CustomInfo.cs
├── ItemDocumentInfo.cs
├── ItemInfoBase.cs
├── ItemPublishInfo.cs
└── ItemTitleInfo.cs
├── IFB2Reader.cs
└── XmlLoadSettings.cs
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - master
5 | pull_request:
6 | branches:
7 | - master
8 | env:
9 | DOTNET_NOLOGO: true
10 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
11 | DOTNET_CLI_TELEMETRY_OPTOUT: true
12 | jobs:
13 | build:
14 | runs-on: ${{ matrix.os }}
15 | strategy:
16 | matrix:
17 | os: [ ubuntu-latest, windows-latest, macos-latest ]
18 | timeout-minutes: 10
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v2
22 | - name: Build All
23 | if: matrix.os == 'ubuntu-latest'
24 | run: dotnet build --configuration Release
25 | - name: Build Library
26 | run: dotnet build src --configuration Release
--------------------------------------------------------------------------------
/.github/workflows/release-preview.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | tags:
4 | - "v[0-9]+.[0-9]+.[0-9]+-preview[0-9]+"
5 | env:
6 | DOTNET_NOLOGO: true
7 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
8 | DOTNET_CLI_TELEMETRY_OPTOUT: true
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | timeout-minutes: 10
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v2
16 | - name: Set VERSION variable from tag
17 | run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV
18 | - name: Pack
19 | run: |
20 | dotnet pack src \
21 | -p:PackageVersion="${VERSION}" \
22 | --configuration Release \
23 | --verbosity normal \
24 | --output .
25 | - name: Upload Artifact
26 | uses: actions/upload-artifact@v3
27 | with:
28 | name: nupkg
29 | path: |
30 | *.nupkg
31 | *.snupkg
32 |
33 | deploy-github:
34 | needs: build
35 | runs-on: ubuntu-latest
36 | steps:
37 | - name: Download Artifact
38 | uses: actions/download-artifact@v1
39 | with:
40 | name: nupkg
41 | - name: Push to GitHub
42 | run: |
43 | dotnet nuget push ./nupkg/*.nupkg \
44 | --source ${FEED_URL} \
45 | --api-key ${FEED_KEY} \
46 | --no-symbols true \
47 | --skip-duplicate
48 | env:
49 | FEED_URL: https://nuget.pkg.github.com/wcoder/index.json \
50 | FEED_KEY: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | tags:
4 | - "v[0-9]+.[0-9]+.[0-9]+"
5 | env:
6 | DOTNET_NOLOGO: true
7 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
8 | DOTNET_CLI_TELEMETRY_OPTOUT: true
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | timeout-minutes: 10
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v2
16 | - name: Verify commit exists in origin/master
17 | run: |
18 | git fetch --no-tags --prune --depth=1 origin '+refs/heads/*:refs/remotes/origin/*'
19 | git branch --remote --contains | grep origin/master
20 | - name: Set VERSION variable from tag
21 | run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV
22 | - name: Pack
23 | run: |
24 | dotnet pack src \
25 | -p:PackageVersion="${VERSION}" \
26 | --configuration Release \
27 | --verbosity normal \
28 | --output .
29 | - name: Upload Artifact
30 | uses: actions/upload-artifact@v3
31 | with:
32 | name: nupkg
33 | path: |
34 | *.nupkg
35 | *.snupkg
36 |
37 | deploy-nuget:
38 | needs: build
39 | runs-on: ubuntu-latest
40 | steps:
41 | - name: Download Artifact
42 | uses: actions/download-artifact@v1
43 | with:
44 | name: nupkg
45 | - name: Push to NuGet
46 | run: |
47 | dotnet nuget push ./nupkg/* \
48 | --source ${FEED_URL} \
49 | --api-key ${FEED_KEY} \
50 | --skip-duplicate
51 | env:
52 | FEED_URL: https://api.nuget.org/v3/index.json
53 | FEED_KEY: ${{ secrets.NUGET_KEY }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/is,visualstudio,xamarinstudio
2 | #!! ERROR: is is undefined. Use list command to see defined gitignore types !!#
3 | ### VisualStudio ###
4 | ## Ignore Visual Studio temporary files, build results, and
5 | ## files generated by popular Visual Studio add-ons.
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 | # User-specific files (MonoDevelop/Xamarin Studio)
12 | *.userprefs
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 | # Visual Studio 2015 cache/options directory
25 | .vs/
26 | # Uncomment if you have tasks that create the project's static files in wwwroot
27 | #wwwroot/
28 | # MSTest test Results
29 | [Tt]est[Rr]esult*/
30 | [Bb]uild[Ll]og.*
31 | # NUNIT
32 | *.VisualState.xml
33 | TestResult.xml
34 | # Build Results of an ATL Project
35 | [Dd]ebugPS/
36 | [Rr]eleasePS/
37 | dlldata.c
38 | # DNX
39 | project.lock.json
40 | artifacts/
41 | *_i.c
42 | *_p.c
43 | *_i.h
44 | *.ilk
45 | *.meta
46 | *.obj
47 | *.pch
48 | *.pdb
49 | *.pgc
50 | *.pgd
51 | *.rsp
52 | *.sbr
53 | *.tlb
54 | *.tli
55 | *.tlh
56 | *.tmp
57 | *.tmp_proj
58 | *.log
59 | *.vspscc
60 | *.vssscc
61 | .builds
62 | *.pidb
63 | *.svclog
64 | *.scc
65 | # Chutzpah Test files
66 | _Chutzpah*
67 | # Visual C++ cache files
68 | ipch/
69 | *.aps
70 | *.ncb
71 | *.opendb
72 | *.opensdf
73 | *.sdf
74 | *.cachefile
75 | # Visual Studio profiler
76 | *.psess
77 | *.vsp
78 | *.vspx
79 | *.sap
80 | # TFS 2012 Local Workspace
81 | $tf/
82 | # Guidance Automation Toolkit
83 | *.gpState
84 | # ReSharper is a .NET coding add-in
85 | _ReSharper*/
86 | *.[Rr]e[Ss]harper
87 | *.DotSettings.user
88 | # JustCode is a .NET coding add-in
89 | .JustCode
90 | # TeamCity is a build add-in
91 | _TeamCity*
92 | # DotCover is a Code Coverage Tool
93 | *.dotCover
94 | # NCrunch
95 | _NCrunch_*
96 | .*crunch*.local.xml
97 | nCrunchTemp_*
98 | # MightyMoose
99 | *.mm.*
100 | AutoTest.Net/
101 | # Web workbench (sass)
102 | .sass-cache/
103 | # Installshield output folder
104 | [Ee]xpress/
105 | # DocProject is a documentation generator add-in
106 | DocProject/buildhelp/
107 | DocProject/Help/*.HxT
108 | DocProject/Help/*.HxC
109 | DocProject/Help/*.hhc
110 | DocProject/Help/*.hhk
111 | DocProject/Help/*.hhp
112 | DocProject/Help/Html2
113 | DocProject/Help/html
114 | # Click-Once directory
115 | publish/
116 | # Publish Web Output
117 | *.[Pp]ublish.xml
118 | *.azurePubxml
119 | # TODO: Comment the next line if you want to checkin your web deploy settings
120 | # but database connection strings (with potential passwords) will be unencrypted
121 | *.pubxml
122 | *.publishproj
123 | # NuGet Packages
124 | *.nupkg
125 | *.snupkg
126 | # The packages folder can be ignored because of Package Restore
127 | **/packages/*
128 | # except build/, which is used as an MSBuild target.
129 | !**/packages/build/
130 | # Uncomment if necessary however generally it will be regenerated when needed
131 | #!**/packages/repositories.config
132 | # Windows Azure Build Output
133 | csx/
134 | *.build.csdef
135 | # Windows Azure Emulator
136 | ecf/
137 | rcf/
138 | # Windows Store app package directory
139 | AppPackages/
140 | # Visual Studio cache files
141 | # files ending in .cache can be ignored
142 | *.[Cc]ache
143 | # but keep track of directories ending in .cache
144 | !*.[Cc]ache/
145 | # Others
146 | ClientBin/
147 | [Ss]tyle[Cc]op.*
148 | ~$*
149 | *~
150 | *.dbmdl
151 | *.dbproj.schemaview
152 | *.pfx
153 | *.publishsettings
154 | node_modules/
155 | orleans.codegen.cs
156 | # RIA/Silverlight projects
157 | Generated_Code/
158 | # Backup & report files from converting an old project file
159 | # to a newer Visual Studio version. Backup files are not needed,
160 | # because we have git ;-)
161 | _UpgradeReport_Files/
162 | Backup*/
163 | UpgradeLog*.XML
164 | UpgradeLog*.htm
165 | # SQL Server files
166 | *.mdf
167 | *.ldf
168 | # Business Intelligence projects
169 | *.rdl.data
170 | *.bim.layout
171 | *.bim_*.settings
172 | # Microsoft Fakes
173 | FakesAssemblies/
174 | # GhostDoc plugin setting file
175 | *.GhostDoc.xml
176 | # Node.js Tools for Visual Studio
177 | .ntvs_analysis.dat
178 | # Visual Studio 6 build log
179 | *.plg
180 | # Visual Studio 6 workspace options file
181 | *.opt
182 | # Visual Studio LightSwitch build output
183 | **/*.HTMLClient/GeneratedArtifacts
184 | **/*.DesktopClient/GeneratedArtifacts
185 | **/*.DesktopClient/ModelManifest.xml
186 | **/*.Server/GeneratedArtifacts
187 | **/*.Server/ModelManifest.xml
188 | _Pvt_Extensions
189 | # Paket dependency manager
190 | .paket/paket.exe
191 | # FAKE - F# Make
192 | .fake/
193 | ### XamarinStudio ###
194 | bin/
195 | obj/
196 | *.userprefs
197 |
198 | # Idea
199 | .idea/
200 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": ".NET Launch (ConsoleApp)",
9 | "type": "coreclr",
10 | "request": "launch",
11 | "preLaunchTask": "build",
12 | "program": "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/bin/Debug/net6.0/FBLibrary.Sample.ConsoleApp.dll",
13 | "args": [],
14 | "cwd": "${workspaceFolder}/FBLibrary.Sample.ConsoleApp",
15 | "console": "internalConsole",
16 | "stopAtEntry": false
17 | },
18 | {
19 | "name": ".NET Core Attach",
20 | "type": "coreclr",
21 | "request": "attach"
22 | }
23 | ]
24 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build",
6 | "command": "dotnet",
7 | "type": "process",
8 | "args": [
9 | "build",
10 | "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj",
11 | "/property:GenerateFullPaths=true",
12 | "/consoleloggerparameters:NoSummary"
13 | ],
14 | "problemMatcher": "$msCompile"
15 | },
16 | {
17 | "label": "publish",
18 | "command": "dotnet",
19 | "type": "process",
20 | "args": [
21 | "publish",
22 | "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj",
23 | "/property:GenerateFullPaths=true",
24 | "/consoleloggerparameters:NoSummary"
25 | ],
26 | "problemMatcher": "$msCompile"
27 | },
28 | {
29 | "label": "watch",
30 | "command": "dotnet",
31 | "type": "process",
32 | "args": [
33 | "watch",
34 | "run",
35 | "--project",
36 | "${workspaceFolder}/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj"
37 | ],
38 | "problemMatcher": "$msCompile"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/FB2Library.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.14
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FB2Library", "src\FB2Library.csproj", "{718CE136-BCDC-4BF8-9863-ADC7633EB2CA}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FB2Library.Sample.UWP", "samples\FB2Library.Sample.UWP\FB2Library.Sample.UWP.csproj", "{9E25F85E-486A-4B68-AF44-3E47CA962433}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FBLibrary.Sample.ConsoleApp", "samples\FBLibrary.Sample.ConsoleApp\FBLibrary.Sample.ConsoleApp.csproj", "{6D8B892A-DDE9-4860-94DD-B567D431CA7D}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|ARM = Debug|ARM
16 | Debug|x64 = Debug|x64
17 | Debug|x86 = Debug|x86
18 | Release|Any CPU = Release|Any CPU
19 | Release|ARM = Release|ARM
20 | Release|x64 = Release|x64
21 | Release|x86 = Release|x86
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|ARM.ActiveCfg = Debug|Any CPU
27 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|ARM.Build.0 = Debug|Any CPU
28 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|x64.ActiveCfg = Debug|Any CPU
29 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|x64.Build.0 = Debug|Any CPU
30 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|x86.ActiveCfg = Debug|Any CPU
31 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Debug|x86.Build.0 = Debug|Any CPU
32 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|ARM.ActiveCfg = Release|Any CPU
35 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|ARM.Build.0 = Release|Any CPU
36 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|x64.ActiveCfg = Release|Any CPU
37 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|x64.Build.0 = Release|Any CPU
38 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|x86.ActiveCfg = Release|Any CPU
39 | {718CE136-BCDC-4BF8-9863-ADC7633EB2CA}.Release|x86.Build.0 = Release|Any CPU
40 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|Any CPU.ActiveCfg = Debug|x86
41 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|Any CPU.Build.0 = Debug|x86
42 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|Any CPU.Deploy.0 = Debug|x86
43 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|ARM.ActiveCfg = Debug|ARM
44 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|ARM.Build.0 = Debug|ARM
45 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|ARM.Deploy.0 = Debug|ARM
46 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|x64.ActiveCfg = Debug|x64
47 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|x64.Build.0 = Debug|x64
48 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|x64.Deploy.0 = Debug|x64
49 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|x86.ActiveCfg = Debug|x86
50 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|x86.Build.0 = Debug|x86
51 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Debug|x86.Deploy.0 = Debug|x86
52 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|Any CPU.ActiveCfg = Release|x86
53 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|ARM.ActiveCfg = Release|ARM
54 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|ARM.Build.0 = Release|ARM
55 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|ARM.Deploy.0 = Release|ARM
56 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x64.ActiveCfg = Release|x64
57 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x64.Build.0 = Release|x64
58 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x64.Deploy.0 = Release|x64
59 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x86.ActiveCfg = Release|x86
60 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x86.Build.0 = Release|x86
61 | {9E25F85E-486A-4B68-AF44-3E47CA962433}.Release|x86.Deploy.0 = Release|x86
62 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
63 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
64 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|ARM.ActiveCfg = Debug|Any CPU
65 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|ARM.Build.0 = Debug|Any CPU
66 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x64.ActiveCfg = Debug|Any CPU
67 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x64.Build.0 = Debug|Any CPU
68 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x86.ActiveCfg = Debug|Any CPU
69 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Debug|x86.Build.0 = Debug|Any CPU
70 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
71 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|Any CPU.Build.0 = Release|Any CPU
72 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|ARM.ActiveCfg = Release|Any CPU
73 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|ARM.Build.0 = Release|Any CPU
74 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x64.ActiveCfg = Release|Any CPU
75 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x64.Build.0 = Release|Any CPU
76 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x86.ActiveCfg = Release|Any CPU
77 | {6D8B892A-DDE9-4860-94DD-B567D431CA7D}.Release|x86.Build.0 = Release|Any CPU
78 | EndGlobalSection
79 | GlobalSection(SolutionProperties) = preSolution
80 | HideSolutionNode = FALSE
81 | EndGlobalSection
82 | EndGlobal
83 |
--------------------------------------------------------------------------------
/FB2Library.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | FB
3 | XML
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | #Microsoft Public License (Ms-PL)
2 |
3 | Copyright (c) 2009-2015 lordkiron / 2016 Yauheni Pakala
4 |
5 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
6 |
7 | ##1. Definitions
8 |
9 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
10 |
11 | A "contribution" is the original software, or any additions or changes to the software.
12 |
13 | A "contributor" is any person that distributes its contribution under this license.
14 |
15 | "Licensed patents" are a contributor's patent claims that read directly on its contribution.
16 |
17 | ##2. Grant of Rights
18 |
19 | * (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
20 |
21 | * (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
22 |
23 | ##3. Conditions and Limitations
24 |
25 | * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
26 |
27 | * (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
28 |
29 | * (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
30 |
31 | * (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
32 |
33 | * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FB2Library [](https://www.nuget.org/packages/FB2Library/)
2 |
3 | This project provides .Net library to help developers load .FB2 (Fiction Book: http://en.wikipedia.org/wiki/FictionBook ) ebook files. This ebook files format is widely acceptable in Russia. If you doing some converter, reader or editor for ebooks and you using one of the .Net languages - this project for you.
4 |
5 | > The original library automatically exported from http://code.google.com/p/fb2librarynet and placed [here](https://github.com/wcoder/FB2Library).
6 |
7 | ## Installation
8 |
9 | * Available on NuGet: https://www.nuget.org/packages/FB2Library
10 | * Install into your PCL project or Client projects.
11 |
12 | ```
13 | Install-Package FB2Library
14 | ```
15 | or
16 | ```
17 | dotnet add package FB2Library
18 | ```
19 |
20 | ## Usage
21 |
22 | * [Gettings started](https://github.com/wcoder/FB2Library/wiki/Usage)
23 | * [How to make book for reading](https://github.com/wcoder/FB2Library/wiki/How-to-make-book)
24 |
25 | ## Platform Support
26 |
27 | Everything that supports [.NET Standard 1.0](https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.0.md):
28 |
29 | * .NET Core 1.0+
30 | * .NET Framework 4.5+
31 | * .NET 6
32 | * .NET 7
33 | * Mono
34 | * Xamarin.iOS
35 | * Xamarin.Android
36 | * Universal Windows Platform 10
37 | * Windows 8.0
38 | * Windows Phone 8.1
39 | * Windows Phone Silverlight 8.0
40 |
41 | ## Authors
42 |
43 | * [lordkiron](https://github.com/lordkiron) - developed original library
44 | * [Yauheni Pakala](https://github.com/wcoder) - porting to PCL/NetStandard
45 |
46 | ---
47 | Microsoft Public License
48 |
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/images/icon.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace FB2Library.Sample.UWP
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 | Frame rootFrame = Window.Current.Content as Frame;
43 |
44 | // Do not repeat app initialization when the Window already has content,
45 | // just ensure that the window is active
46 | if (rootFrame == null)
47 | {
48 | // Create a Frame to act as the navigation context and navigate to the first page
49 | rootFrame = new Frame();
50 |
51 | rootFrame.NavigationFailed += OnNavigationFailed;
52 |
53 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
54 | {
55 | //TODO: Load state from previously suspended application
56 | }
57 |
58 | // Place the frame in the current Window
59 | Window.Current.Content = rootFrame;
60 | }
61 |
62 | if (e.PrelaunchActivated == false)
63 | {
64 | if (rootFrame.Content == null)
65 | {
66 | // When the navigation stack isn't restored navigate to the first page,
67 | // configuring the new page by passing required information as a navigation
68 | // parameter
69 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
70 | }
71 | // Ensure the current window is active
72 | Window.Current.Activate();
73 | }
74 | }
75 |
76 | ///
77 | /// Invoked when Navigation to a certain page fails
78 | ///
79 | /// The Frame which failed navigation
80 | /// Details about the navigation failure
81 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
82 | {
83 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
84 | }
85 |
86 | ///
87 | /// Invoked when application execution is being suspended. Application state is saved
88 | /// without knowing whether the application will be terminated or resumed with the contents
89 | /// of memory still intact.
90 | ///
91 | /// The source of the suspend request.
92 | /// Details about the suspend request.
93 | private void OnSuspending(object sender, SuspendingEventArgs e)
94 | {
95 | var deferral = e.SuspendingOperation.GetDeferral();
96 | //TODO: Save application state and stop any background activity
97 | deferral.Complete();
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Library.Sample.UWP/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using Windows.Storage;
8 | using Windows.Storage.Pickers;
9 | using Windows.UI.Xaml;
10 | using Windows.UI.Xaml.Controls;
11 |
12 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
13 |
14 | namespace FB2Library.Sample.UWP
15 | {
16 | ///
17 | /// An empty page that can be used on its own or navigated to within a Frame.
18 | ///
19 | public sealed partial class MainPage : Page
20 | {
21 | private FB2File _file;
22 |
23 | public MainPage()
24 | {
25 | InitializeComponent();
26 |
27 | _file = new FB2File();
28 |
29 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
30 | }
31 |
32 | private async void Choose_Click(object sender, RoutedEventArgs e)
33 | {
34 | var file = await CreatePicker().PickSingleFileAsync();
35 | if (file != null)
36 | {
37 | textBlock.Text = "Picked file: " + file.Name;
38 |
39 | await OpenFileAsync(file);
40 | }
41 | else
42 | {
43 | textBlock.Text = "Operation cancelled.";
44 | }
45 | }
46 |
47 | private FileOpenPicker CreatePicker()
48 | {
49 | var picker = new FileOpenPicker();
50 | picker.ViewMode = PickerViewMode.Thumbnail;
51 | picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
52 | picker.FileTypeFilter.Add(".fb2");
53 | return picker;
54 | }
55 |
56 | private async Task OpenFileAsync(StorageFile file)
57 | {
58 | loading.Visibility = Visibility.Visible;
59 |
60 | using (var s = await file.OpenStreamForReadAsync())
61 | {
62 | try
63 | {
64 | var xml = await GetStringFromStreamAsync(s);
65 | _file = await new FB2Reader().ReadAsync(xml);
66 |
67 | //DisplayLines();
68 | }
69 | catch (Exception ex)
70 | {
71 | bookInfo.Text = string.Format("Error loading file : {0}", ex.Message);
72 | }
73 | finally
74 | {
75 | loading.Visibility = Visibility.Collapsed;
76 | }
77 | }
78 | }
79 |
80 | private async Task ReadFB2FileStreamAsync(Stream stream)
81 | {
82 | // setup
83 | var readerSettings = new XmlReaderSettings
84 | {
85 | DtdProcessing = DtdProcessing.Ignore
86 | };
87 | var loadSettings = new XmlLoadSettings(readerSettings);
88 |
89 | try
90 | {
91 | // reading
92 | FB2File file = await new FB2Reader().ReadAsync(stream, loadSettings);
93 | }
94 | catch (Exception ex)
95 | {
96 | Debug.WriteLine(string.Format("Error loading file : {0}", ex.Message));
97 | }
98 | }
99 |
100 |
101 | private async Task GetStringFromStreamAsync(Stream stream)
102 | {
103 | // get first line
104 | var firstLineBuffer = new byte[60];
105 | stream.Read(firstLineBuffer, 0, firstLineBuffer.Length);
106 | stream.Position = 0;
107 | var firstLine = Encoding.UTF8.GetString(firstLineBuffer);
108 |
109 | // create reader
110 | StreamReader streamReader;
111 | if (firstLine.Contains("windows-1251"))
112 | {
113 | streamReader = new StreamReader(stream, Encoding.GetEncoding(1251));
114 | }
115 | else
116 | {
117 | streamReader = new StreamReader(stream, true);
118 | }
119 |
120 | var xml = await streamReader.ReadToEndAsync();
121 |
122 | streamReader.Dispose();
123 |
124 | return xml;
125 | }
126 |
127 | private void Close_Click(object sender, RoutedEventArgs e)
128 | {
129 | bookInfo.Text = string.Empty;
130 | textBlock.Text = "Closed";
131 | _file = null;
132 |
133 | GC.Collect();
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | FB2Library.Sample.UWP
18 | yauhe
19 | Assets\StoreLogo.png
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FB2Library.Sample.UWP")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FB2Library.Sample.UWP")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/samples/FB2Library.Sample.UWP/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with you package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content.PM;
5 | using Android.Runtime;
6 | using Android.Views;
7 | using Android.Widget;
8 | using Android.OS;
9 |
10 | namespace FB2Sample.XF.Droid
11 | {
12 | [Activity(Label = "FB2Sample.XF", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
13 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
14 | {
15 | protected override void OnCreate(Bundle bundle)
16 | {
17 | base.OnCreate(bundle);
18 |
19 | global::Xamarin.Forms.Forms.Init(this, bundle);
20 | LoadApplication(new App());
21 | }
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("FB2Sample.XF.Droid")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("FB2Sample.XF.Droid")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
32 | // Add some common permissions, these can be removed if not needed
33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
35 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
51 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Droid/Resources/drawable/icon.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Droid/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace FB2Sample.XF.UWP
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 |
43 | #if DEBUG
44 | if (System.Diagnostics.Debugger.IsAttached)
45 | {
46 | this.DebugSettings.EnableFrameRateCounter = true;
47 | }
48 | #endif
49 |
50 | Frame rootFrame = Window.Current.Content as Frame;
51 |
52 | // Do not repeat app initialization when the Window already has content,
53 | // just ensure that the window is active
54 | if (rootFrame == null)
55 | {
56 | // Create a Frame to act as the navigation context and navigate to the first page
57 | rootFrame = new Frame();
58 |
59 | rootFrame.NavigationFailed += OnNavigationFailed;
60 |
61 | Xamarin.Forms.Forms.Init(e);
62 |
63 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
64 | {
65 | //TODO: Load state from previously suspended application
66 | }
67 |
68 | // Place the frame in the current Window
69 | Window.Current.Content = rootFrame;
70 | }
71 |
72 | if (rootFrame.Content == null)
73 | {
74 | // When the navigation stack isn't restored navigate to the first page,
75 | // configuring the new page by passing required information as a navigation
76 | // parameter
77 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
78 | }
79 | // Ensure the current window is active
80 | Window.Current.Activate();
81 | }
82 |
83 | ///
84 | /// Invoked when Navigation to a certain page fails
85 | ///
86 | /// The Frame which failed navigation
87 | /// Details about the navigation failure
88 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
89 | {
90 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
91 | }
92 |
93 | ///
94 | /// Invoked when application execution is being suspended. Application state is saved
95 | /// without knowing whether the application will be terminated or resumed with the contents
96 | /// of memory still intact.
97 | ///
98 | /// The source of the suspend request.
99 | /// Details about the suspend request.
100 | private void OnSuspending(object sender, SuspendingEventArgs e)
101 | {
102 | var deferral = e.SuspendingOperation.GetDeferral();
103 | //TODO: Save application state and stop any background activity
104 | deferral.Complete();
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.UWP/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/FB2Sample.XF.UWP.nuget.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(UserProfile)\.nuget\packages\
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | namespace FB2Sample.XF.UWP
17 | {
18 | public sealed partial class MainPage
19 | {
20 | public MainPage()
21 | {
22 | this.InitializeComponent();
23 |
24 | LoadApplication(new FB2Sample.XF.App());
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | FPCL.WIndows
18 | joaqu
19 | Assets\StoreLogo.png
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FB2Sample.XF.UWP")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FB2Sample.XF.UWP")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.UWP/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0",
4 | "Xamarin.Forms": "2.0.0.6482"
5 | },
6 | "frameworks": {
7 | "uap10.0": {}
8 | },
9 | "runtimes": {
10 | "win10-arm": {},
11 | "win10-arm-aot": {},
12 | "win10-x86": {},
13 | "win10-x86-aot": {},
14 | "win10-x64": {},
15 | "win10-x64-aot": {}
16 | }
17 | }
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Media.Animation;
17 | using Windows.UI.Xaml.Navigation;
18 |
19 | // The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
20 |
21 | namespace FB2Sample.XF.WinPhone
22 | {
23 | ///
24 | /// Provides application-specific behavior to supplement the default Application class.
25 | ///
26 | public sealed partial class App : Application
27 | {
28 | private TransitionCollection transitions;
29 |
30 | ///
31 | /// Initializes the singleton application object. This is the first line of authored code
32 | /// executed, and as such is the logical equivalent of main() or WinMain().
33 | ///
34 | public App()
35 | {
36 | this.InitializeComponent();
37 | this.Suspending += this.OnSuspending;
38 | }
39 |
40 | ///
41 | /// Invoked when the application is launched normally by the end user. Other entry points
42 | /// will be used when the application is launched to open a specific file, to display
43 | /// search results, and so forth.
44 | ///
45 | /// Details about the launch request and process.
46 | protected override void OnLaunched(LaunchActivatedEventArgs e)
47 | {
48 | #if DEBUG
49 | if (System.Diagnostics.Debugger.IsAttached)
50 | {
51 | this.DebugSettings.EnableFrameRateCounter = true;
52 | }
53 | #endif
54 |
55 | Frame rootFrame = Window.Current.Content as Frame;
56 |
57 | // Do not repeat app initialization when the Window already has content,
58 | // just ensure that the window is active
59 | if (rootFrame == null)
60 | {
61 | // Create a Frame to act as the navigation context and navigate to the first page
62 | rootFrame = new Frame();
63 |
64 | // TODO: change this value to a cache size that is appropriate for your application
65 | rootFrame.CacheSize = 1;
66 |
67 | Xamarin.Forms.Forms.Init(e);
68 |
69 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
70 | {
71 | // TODO: Load state from previously suspended application
72 | }
73 |
74 | // Place the frame in the current Window
75 | Window.Current.Content = rootFrame;
76 | }
77 |
78 | if (rootFrame.Content == null)
79 | {
80 | // Removes the turnstile navigation for startup.
81 | if (rootFrame.ContentTransitions != null)
82 | {
83 | this.transitions = new TransitionCollection();
84 | foreach (var c in rootFrame.ContentTransitions)
85 | {
86 | this.transitions.Add(c);
87 | }
88 | }
89 |
90 | rootFrame.ContentTransitions = null;
91 | rootFrame.Navigated += this.RootFrame_FirstNavigated;
92 |
93 | // When the navigation stack isn't restored navigate to the first page,
94 | // configuring the new page by passing required information as a navigation
95 | // parameter
96 | if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
97 | {
98 | throw new Exception("Failed to create initial page");
99 | }
100 | }
101 |
102 | // Ensure the current window is active
103 | Window.Current.Activate();
104 | }
105 |
106 | ///
107 | /// Restores the content transitions after the app has launched.
108 | ///
109 | /// The object where the handler is attached.
110 | /// Details about the navigation event.
111 | private void RootFrame_FirstNavigated(object sender, NavigationEventArgs e)
112 | {
113 | var rootFrame = sender as Frame;
114 | rootFrame.ContentTransitions = this.transitions ?? new TransitionCollection() { new NavigationThemeTransition() };
115 | rootFrame.Navigated -= this.RootFrame_FirstNavigated;
116 | }
117 |
118 | ///
119 | /// Invoked when application execution is being suspended. Application state is saved
120 | /// without knowing whether the application will be terminated or resumed with the contents
121 | /// of memory still intact.
122 | ///
123 | /// The source of the suspend request.
124 | /// Details about the suspend request.
125 | private void OnSuspending(object sender, SuspendingEventArgs e)
126 | {
127 | var deferral = e.SuspendingOperation.GetDeferral();
128 |
129 | // TODO: Save application state and stop any background activity
130 | deferral.Complete();
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/Logo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/Logo.scale-240.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/SmallLogo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/SmallLogo.scale-240.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/SplashScreen.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/SplashScreen.scale-240.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/Square71x71Logo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/Square71x71Logo.scale-240.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/StoreLogo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/StoreLogo.scale-240.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/WideLogo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Assets/WideLogo.scale-240.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
17 |
18 | namespace FB2Sample.XF.WinPhone
19 | {
20 | ///
21 | /// An empty page that can be used on its own or navigated to within a Frame.
22 | ///
23 | public sealed partial class MainPage
24 | {
25 | public MainPage()
26 | {
27 | this.InitializeComponent();
28 |
29 | this.NavigationCacheMode = NavigationCacheMode.Required;
30 |
31 | LoadApplication(new FB2Sample.XF.App());
32 | }
33 |
34 | ///
35 | /// Invoked when this page is about to be displayed in a Frame.
36 | ///
37 | /// Event data that describes how this page was reached.
38 | /// This parameter is typically used to configure the page.
39 | protected override void OnNavigatedTo(NavigationEventArgs e)
40 | {
41 | // TODO: Prepare page for display here.
42 |
43 | // TODO: If your application contains multiple pages, ensure that you are
44 | // handling the hardware Back button by registering for the
45 | // Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
46 | // If you are using the NavigationHelper provided by some templates,
47 | // this event is handled for you.
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 | FPCL.Windows8.WindowsPhone
12 | joaqu
13 | Assets\StoreLogo.png
14 |
15 |
16 |
17 | 6.3.1
18 | 6.3.1
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FB2Sample.XF.WinPhone.WindowsPhone")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FB2Sample.XF.WinPhone.WindowsPhone")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.WinPhone/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Media.Animation;
17 | using Windows.UI.Xaml.Navigation;
18 |
19 | // The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
20 |
21 | namespace FB2Sample.XF.Windows
22 | {
23 | ///
24 | /// Provides application-specific behavior to supplement the default Application class.
25 | ///
26 | public sealed partial class App : Application
27 | {
28 | ///
29 | /// Initializes the singleton application object. This is the first line of authored code
30 | /// executed, and as such is the logical equivalent of main() or WinMain().
31 | ///
32 | public App()
33 | {
34 | this.InitializeComponent();
35 | this.Suspending += this.OnSuspending;
36 | }
37 |
38 | ///
39 | /// Invoked when the application is launched normally by the end user. Other entry points
40 | /// will be used when the application is launched to open a specific file, to display
41 | /// search results, and so forth.
42 | ///
43 | /// Details about the launch request and process.
44 | protected override void OnLaunched(LaunchActivatedEventArgs e)
45 | {
46 | #if DEBUG
47 | if (System.Diagnostics.Debugger.IsAttached)
48 | {
49 | this.DebugSettings.EnableFrameRateCounter = true;
50 | }
51 | #endif
52 |
53 | Frame rootFrame = Window.Current.Content as Frame;
54 |
55 | // Do not repeat app initialization when the Window already has content,
56 | // just ensure that the window is active
57 | if (rootFrame == null)
58 | {
59 | // Create a Frame to act as the navigation context and navigate to the first page
60 | rootFrame = new Frame();
61 |
62 | // TODO: change this value to a cache size that is appropriate for your application
63 | rootFrame.CacheSize = 1;
64 |
65 | Xamarin.Forms.Forms.Init(e);
66 |
67 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
68 | {
69 | // TODO: Load state from previously suspended application
70 | }
71 |
72 | // Place the frame in the current Window
73 | Window.Current.Content = rootFrame;
74 | }
75 |
76 | if (rootFrame.Content == null)
77 | {
78 | // When the navigation stack isn't restored navigate to the first page,
79 | // configuring the new page by passing required information as a navigation
80 | // parameter
81 | if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
82 | {
83 | throw new Exception("Failed to create initial page");
84 | }
85 | }
86 |
87 | // Ensure the current window is active
88 | Window.Current.Activate();
89 | }
90 |
91 | ///
92 | /// Invoked when application execution is being suspended. Application state is saved
93 | /// without knowing whether the application will be terminated or resumed with the contents
94 | /// of memory still intact.
95 | ///
96 | /// The source of the suspend request.
97 | /// Details about the suspend request.
98 | private void OnSuspending(object sender, SuspendingEventArgs e)
99 | {
100 | var deferral = e.SuspendingOperation.GetDeferral();
101 |
102 | // TODO: Save application state and stop any background activity
103 | deferral.Complete();
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/Logo.scale-100.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/SmallLogo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/SmallLogo.scale-100.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/SplashScreen.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/SplashScreen.scale-100.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/StoreLogo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.Windows/Assets/StoreLogo.scale-100.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | namespace FB2Sample.XF.Windows
17 | {
18 | public sealed partial class MainPage
19 | {
20 | public MainPage()
21 | {
22 | this.InitializeComponent();
23 |
24 | LoadApplication(new FB2Sample.XF.App());
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 | FPCL.Windows8.Windows
10 | joaqu
11 | Assets\StoreLogo.png
12 |
13 |
14 |
15 | 6.3.0
16 | 6.3.0
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FB2Sample.XF.Windows.Windows")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FB2Sample.XF.Windows.Windows")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.Windows/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace FB2Sample.XF.iOS
9 | {
10 | // The UIApplicationDelegate for the application. This class is responsible for launching the
11 | // User Interface of the application, as well as listening (and optionally responding) to
12 | // application events from iOS.
13 | [Register("AppDelegate")]
14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
15 | {
16 | //
17 | // This method is invoked when the application has loaded and is ready to run. In this
18 | // method you should instantiate the window, load the UI into it and then make the window
19 | // visible.
20 | //
21 | // You have 17 seconds to return from this method, or iOS will terminate your application.
22 | //
23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
24 | {
25 | global::Xamarin.Forms.Forms.Init();
26 | LoadApplication(new App());
27 |
28 | return base.FinishedLaunching(app, options);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UISupportedInterfaceOrientations
11 |
12 | UIInterfaceOrientationPortrait
13 | UIInterfaceOrientationLandscapeLeft
14 | UIInterfaceOrientationLandscapeRight
15 |
16 | UISupportedInterfaceOrientations~ipad
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationPortraitUpsideDown
20 | UIInterfaceOrientationLandscapeLeft
21 | UIInterfaceOrientationLandscapeRight
22 |
23 | MinimumOSVersion
24 | 6.0
25 | CFBundleDisplayName
26 | FB2Sample.XF
27 | CFBundleIdentifier
28 | com.yourcompany.FB2Sample.XF
29 | CFBundleVersion
30 | 1.0
31 | CFBundleIconFiles
32 |
33 | Icon-60@2x
34 | Icon-60@3x
35 | Icon-76
36 | Icon-76@2x
37 | Default
38 | Default@2x
39 | Default-568h@2x
40 | Default-Portrait
41 | Default-Portrait@2x
42 | Icon-Small-40
43 | Icon-Small-40@2x
44 | Icon-Small-40@3x
45 | Icon-Small
46 | Icon-Small@2x
47 | Icon-Small@3x
48 |
49 | UILaunchStoryboardName
50 | LaunchScreen
51 |
52 |
53 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace FB2Sample.XF.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FB2Sample.XF.iOS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FB2Sample.XF.iOS")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default-Portrait.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Default@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-60@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-60@3x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-76.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-76@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small-40.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small-40@3x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small@2x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/Icon-Small@3x.png
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/Resources/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/iTunesArtwork:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/iTunesArtwork
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/iTunesArtwork@2x:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wcoder/FB2Library/776fd30e5c44d10db857d53574860beb13a5fb99/samples/FB2Sample.XF/FB2Sample.XF.iOS/iTunesArtwork@2x
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF.iOS/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF/App.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | using Xamarin.Forms;
7 |
8 | namespace FB2Sample.XF
9 | {
10 | public class App : Application
11 | {
12 | public App()
13 | {
14 | // The root page of your application
15 | MainPage = new MainPage();
16 | }
17 |
18 | protected override void OnStart()
19 | {
20 | // Handle when your app starts
21 | }
22 |
23 | protected override void OnSleep()
24 | {
25 | // Handle when your app sleeps
26 | }
27 |
28 | protected override void OnResume()
29 | {
30 | // Handle when your app resumes
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF/FB2Sample.XF.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 10.0
6 | Debug
7 | AnyCPU
8 | {B0201DAD-720E-49B2-9667-1677552FFAC3}
9 | Library
10 | Properties
11 | FB2Sample.XF
12 | FB2Sample.XF
13 | v4.5
14 | Profile111
15 | 512
16 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
17 |
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 | MainPage.xaml
41 |
42 |
43 |
44 |
45 |
46 | ..\..\..\packages\Xamarin.Forms.2.0.0.6482\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll
47 | True
48 |
49 |
50 | ..\..\..\packages\Xamarin.Forms.2.0.0.6482\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Platform.dll
51 | True
52 |
53 |
54 | ..\..\..\packages\Xamarin.Forms.2.0.0.6482\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Xaml.dll
55 | True
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | {185940bd-6cc8-4e7b-8658-76b538c875fc}
64 | FB2Library.Reader
65 |
66 |
67 | {718ce136-bcdc-4bf8-9863-adc7633eb2ca}
68 | FB2Library
69 |
70 |
71 |
72 |
73 | MSBuild:UpdateDesignTimeXaml
74 | Designer
75 |
76 |
77 |
78 |
79 |
80 |
81 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
82 |
83 |
84 |
85 |
92 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 | using FB2Library;
9 | using System.Net.Http;
10 | using FB2Library.Reader;
11 |
12 | namespace FB2Sample.XF
13 | {
14 | public partial class MainPage : ContentPage
15 | {
16 | private FB2File _file;
17 |
18 | public MainPage()
19 | {
20 | InitializeComponent();
21 | }
22 |
23 | private async void DownloadClicked(object sender, EventArgs args)
24 | {
25 | textBlock.Text = "Start download...";
26 |
27 | using (var httpClient = new HttpClient())
28 | {
29 | var stream = await httpClient.GetStreamAsync("https://dl.dropboxusercontent.com/u/30506652/data/test.fb2");
30 |
31 | textBlock.Text = "Reading...";
32 | try
33 | {
34 | using (var reader = new FB2Reader())
35 | {
36 | _file = await reader.LoadAsync(stream);
37 | }
38 | }
39 | catch (Exception ex)
40 | {
41 | bookInfo.Text = string.Format("Error loading file : {0}", ex.Message);
42 | }
43 | }
44 |
45 | PrepareFile();
46 | }
47 |
48 | private void PrepareFile()
49 | {
50 | textBlock.Text = "Done";
51 | if (_file.MainBody != null)
52 | {
53 | bookInfo.Text = $"Title: {_file.MainBody.Title.TitleData[0]} {_file.MainBody.Title.TitleData[1]}";
54 | }
55 | }
56 |
57 | private void CloseClicked(object sender, EventArgs args)
58 | {
59 | bookInfo.Text = string.Empty;
60 | _file = null;
61 | textBlock.Text = "Closed";
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Resources;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("FB2Sample.XF")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("FB2Sample.XF")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: NeutralResourcesLanguage("en")]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
--------------------------------------------------------------------------------
/samples/FB2Sample.XF/FB2Sample.XF/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/samples/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | enable
7 | enable
8 | 10.0
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/samples/FBLibrary.Sample.ConsoleApp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Imaging;
4 | using System.IO;
5 | using System.Text;
6 | using System.Xml;
7 | using FB2Library;
8 | using FB2Library.Elements;
9 |
10 |
11 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
12 |
13 | var filePath = Path.Combine("..", "..", "..", "..", "..", "files", "test.fb2");
14 |
15 | await using var fileStream = new FileStream(filePath, FileMode.Open);
16 |
17 | var readerSettings = new XmlReaderSettings
18 | {
19 | DtdProcessing = DtdProcessing.Ignore
20 | };
21 | var loadSettings = new XmlLoadSettings(readerSettings);
22 |
23 | BinaryItem.DetectContentType = binaryData =>
24 | {
25 | try
26 | {
27 | using var imgStream = new MemoryStream(binaryData);
28 |
29 | // For MacOS need native libgdiplus, more:
30 | // https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only#recommended-action
31 | #pragma warning disable CA1416
32 | using var bitmap = new Bitmap(imgStream);
33 |
34 | var rawFormat = bitmap.RawFormat;
35 |
36 | if (rawFormat.Equals(ImageFormat.Jpeg))
37 | return ContentTypeEnum.ContentTypeJpeg;
38 |
39 | if (rawFormat.Equals(ImageFormat.Png))
40 | return ContentTypeEnum.ContentTypePng;
41 |
42 | if (rawFormat.Equals(ImageFormat.Gif))
43 | return ContentTypeEnum.ContentTypeGif;
44 |
45 | return ContentTypeEnum.ContentTypeUnknown;
46 |
47 | #pragma warning restore CA1416
48 | }
49 | catch (Exception ex)
50 | {
51 | throw new Exception($"Error during image type detection: {ex}", ex);
52 | }
53 | };
54 |
55 |
56 | var reader = new FB2Reader();
57 | var file = await reader.ReadAsync(fileStream, loadSettings);
58 |
59 |
60 | Console.WriteLine("Done");
--------------------------------------------------------------------------------
/samples/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "configProperties": {
3 | "System.Drawing.EnableUnixSupport": true
4 | }
5 | }
--------------------------------------------------------------------------------
/src/Elements/AnnotationItem.cs:
--------------------------------------------------------------------------------
1 | namespace FB2Library.Elements
2 | {
3 | public class AnnotationItem : AnnotationType
4 | {
5 | internal const string Fb2AnnotationItemName = "annotation";
6 |
7 | public AnnotationItem()
8 | {
9 | ElementName = Fb2AnnotationItemName;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Elements/AnnotationType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml.Linq;
7 | using FB2Library.Elements.Poem;
8 | using FB2Library.Elements.Table;
9 |
10 | namespace FB2Library.Elements
11 | {
12 | public class AnnotationType : IFb2TextItem
13 | {
14 | private readonly List _content = new List();
15 |
16 | protected string GetElementName()
17 | {
18 | return ElementName;
19 | }
20 |
21 | public string ElementName { get; set; }
22 |
23 | public List Content => _content;
24 |
25 | public string ID { get; set; }
26 |
27 | public override string ToString()
28 | {
29 | StringBuilder builder = new StringBuilder();
30 | foreach (var textItem in _content)
31 | {
32 | builder.Append(textItem.ToString());
33 | builder.Append(" ");
34 | }
35 | return builder.ToString();
36 |
37 | }
38 |
39 | internal void Load(XElement xAnnotation)
40 | {
41 | if (xAnnotation == null)
42 | {
43 | throw new ArgumentNullException(nameof(xAnnotation));
44 | }
45 |
46 | if (xAnnotation.Name.LocalName != GetElementName())
47 | {
48 | throw new ArgumentException("Element of wrong type passed", nameof(xAnnotation));
49 | }
50 |
51 | _content.Clear();
52 | IEnumerable xItems = xAnnotation.Elements();
53 | foreach (var xItem in xItems)
54 | {
55 | switch (xItem.Name.LocalName)
56 | {
57 | case ParagraphItem.Fb2ParagraphElementName:
58 | ParagraphItem paragraph = new ParagraphItem();
59 | try
60 | {
61 | paragraph.Load(xItem);
62 | _content.Add(paragraph);
63 | }
64 | catch (Exception)
65 | {
66 | }
67 | break;
68 | case PoemItem.Fb2PoemElementName:
69 | PoemItem poem = new PoemItem();
70 | try
71 | {
72 | poem.Load(xItem);
73 | _content.Add(poem);
74 | }
75 | catch (Exception)
76 | {
77 | }
78 | break;
79 | case CiteItem.Fb2CiteElementName:
80 | CiteItem cite = new CiteItem();
81 | try
82 | {
83 | cite.Load(xItem);
84 | _content.Add(cite);
85 | }
86 | catch (Exception)
87 | {
88 | }
89 | break;
90 | case SubTitleItem.Fb2SubtitleElementName:
91 | SubTitleItem subtitle = new SubTitleItem();
92 | try
93 | {
94 | subtitle.Load(xItem);
95 | _content.Add(subtitle);
96 | }
97 | catch (Exception)
98 | {
99 | }
100 | break;
101 | case TableItem.Fb2TableElementName:
102 | TableItem table = new TableItem();
103 | try
104 | {
105 | table.Load(xItem);
106 | _content.Add(table);
107 | }
108 | catch (Exception)
109 | {
110 | }
111 | break;
112 | case EmptyLineItem.Fb2EmptyLineElementName:
113 | EmptyLineItem eline = new EmptyLineItem();
114 | _content.Add(eline);
115 | break;
116 | default:
117 | Debug.WriteLine(string.Format("AnnotationItem:Load - invalid element <{0}> encountered in annotation ."), xItem.Name.LocalName);
118 | break;
119 | }
120 | }
121 |
122 | ID = null;
123 | XAttribute xID = xAnnotation.Attribute("id");
124 | if ((xID != null) && (xID.Value != null))
125 | {
126 | ID = xID.Value;
127 | }
128 | }
129 |
130 | public XNode ToXML()
131 | {
132 | XElement xAnnotation = new XElement(Fb2Const.fb2DefaultNamespace+ ElementName);
133 | if (ID != null)
134 | {
135 | xAnnotation.Add(new XAttribute("id",ID));
136 | }
137 | foreach (IFb2TextItem Item in _content)
138 | {
139 | xAnnotation.Add(Item.ToXML());
140 | }
141 |
142 | return xAnnotation;
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/Elements/AuthorItem.cs:
--------------------------------------------------------------------------------
1 | namespace FB2Library.HeaderItems
2 | {
3 | class AuthorItem : AuthorType
4 | {
5 | public AuthorItem()
6 | {
7 | ElementName = AuthorElementName;
8 | }
9 | }
10 |
11 | class TranslatorItem : AuthorType
12 | {
13 | public TranslatorItem()
14 | {
15 | ElementName = TranslatorElementName;
16 | }
17 | }
18 |
19 | class PublisherItem : AuthorType
20 | {
21 | public PublisherItem()
22 | {
23 | ElementName = PublisherElementName;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Elements/BinaryItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | public enum ContentTypeEnum
7 | {
8 | ContentTypeUnknown,
9 | ContentTypeJpeg,
10 | ContentTypePng,
11 | ContentTypeGif,
12 | }
13 |
14 | public class BinaryItem
15 | {
16 | private const string ContentTypeAttributeName = "content-type";
17 | private const string IdAttributeName = "id";
18 |
19 | internal const string Fb2BinaryItemName = "binary";
20 |
21 | public static Func DetectContentType { get; set; }
22 |
23 | public ContentTypeEnum ContentType { get; set; }
24 | public byte[] BinaryData { get; set; }
25 | public string Id { get; set; }
26 |
27 | internal void Load(XElement binarye)
28 | {
29 | if (binarye == null)
30 | {
31 | throw new ArgumentNullException(nameof(binarye));
32 | }
33 |
34 | if (binarye.Name.LocalName != Fb2BinaryItemName)
35 | {
36 | throw new ArgumentException("Element of wrong type passed", nameof(binarye));
37 | }
38 |
39 | XAttribute xContentType = binarye.Attribute(ContentTypeAttributeName);
40 | if (xContentType?.Value == null)
41 | {
42 | throw new NullReferenceException("content type not defined/present");
43 | }
44 | switch (xContentType.Value.ToLower())
45 | {
46 | case "image/jpeg":
47 | case "image/jpg":
48 | ContentType = ContentTypeEnum.ContentTypeJpeg;
49 | break;
50 | case "image/png":
51 | ContentType = ContentTypeEnum.ContentTypePng;
52 | break;
53 | case "image/gif":
54 | ContentType = ContentTypeEnum.ContentTypeGif;
55 | break;
56 | case "application/octet-stream": // something not detected , generated by various converters
57 | break;
58 | }
59 |
60 | XAttribute idAttribute = binarye.Attribute(IdAttributeName);
61 |
62 | Id = idAttribute?.Value ?? throw new NullReferenceException("ID not defined/present");
63 |
64 | if (BinaryData != null)
65 | {
66 | BinaryData = null;
67 | }
68 | BinaryData = Convert.FromBase64String(binarye.Value);
69 |
70 | // try to detect type, this will detect for unknown and fix for wrongly set
71 | if (DetectContentType == null)
72 | {
73 | ContentType = ContentTypeEnum.ContentTypeUnknown;
74 | }
75 | else
76 | {
77 | var contentType = DetectContentType(BinaryData);
78 |
79 | // if we were not able to detect type and type was not set
80 | if (contentType == ContentTypeEnum.ContentTypeUnknown
81 | && ContentType == ContentTypeEnum.ContentTypeUnknown)
82 | {
83 | // then we throw exception
84 | throw new Exception("Unknown image content type passed");
85 | }
86 |
87 | ContentType = contentType;
88 | }
89 | }
90 |
91 | protected string GetXContentType()
92 | {
93 | switch (ContentType)
94 | {
95 | case ContentTypeEnum.ContentTypeJpeg:
96 | return "image/jpg";
97 | case ContentTypeEnum.ContentTypePng:
98 | return "image/png";
99 | case ContentTypeEnum.ContentTypeGif:
100 | return "image/gif";
101 | case ContentTypeEnum.ContentTypeUnknown:
102 | default:
103 | return "";
104 | }
105 | }
106 |
107 | public XElement ToXML()
108 | {
109 | XElement xBinary = new XElement(Fb2Const.fb2DefaultNamespace + Fb2BinaryItemName);
110 | xBinary.Add(new XAttribute(ContentTypeAttributeName,GetXContentType()));
111 | xBinary.Add(new XAttribute(IdAttributeName,Id));
112 | xBinary.Value=Convert.ToBase64String(BinaryData);
113 |
114 | return xBinary;
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/Elements/BodyItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Xml.Linq;
5 |
6 | namespace FB2Library.Elements
7 | {
8 | ///
9 | /// Main content of the book, multiple bodies are used for additional information, like footnotes, that do not appear in the main book flow.
10 | /// The first body is presented to the reader by default, and content in the other bodies should be accessible by hyperlinks.
11 | /// Name attribute should describe the meaning of this body, this is optional for the main body.
12 | ///
13 | public class BodyItem : IFb2TextItem
14 | {
15 | private readonly XNamespace linkNamespace = @"http://www.w3.org/1999/xlink";
16 |
17 | private readonly List sections = new List();
18 | private readonly List epigraphs = new List();
19 | private readonly TitleItem title = new TitleItem();
20 |
21 | private const string Fb2NameAttributeName = "name";
22 | private const string Fb2ImageElementName = "image";
23 |
24 |
25 |
26 | public XNamespace NameSpace { get; set; }
27 |
28 | public string Name { get; set; }
29 | public TitleItem Title { get { return title; } }
30 | public ImageItem ImageName { get; set; }
31 | public List Sections { get { return sections; } }
32 | public List Epigraphs { get { return epigraphs; } }
33 | public string Lang { get; set; }
34 |
35 | internal const string Fb2BodyItemName = "body";
36 |
37 | internal void Load(XElement xBody)
38 | {
39 | if (xBody == null)
40 | {
41 | throw new ArgumentNullException("xBody");
42 | }
43 |
44 | if (xBody.Name.LocalName != Fb2BodyItemName)
45 | {
46 | throw new ArgumentException("Element of wrong type passed", "xBody");
47 | }
48 |
49 |
50 | ImageName = null;
51 | XElement xImage = xBody.Element(NameSpace + Fb2ImageElementName);
52 | if ((xImage != null))
53 | {
54 | ImageName = new ImageItem();
55 | try
56 | {
57 | ImageName.Load(xImage);
58 | }
59 | catch (Exception ex)
60 | {
61 | Debug.WriteLine(string.Format("Error reading body image: {0}", ex.Message));
62 | }
63 | }
64 |
65 |
66 | XElement xTitle = xBody.Element(NameSpace + TitleItem.Fb2TitleElementName);
67 | if ((xTitle != null) && (xTitle.Value != null))
68 | {
69 | try
70 | {
71 | title.Load(xTitle);
72 | }
73 | catch (Exception ex)
74 | {
75 | Debug.WriteLine(string.Format("Error reading body title: {0}", ex.Message));
76 | }
77 | }
78 |
79 |
80 | // Load epigraph elements
81 | IEnumerable xEpigraphs = xBody.Elements(NameSpace + EpigraphItem.Fb2EpigraphElementName);
82 | epigraphs.Clear();
83 | foreach (var xEpigraph in xEpigraphs)
84 | {
85 | EpigraphItem item = new EpigraphItem();
86 | try
87 | {
88 | item.Load(xEpigraph);
89 | }
90 | catch (Exception ex)
91 | {
92 | Debug.WriteLine(string.Format("Error reading body epigraph: {0}", ex.Message));
93 | continue;
94 | }
95 | epigraphs.Add(item);
96 | }
97 |
98 |
99 | // Load body elements (first is main text)
100 | IEnumerable xSections = xBody.Elements(NameSpace + SectionItem.Fb2TextSectionElementName);
101 | sections.Clear();
102 | foreach (var section in xSections)
103 | {
104 | SectionItem item = new SectionItem();
105 | try
106 | {
107 | item.Load(section);
108 | }
109 | catch (Exception ex)
110 | {
111 | Debug.WriteLine(string.Format("Error reading body sections: {0}", ex.Message));
112 | continue;
113 | }
114 | sections.Add(item);
115 | }
116 |
117 | Name = string.Empty;
118 | XAttribute xName = xBody.Attribute(Fb2NameAttributeName);
119 | if ((xName != null) && (xName.Value != null))
120 | {
121 | Name = xName.Value;
122 | }
123 |
124 |
125 |
126 | Lang = null;
127 | XAttribute xLang = xBody.Attribute(XNamespace.Xml + "lang");
128 | if ((xLang != null) && (xLang.Value != null))
129 | {
130 | Lang = xLang.Value;
131 | }
132 |
133 |
134 | }
135 |
136 | public XNode ToXML()
137 | {
138 | XElement xBody = new XElement(Fb2Const.fb2DefaultNamespace + Fb2BodyItemName);
139 | if (!string.IsNullOrEmpty(Name))
140 | {
141 | xBody.Add(new XAttribute(Fb2NameAttributeName, Name));
142 | }
143 | if (!string.IsNullOrEmpty(Lang))
144 | {
145 | xBody.Add(new XAttribute(XNamespace.Xml + "lang", Lang));
146 | }
147 | if (ImageName != null)
148 | {
149 | xBody.Add(ImageName.ToXML());
150 | }
151 | if (Title != null)
152 | {
153 | xBody.Add(Title.ToXML());
154 | }
155 | foreach (EpigraphItem EpItem in epigraphs)
156 | {
157 | xBody.Add(EpItem.ToXML());
158 | }
159 | foreach (SectionItem SecItem in sections)
160 | {
161 | xBody.Add(SecItem.ToXML());
162 | }
163 |
164 | return xBody;
165 | }
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/Elements/CiteItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Xml.Linq;
5 | using FB2Library.Elements.Poem;
6 | using FB2Library.Elements.Table;
7 |
8 | namespace FB2Library.Elements
9 | {
10 | public class CiteItem : IFb2TextItem
11 | {
12 | internal const string Fb2CiteElementName = "cite";
13 |
14 | private readonly List _citeData = new List();
15 | private readonly List _textAuthors = new List();
16 |
17 | public string ID { get; set; }
18 | public List CiteData => _citeData;
19 | public List TextAuthors => _textAuthors;
20 | public string Lang { get; set; }
21 |
22 | internal void Load(XElement xCite)
23 | {
24 | _citeData.Clear();
25 | if (xCite == null)
26 | {
27 | throw new ArgumentNullException(nameof(xCite));
28 | }
29 |
30 | if (xCite.Name.LocalName != Fb2CiteElementName)
31 | {
32 | throw new ArgumentException("Element of wrong type passed", nameof(xCite));
33 | }
34 |
35 | _textAuthors.Clear();
36 | IEnumerable xItems = xCite.Elements();
37 | foreach (var element in xItems)
38 | {
39 | switch (element.Name.LocalName)
40 | {
41 | case ParagraphItem.Fb2ParagraphElementName:
42 | ParagraphItem paragraph = new ParagraphItem();
43 | try
44 | {
45 | paragraph.Load(element);
46 | _citeData.Add(paragraph);
47 | }
48 | catch (Exception)
49 | {
50 | }
51 | break;
52 | case PoemItem.Fb2PoemElementName:
53 | PoemItem poem = new PoemItem();
54 | try
55 | {
56 | poem.Load(element);
57 | _citeData.Add(poem);
58 | }
59 | catch (Exception)
60 | {
61 | }
62 | break;
63 | case EmptyLineItem.Fb2EmptyLineElementName:
64 | EmptyLineItem emptyLine = new EmptyLineItem();
65 | try
66 | {
67 | _citeData.Add(emptyLine);
68 | }
69 | catch (Exception)
70 | {
71 | }
72 | break;
73 | case SubTitleItem.Fb2SubtitleElementName:
74 | SubTitleItem subtitle = new SubTitleItem();
75 | try
76 | {
77 | subtitle.Load(element);
78 | _citeData.Add(subtitle);
79 | }
80 | catch (Exception)
81 | {
82 | }
83 | break;
84 | case TableItem.Fb2TableElementName:
85 | TableItem table = new TableItem();
86 | try
87 | {
88 | table.Load(element);
89 | _citeData.Add(table);
90 |
91 | }
92 | catch (Exception)
93 | {
94 | }
95 | break;
96 | case TextAuthorItem.Fb2TextAuthorElementName:
97 | //ParagraphItem author = new ParagraphItem();
98 | TextAuthorItem author = new TextAuthorItem();
99 | try
100 | {
101 | author.Load(element);
102 | _textAuthors.Add(author);
103 | }
104 | catch (Exception)
105 | {
106 | }
107 | break;
108 | default:
109 | Debug.WriteLine(
110 | $"CiteItem:Load - invalid element <{element.Name.LocalName}> encountered in title .");
111 | break;
112 | }
113 | }
114 |
115 | Lang = null;
116 | XAttribute xLang = xCite.Attribute(XNamespace.Xml + "lang");
117 | if (xLang != null && xLang.Value != null)
118 | {
119 | Lang = xLang.Value;
120 | }
121 |
122 | ID = null;
123 | XAttribute xID = xCite.Attribute("id");
124 | if (xID != null && xID.Value != null)
125 | {
126 | ID = xID.Value;
127 | }
128 |
129 | }
130 |
131 | public XNode ToXML()
132 | {
133 | XElement xCite = new XElement(Fb2Const.fb2DefaultNamespace + Fb2CiteElementName);
134 | if (!string.IsNullOrEmpty(ID))
135 | {
136 | xCite.Add(new XAttribute("id", ID));
137 | }
138 | if (!string.IsNullOrEmpty(Lang))
139 | {
140 | xCite.Add(new XAttribute(XNamespace.Xml + "lang", Lang));
141 | }
142 |
143 | foreach (IFb2TextItem citeItem in _citeData)
144 | {
145 | xCite.Add(citeItem.ToXML());
146 | }
147 | foreach (ParagraphItem authorItem in _textAuthors)
148 | {
149 | xCite.Add(authorItem.ToXML());
150 | }
151 |
152 | return xCite;
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/Elements/CustomTextFieldType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | public class CustomTextFieldType : TextFieldType
7 | {
8 | ///
9 | /// Get/Set info-type attribute
10 | ///
11 | public string InfoType { get; private set; }
12 |
13 | public override void Load(XElement xElement)
14 | {
15 | base.Load(xElement);
16 |
17 | InfoType = null;
18 | XAttribute xInfoType = xElement.Attribute("info-type");
19 | if (xInfoType == null)
20 | {
21 | throw new Exception("info-type attribute required for custom info element");
22 | }
23 |
24 | InfoType = xInfoType.Value;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Elements/DateItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | ///
7 | /// A human readable date, maybe not exact, with an optional computer readable variant
8 | ///
9 | public class DateItem : IFb2TextItem
10 | {
11 | internal const string Fb2DateElementName = "date";
12 |
13 | ///
14 | /// Get/Set Date as Text
15 | ///
16 | public string Text { get; set; }
17 |
18 | ///
19 | /// Get/Set Date in computer readable form
20 | ///
21 | public DateTime DateValue{get;set;}
22 |
23 | ///
24 | /// Get/Set language
25 | ///
26 | public string Language { get; set; }
27 |
28 | internal void Load(XElement xDate)
29 | {
30 | if (xDate == null)
31 | {
32 | throw new ArgumentNullException(nameof(xDate));
33 | }
34 |
35 | if (xDate.Name.LocalName != Fb2DateElementName)
36 | {
37 | throw new ArgumentException("Element of wrong type passed", nameof(xDate));
38 | }
39 |
40 | if (xDate.Value != null)
41 | {
42 | Text = xDate.Value;
43 | }
44 |
45 | XAttribute xDateValue = xDate.Attribute("value");
46 | if (xDateValue != null && xDateValue.Value != null)
47 | {
48 | try
49 | {
50 | DateValue = DateTime.Parse(xDateValue.Value);
51 | }
52 | catch (Exception)
53 | {
54 | // ignore
55 | }
56 | }
57 |
58 | Language = null;
59 | XAttribute xLang = xDate.Attribute(XNamespace.Xml + "lang");
60 | if (xLang != null && string.IsNullOrEmpty(xLang.Value))
61 | {
62 | Language = xLang.Value;
63 | }
64 | }
65 |
66 | public XNode ToXML()
67 | {
68 | XElement xDate = new XElement(Fb2Const.fb2DefaultNamespace + Fb2DateElementName);
69 | if (!string.IsNullOrEmpty(Text))
70 | {
71 | xDate.Value = Text;
72 | }
73 | if (!string.IsNullOrEmpty(Language))
74 | {
75 | xDate.Add(new XAttribute(XNamespace.Xml + "lang", Language));
76 | }
77 | if (!DateValue.Equals(DateTime.MinValue))
78 | {
79 | xDate.Add(new XAttribute("value", DateValue.ToString("d")));
80 | }
81 | return xDate;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Elements/EmptyLineItem.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 |
3 | namespace FB2Library.Elements
4 | {
5 | public class EmptyLineItem : IFb2TextItem
6 | {
7 | internal const string Fb2EmptyLineElementName = "empty-line";
8 |
9 | public override string ToString()
10 | {
11 | return "\n";
12 | }
13 | public XNode ToXML()
14 | {
15 | return new XElement(Fb2Const.fb2DefaultNamespace + Fb2EmptyLineElementName);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Elements/EpigraphItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Xml.Linq;
5 | using FB2Library.Elements.Poem;
6 |
7 | namespace FB2Library.Elements
8 | {
9 | public class EpigraphItem : IFb2TextItem
10 | {
11 | internal const string Fb2EpigraphElementName = "epigraph";
12 |
13 | private readonly List _epigraphData = new List();
14 | private readonly List _textAuthors = new List();
15 |
16 | public string ID { get; set; }
17 | public List EpigraphData => _epigraphData;
18 | public List TextAuthors => _textAuthors;
19 |
20 | internal void Load(XElement xEpigraph)
21 | {
22 | _epigraphData.Clear();
23 | if (xEpigraph == null)
24 | {
25 | throw new ArgumentNullException(nameof(xEpigraph));
26 | }
27 | if (xEpigraph.Name.LocalName != Fb2EpigraphElementName)
28 | {
29 | throw new ArgumentException("Element of wrong type passed", nameof(xEpigraph));
30 | }
31 |
32 | IEnumerable xItems = xEpigraph.Elements();
33 | _textAuthors.Clear();
34 | foreach (var element in xItems)
35 | {
36 | switch (element.Name.LocalName)
37 | {
38 | case ParagraphItem.Fb2ParagraphElementName:
39 | ParagraphItem paragraph = new ParagraphItem();
40 | try
41 | {
42 | paragraph.Load(element);
43 | _epigraphData.Add(paragraph);
44 | }
45 | catch (Exception ex)
46 | {
47 | Debug.WriteLine($"Failed to load paragraph: {ex.Message}.");
48 | }
49 | break;
50 | case PoemItem.Fb2PoemElementName:
51 | PoemItem poem = new PoemItem();
52 | try
53 | {
54 | poem.Load(element);
55 | _epigraphData.Add(poem);
56 | }
57 | catch (Exception ex)
58 | {
59 | Debug.WriteLine($"Failed to load poem: {ex.Message}.");
60 | }
61 | break;
62 | case CiteItem.Fb2CiteElementName:
63 | CiteItem cite = new CiteItem();
64 | try
65 | {
66 | cite.Load(element);
67 | _epigraphData.Add(cite);
68 | }
69 | catch (Exception ex)
70 | {
71 | Debug.WriteLine($"Failed to load citation: {ex.Message}.");
72 | }
73 | break;
74 | case EmptyLineItem.Fb2EmptyLineElementName:
75 | EmptyLineItem emptyLine = new EmptyLineItem();
76 | try
77 | {
78 | _epigraphData.Add(emptyLine);
79 | }
80 | catch (Exception ex)
81 | {
82 | Debug.WriteLine($"Failed to load empty line: {ex.Message}.");
83 | }
84 | break;
85 | case TextAuthorItem.Fb2TextAuthorElementName:
86 | TextAuthorItem author = new TextAuthorItem();
87 | //SimpleText author = new SimpleText();
88 | try
89 | {
90 | author.Load(element);
91 | _textAuthors.Add(author);
92 | }
93 | catch (Exception ex)
94 | {
95 | Debug.WriteLine($"Failed to load text author: {ex.Message}.");
96 | }
97 | break;
98 | default:
99 | Debug.WriteLine(
100 | $"EpigraphItem:Load - invalid element <{element.Name.LocalName}> encountered in title.");
101 | break;
102 | }
103 | }
104 |
105 | XAttribute xID = xEpigraph.Attribute("id");
106 | if (xID != null && xID.Value != null)
107 | {
108 | ID = xID.Value;
109 | }
110 | }
111 |
112 | public XNode ToXML()
113 | {
114 | XElement xEpigraph = new XElement(Fb2Const.fb2DefaultNamespace + Fb2EpigraphElementName);
115 | if (!string.IsNullOrEmpty(ID))
116 | {
117 | xEpigraph.Add(new XAttribute("id", ID));
118 | }
119 |
120 | foreach (IFb2TextItem epigrafItem in _epigraphData)
121 | {
122 | xEpigraph.Add(epigrafItem.ToXML());
123 | }
124 | foreach (IFb2TextItem epigrafAuthor in _textAuthors)
125 | {
126 | xEpigraph.Add(epigrafAuthor.ToXML());
127 | }
128 |
129 | return xEpigraph;
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/Elements/FB2Const.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 |
3 | namespace FB2Library.Elements
4 | {
5 | public class Fb2Const
6 | {
7 | public static XNamespace fb2DefaultNamespace = @"http://www.gribuser.ru/xml/fictionbook/2.0";
8 |
9 | //public XNamespace FB2DefaultNamespace {get {return fb2DefaultNamespace;}}
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Elements/FB2TextItem.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 |
3 | namespace FB2Library.Elements
4 | {
5 | public enum TextStyles
6 | {
7 | Normal = 0,
8 | Strong, //
9 | Emphasis, //
10 | Code, //
11 | Sub, //
12 | Sup, //
13 | Strikethrough, //
14 | }
15 |
16 |
17 | public interface IFb2TextItem
18 | {
19 | XNode ToXML();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Elements/GenreType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | ///
7 | /// Holds genre element
8 | ///
9 | public class GenreType
10 | {
11 | ///
12 | /// Get/Set genre
13 | ///
14 | public string Genre { get; set; }
15 | }
16 |
17 | ///
18 | /// Extends GenreType class to support match
19 | /// match from 1 to 100%
20 | ///
21 | public class TitleGenreType : GenreType
22 | {
23 | private int _match = 100;
24 |
25 | ///
26 | /// Get/Set matching value , can be from 1 to 100%
27 | ///
28 | public int Match
29 | {
30 | get => _match;
31 | set
32 | {
33 | if (value > 0 && value <= 100)
34 | {
35 | _match = value;
36 | }
37 | else
38 | {
39 | _match = 100;
40 | }
41 | }
42 | }
43 |
44 | public XElement ToXML()
45 | {
46 | if (string.IsNullOrEmpty(Genre))
47 | {
48 | throw new ArgumentException("Genre is empty");
49 | }
50 |
51 | XElement xGenre = new XElement(Fb2Const.fb2DefaultNamespace + "genre", Genre);
52 | if (_match > 0 && _match < 100)
53 | {
54 | xGenre.Add(new XAttribute("match",_match.ToString()));
55 | }
56 | return xGenre;
57 | }
58 |
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Elements/ImageItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | public class ImageItem : IFb2TextItem
7 | {
8 | internal const string Fb2ImageElementName = "image";
9 |
10 | private readonly XNamespace _xLinkNamespace = @"http://www.w3.org/1999/xlink";
11 |
12 | public string ImageType { get; set; }
13 | public string HRef { get; set; }
14 | public string AltText { get; set; }
15 | public string Title { get; set; }
16 | public string ID { get; set; }
17 |
18 | internal void Load(XElement xImage)
19 | {
20 | if (xImage == null)
21 | {
22 | throw new ArgumentNullException(nameof(xImage));
23 | }
24 |
25 | if (xImage.Name.LocalName != Fb2ImageElementName)
26 | {
27 | throw new ArgumentException("Element of wrong type passed", nameof(xImage));
28 | }
29 |
30 | XAttribute xType = xImage.Attribute(_xLinkNamespace + "type");
31 | if (xType != null && xType.Value != null)
32 | {
33 | ImageType = xType.Value;
34 | }
35 |
36 |
37 | XAttribute xHRef = xImage.Attribute(_xLinkNamespace + "href");
38 | if (xHRef != null && xHRef.Value != null)
39 | {
40 | HRef = xHRef.Value;
41 | }
42 |
43 | XAttribute xAlt = xImage.Attribute("alt");
44 | if (xAlt != null && xAlt.Value != null)
45 | {
46 | AltText = xAlt.Value;
47 | }
48 |
49 | XAttribute xTitle = xImage.Attribute("title");
50 | if (xTitle != null && xTitle.Value != null)
51 | {
52 | Title = xTitle.Value;
53 | }
54 |
55 | XAttribute xID = xImage.Attribute("id");
56 | if (xID != null && xID.Value != null)
57 | {
58 | ID = xID.Value;
59 | }
60 | }
61 |
62 | public XNode ToXML()
63 | {
64 | XElement xImage = new XElement(Fb2Const.fb2DefaultNamespace + Fb2ImageElementName);
65 | if (!string.IsNullOrEmpty(ImageType))
66 | {
67 | xImage.Add(new XAttribute(_xLinkNamespace + "type", ImageType));
68 | }
69 | if (!string.IsNullOrEmpty(HRef))
70 | {
71 | xImage.Add(new XAttribute(_xLinkNamespace + "href", HRef));
72 | }
73 | if (!string.IsNullOrEmpty(AltText))
74 | {
75 | xImage.Add(new XAttribute("alt", AltText));
76 | }
77 | if (!string.IsNullOrEmpty(Title))
78 | {
79 | xImage.Add(new XAttribute("title", Title));
80 | }
81 | if (!string.IsNullOrEmpty(ID))
82 | {
83 | xImage.Add(new XAttribute("id", ID));
84 | }
85 | return xImage;
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/Elements/InlineImageItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | public class InlineImageItem : StyleType
7 | {
8 | internal const string Fb2InlineImageElementName = "image";
9 |
10 | private readonly XNamespace xLinkNamespace = @"http://www.w3.org/1999/xlink";
11 |
12 | protected virtual string GetElementName()
13 | {
14 | return Fb2InlineImageElementName;
15 | }
16 |
17 | public string ImageType { get; set;}
18 | public string HRef { get; set;}
19 | public string AltText { get; set;}
20 |
21 | public override string ToString()
22 | {
23 | return HRef;
24 | }
25 |
26 | internal void Load(XElement xImage)
27 | {
28 | if (xImage == null)
29 | {
30 | throw new ArgumentNullException(nameof(xImage));
31 | }
32 |
33 | if (xImage.Name.LocalName != GetElementName())
34 | {
35 | throw new ArgumentException("Element of wrong type passed", nameof(xImage));
36 | }
37 |
38 | XAttribute xType = xImage.Attribute(xLinkNamespace + "type");
39 | if ((xType != null) && (xType.Value != null))
40 | {
41 | ImageType = xType.Value;
42 | }
43 | else // to fix badly formated FB2s
44 | {
45 | xType = xImage.Attribute("type");
46 | if ((xType != null) && (xType.Value != null))
47 | {
48 | ImageType = xType.Value;
49 | }
50 | }
51 |
52 |
53 | XAttribute xHRef = xImage.Attribute(xLinkNamespace + "href");
54 | if ((xHRef != null) && (xHRef.Value != null))
55 | {
56 | HRef = xHRef.Value;
57 | }
58 | else // to fix badly formated FB2s
59 | {
60 | xHRef = xImage.Attribute(xLinkNamespace + "href");
61 | if ((xHRef != null) && (xHRef.Value != null))
62 | {
63 | HRef = xHRef.Value;
64 | }
65 | }
66 |
67 | XAttribute xAlt = xImage.Attribute(xLinkNamespace + "alt");
68 | if ((xAlt != null) &&(xAlt.Value != null))
69 | {
70 | AltText = xAlt.Value;
71 | }
72 | else // to fix badly formated FB2s
73 | {
74 | xAlt = xImage.Attribute(xLinkNamespace + "alt");
75 | if ((xAlt != null) && (xAlt.Value != null))
76 | {
77 | AltText = xAlt.Value;
78 | }
79 | }
80 | }
81 |
82 | public XNode ToXML()
83 | {
84 | XElement xImage = new XElement(Fb2Const.fb2DefaultNamespace + Fb2InlineImageElementName);
85 | if (!string.IsNullOrEmpty(ImageType))
86 | {
87 | xImage.Add(new XAttribute(xLinkNamespace + "type",ImageType));
88 | }
89 | if (!string.IsNullOrEmpty(HRef))
90 | {
91 | xImage.Add(new XAttribute(xLinkNamespace + "href",HRef));
92 | }
93 | if (!string.IsNullOrEmpty(AltText))
94 | {
95 | xImage.Add(new XAttribute("alt", AltText));
96 | }
97 | return xImage;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Elements/InternalLinkItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Xml;
5 | using System.Xml.Linq;
6 |
7 | namespace FB2Library.Elements
8 | {
9 | public class InternalLinkItem : StyleType
10 | {
11 | internal const string Fb2InternalLinkElementName = "a";
12 |
13 | private readonly XNamespace lNamespace = @"http://www.w3.org/1999/xlink";
14 |
15 | private readonly List _linkData = new List();
16 |
17 | public string Type { get; set; }
18 | public string HRef { get; set; }
19 |
20 | public List LinkData => _linkData;
21 |
22 | public override string ToString()
23 | {
24 | StringBuilder builder = new StringBuilder();
25 | builder.Append("");
35 | foreach (var item in _linkData)
36 | {
37 | builder.Append(item.ToString());
38 | builder.Append(" ");
39 | }
40 | builder.Append("");
41 | return builder.ToString();
42 | }
43 |
44 | internal void Load(XElement xLink)
45 | {
46 | if (xLink == null)
47 | {
48 | throw new ArgumentNullException(nameof(xLink));
49 | }
50 | if (xLink.Name.LocalName != Fb2InternalLinkElementName)
51 | {
52 | throw new ArgumentException("Element of wrong type passed", nameof(xLink));
53 | }
54 |
55 | if (xLink.HasElements)
56 | {
57 | IEnumerable childElements = xLink.Nodes();
58 | foreach (var element in childElements)
59 | {
60 | if ((element.NodeType == XmlNodeType.Element) && !IsSimpleText(element))
61 | {
62 | XElement xElement = (XElement)element;
63 | if (xElement.Name.LocalName == InlineImageItem.Fb2InlineImageElementName)
64 | {
65 | InlineImageItem image = new InlineImageItem();
66 | try
67 | {
68 | image.Load(xElement);
69 | _linkData.Add(image);
70 | }
71 | catch (Exception)
72 | {
73 | // ignored
74 | }
75 | }
76 | else if (xElement.Name.LocalName == StyleItem.StyleItemName)
77 | {
78 | StyleItem styleItem = new StyleItem();
79 | try
80 | {
81 | styleItem.Load(xElement);
82 | _linkData.Add(styleItem);
83 | }
84 | catch (Exception)
85 | {
86 | // ignored
87 | }
88 | }
89 | }
90 | else
91 | {
92 | SimpleText text = new SimpleText();
93 | try
94 | {
95 | text.Load(element);
96 | _linkData.Add(text);
97 | }
98 | catch (Exception)
99 | {
100 | // ignored
101 | }
102 | }
103 | }
104 | }
105 | else if (!string.IsNullOrEmpty(xLink.Value))
106 | {
107 | SimpleText text = new SimpleText();
108 | text.Load(xLink);
109 | _linkData.Add(text);
110 | }
111 |
112 | XAttribute xTypeAttr = xLink.Attribute("type");
113 | if (xTypeAttr != null && xTypeAttr.Value != null)
114 | {
115 | Type = xTypeAttr.Value;
116 | }
117 |
118 | XAttribute xHRefAttr = xLink.Attribute(lNamespace + "href");
119 | if (xHRefAttr != null && xHRefAttr.Value != null)
120 | {
121 | HRef = xHRefAttr.Value;
122 | }
123 | }
124 |
125 | private bool IsSimpleText(XNode element)
126 | {
127 | // if not element than we assume simple text
128 | if (element.NodeType != XmlNodeType.Element)
129 | {
130 | return true;
131 | }
132 | XElement xElement = (XElement)element;
133 | if (xElement.Name.LocalName == Fb2InternalLinkElementName)
134 | {
135 | throw new ArgumentException("Schema doesn't support nested links");
136 | }
137 | switch (xElement.Name.LocalName)
138 | {
139 | case InlineImageItem.Fb2InlineImageElementName:
140 | case StyleItem.StyleItemName:
141 | return false;
142 | }
143 | return true;
144 | }
145 |
146 | public XNode ToXML()
147 | {
148 | XElement xLink = new XElement(Fb2Const.fb2DefaultNamespace + Fb2InternalLinkElementName);
149 | if (!string.IsNullOrEmpty(Type))
150 | {
151 | xLink.Add(new XAttribute("type", Type));
152 | }
153 | if (!string.IsNullOrEmpty(HRef))
154 | {
155 | xLink.Add(new XAttribute(lNamespace + "href", HRef));
156 | }
157 | foreach (StyleType childElements in _linkData)
158 | {
159 | xLink.Add(childElements.ToXML());
160 | }
161 | return xLink;
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/Elements/OutPutDocumentType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Xml.Linq;
5 |
6 | namespace FB2Library.Elements
7 | {
8 | public class OutPutDocumentType : IShareInstructionElement
9 | {
10 | public const string OutputDocumentElementName = "output-document-class";
11 |
12 | private readonly List _parts = new List();
13 |
14 | private XNamespace _fileNameSpace = XNamespace.None;
15 |
16 | ///
17 | /// XML namespace used to read the document
18 | ///
19 | public XNamespace Namespace
20 | {
21 | set { _fileNameSpace = value; }
22 | get { return _fileNameSpace; }
23 | }
24 |
25 | ///
26 | /// Get list of the instruction parts
27 | ///
28 | public List Parts => _parts;
29 |
30 | ///
31 | /// Get/Set Name attribute
32 | ///
33 | public string Name { get; set;}
34 |
35 | ///
36 | /// Get/Set document part creation type
37 | ///
38 | public GenerationInstructionEnum Create { get; set; }
39 |
40 | ///
41 | /// Get/Set price
42 | ///
43 | public float? Price { get; set; }
44 |
45 | public void Load(XElement xElement)
46 | {
47 | if (xElement == null)
48 | {
49 | throw new ArgumentNullException(nameof(xElement));
50 | }
51 |
52 | _parts.Clear();
53 | IEnumerable xParts = xElement.Elements(_fileNameSpace + "part");
54 | foreach (var xPart in xParts)
55 | {
56 | ShareInstructionType part = new ShareInstructionType {Namespace = _fileNameSpace};
57 | try
58 | {
59 | part.Load(xPart);
60 | _parts.Add(part);
61 | }
62 | catch (Exception)
63 | {
64 | // ignored
65 | }
66 | }
67 |
68 | Name = null;
69 | XAttribute xName = xElement.Attribute("name");
70 | if (xName == null)
71 | {
72 | throw new Exception("name is required attribute - absent");
73 | }
74 | Name = xName.Value;
75 |
76 |
77 | Create = GenerationInstructionEnum.Unknown;
78 | XAttribute xCreate = xElement.Attribute("create");
79 | if (xCreate != null)
80 | {
81 | switch (xCreate.Value)
82 | {
83 | case "require":
84 | Create = GenerationInstructionEnum.Require;
85 | break;
86 | case "allow":
87 | Create = GenerationInstructionEnum.Allow;
88 | break;
89 | case "deny":
90 | Create = GenerationInstructionEnum.Deny;
91 | break;
92 | default:
93 | Debug.WriteLine($"Invalid instruction type : {xCreate.Value}");
94 | break;
95 | }
96 | }
97 |
98 | Price = null;
99 | XAttribute xPrice = xElement.Attribute("price");
100 | if (xPrice != null && !string.IsNullOrEmpty(xPrice.Value))
101 | {
102 | if (float.TryParse(xPrice.Value, out var val))
103 | {
104 | Price = val;
105 | }
106 | }
107 |
108 | }
109 | private string GetXCreate()
110 | {
111 | switch (Create)
112 | {
113 | case GenerationInstructionEnum.Require:
114 | return "require";
115 | case GenerationInstructionEnum.Allow:
116 | return "allow";
117 | case GenerationInstructionEnum.Deny:
118 | return "deny";
119 | default:
120 | return "";
121 | //Debug.WriteLine(string.Format("Invalid instruction type : {0}", xIncludeAll.Value));
122 | //break;
123 | }
124 | }
125 |
126 | public XElement ToXML()
127 | {
128 | XElement xOutputDocumentClass = new XElement(Fb2Const.fb2DefaultNamespace + OutputDocumentElementName);
129 | xOutputDocumentClass.Add(new XAttribute("name", Name));
130 | if (Create != GenerationInstructionEnum.Unknown)
131 | {
132 | xOutputDocumentClass.Add(new XAttribute("create", GetXCreate()));
133 | }
134 | if (Price != null)
135 | {
136 | xOutputDocumentClass.Add(new XAttribute("price", Price.ToString()));
137 | }
138 | foreach (ShareInstructionType partElement in _parts)
139 | {
140 | xOutputDocumentClass.Add(partElement.ToXML());
141 | }
142 | return xOutputDocumentClass;
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/Elements/PartShareInstructionType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml.Linq;
7 |
8 | namespace FB2Library.Elements
9 | {
10 | ///
11 | /// Pointer to cpecific document section, explaining how to deal with it
12 | ///
13 | public class PartShareInstructionType : IShareInstructionElement
14 | {
15 | private readonly XNamespace lNamespace = @"http://www.w3.org/1999/xlink";
16 |
17 | public const string PartElementName = "part";
18 |
19 | public string Type { get; set; }
20 |
21 | public string HRef { get; set; }
22 |
23 |
24 | public GenerationInstructionEnum Instruction { get; set; }
25 |
26 |
27 | private XNamespace fileNameSpace = XNamespace.None;
28 |
29 | ///
30 | /// XML namespace used to read the document
31 | ///
32 | public XNamespace Namespace
33 | {
34 | set { fileNameSpace = value; }
35 | get { return fileNameSpace; }
36 | }
37 |
38 | public void Load(XElement xElement)
39 | {
40 | if (xElement == null)
41 | {
42 | throw new ArgumentNullException("xElement");
43 | }
44 |
45 | Type = null;
46 | XAttribute xType = xElement.Attribute(lNamespace + "type");
47 | if (xType != null)
48 | {
49 | Type = xType.Value;
50 | }
51 |
52 | HRef = null;
53 | XAttribute xHRef = xElement.Attribute(lNamespace + "href");
54 | if (xHRef == null)
55 | {
56 | throw new Exception("href is required attribute - absent");
57 | }
58 | HRef = xHRef.Value;
59 |
60 |
61 | XAttribute xIncude = xElement.Attribute("include");
62 | if (xIncude == null)
63 | {
64 | throw new Exception("include is required attribute - absent");
65 | }
66 | switch (xIncude.Value)
67 | {
68 | case "require":
69 | Instruction = GenerationInstructionEnum.Require;
70 | break;
71 | case "allow":
72 | Instruction = GenerationInstructionEnum.Allow;
73 | break;
74 | case "deny":
75 | Instruction = GenerationInstructionEnum.Deny;
76 | break;
77 | default:
78 | Debug.WriteLine(string.Format("Invalid instruction type : {0}", xIncude.Value));
79 | break;
80 | }
81 |
82 | }
83 |
84 | private string GetXInclude()
85 | {
86 | switch (Instruction)
87 | {
88 | case GenerationInstructionEnum.Require:
89 | return "require";
90 | case GenerationInstructionEnum.Allow:
91 | return "allow";
92 | case GenerationInstructionEnum.Deny:
93 | return "deny";
94 | default:
95 | return "";
96 | //Debug.WriteLine(string.Format("Invalid instruction type : {0}", xIncludeAll.Value));
97 | //break;
98 | }
99 | }
100 | public XElement ToXML()
101 | {
102 | XElement xPart = new XElement(Fb2Const.fb2DefaultNamespace + PartElementName);
103 | if (!string.IsNullOrEmpty(Type))
104 | {
105 | xPart.Add(new XAttribute(lNamespace + "type", Type));
106 | }
107 | xPart.Add(new XAttribute(lNamespace + "href", HRef));
108 | xPart.Add(new XAttribute("include", GetXInclude()));
109 |
110 | return xPart;
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/Elements/Poem/StanzaItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Xml.Linq;
4 |
5 | namespace FB2Library.Elements.Poem
6 | {
7 | public class StanzaItem : IFb2TextItem
8 | {
9 | internal const string Fb2StanzaElementName = "stanza";
10 |
11 | private readonly List _lines = new List();
12 |
13 | public TitleItem Title { get; set; }
14 | public SubTitleItem SubTitle { get; set; }
15 | public List Lines => _lines;
16 | public string Lang { get; set; }
17 |
18 | internal void Load(XElement xStanza)
19 | {
20 | if (xStanza == null)
21 | {
22 | throw new ArgumentNullException(nameof(xStanza));
23 | }
24 |
25 | if (xStanza.Name.LocalName != Fb2StanzaElementName)
26 | {
27 | throw new ArgumentException("Element of wrong type passed", nameof(xStanza));
28 | }
29 |
30 | Title = null;
31 | XElement xTitle = xStanza.Element(xStanza.Name.Namespace + TitleItem.Fb2TitleElementName);
32 | if (xTitle != null)
33 | {
34 | Title = new TitleItem();
35 | try
36 | {
37 | Title.Load(xTitle);
38 | }
39 | catch (Exception)
40 | {
41 | // ignored
42 | }
43 | }
44 |
45 | SubTitle = null;
46 | XElement xSubtitle = xStanza.Element(xStanza.Name.Namespace + SubTitleItem.Fb2SubtitleElementName);
47 | if (xSubtitle != null)
48 | {
49 | SubTitle = new SubTitleItem();
50 | try
51 | {
52 | SubTitle.Load(xSubtitle);
53 | }
54 | catch (Exception)
55 | {
56 | // ignored
57 | }
58 | }
59 |
60 | _lines.Clear();
61 | IEnumerable xLines = xStanza.Elements(xStanza.Name.Namespace + VPoemParagraph.Fb2VParagraphItemName);
62 | foreach (var xLine in xLines)
63 | {
64 | VPoemParagraph vline = new VPoemParagraph();
65 | try
66 | {
67 | vline.Load(xLine);
68 | _lines.Add(vline);
69 | }
70 | catch (Exception)
71 | {
72 | // ignored
73 | }
74 | }
75 |
76 | Lang = null;
77 | XAttribute xLang = xStanza.Attribute(XNamespace.Xml + "lang");
78 | if (xLang != null && xLang.Value != null)
79 | {
80 | Lang = xLang.Value;
81 | }
82 |
83 | }
84 |
85 | public XNode ToXML()
86 | {
87 | XElement xStanza = new XElement(Fb2Const.fb2DefaultNamespace + Fb2StanzaElementName);
88 | if (!string.IsNullOrEmpty(Lang))
89 | {
90 | xStanza.Add(new XAttribute(XNamespace.Xml + "lang", Lang));
91 | }
92 | if (Title != null)
93 | {
94 | xStanza.Add(Title.ToXML());
95 | }
96 | if (SubTitle != null)
97 | {
98 | xStanza.Add(SubTitle.ToXML());
99 | }
100 | foreach (VPoemParagraph poemLine in _lines)
101 | {
102 | xStanza.Add(poemLine.ToXML());
103 | }
104 |
105 | return xStanza;
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/Elements/Poem/VPoemParagraph.cs:
--------------------------------------------------------------------------------
1 | namespace FB2Library.Elements.Poem
2 | {
3 | public class VPoemParagraph : ParagraphItem
4 | {
5 | internal const string Fb2VParagraphItemName = "v";
6 |
7 | protected override string GetElementName()
8 | {
9 | return Fb2VParagraphItemName;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Elements/SequenceType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Xml.Linq;
5 |
6 | namespace FB2Library.Elements
7 | {
8 | public class SequenceType
9 | {
10 | private const string NameAttributeName = "name";
11 | private const string NumberAttributeName = "number";
12 |
13 | public const string SequenceElementName = "sequence";
14 |
15 | private readonly List _content = new List();
16 |
17 | ///
18 | /// XML namespace used to read the document
19 | ///
20 | public XNamespace Namespace { get; set; } = XNamespace.None;
21 |
22 | ///
23 | /// Get/Set name of the sequence
24 | ///
25 | public string Name { get; set; }
26 |
27 | ///
28 | /// Get/Set sequence number
29 | ///
30 | public int? Number { get; set; }
31 |
32 | ///
33 | /// Get/Set language
34 | ///
35 | public string Language { get; set; }
36 |
37 | public void Load(XElement xElement)
38 | {
39 | if (xElement == null)
40 | {
41 | throw new ArgumentNullException(nameof(xElement));
42 | }
43 | if (xElement.Name.LocalName != SequenceElementName)
44 | {
45 | throw new ArgumentException("Element of wrong type passed", nameof(xElement));
46 | }
47 |
48 | // read all subsequences
49 | _content.Clear();
50 | foreach (var element in xElement.Elements(Namespace + SequenceElementName))
51 | {
52 | var subElement = new SequenceType();
53 | try
54 | {
55 | subElement.Load(element);
56 | _content.Add(subElement);
57 | }
58 | catch (Exception ex)
59 | {
60 | Debug.WriteLine($"Error reading sequence element: {ex.Message}");
61 | }
62 | }
63 |
64 | // read "name" attribute
65 | Name = null;
66 | XAttribute xName = xElement.Attribute(NameAttributeName);
67 | if (xName != null && !string.IsNullOrEmpty(xName.Value))
68 | {
69 | Name = xName.Value;
70 | }
71 | else
72 | {
73 | throw new Exception("Name attribute in sequence is required!");
74 | }
75 |
76 | // read number attribute
77 | Number = null;
78 | XAttribute xNumber = xElement.Attribute(NumberAttributeName);
79 | if (xNumber != null && !string.IsNullOrEmpty(xNumber.Value))
80 | {
81 | if (int.TryParse(xNumber.Value, out var value))
82 | {
83 | Number = value;
84 | }
85 | }
86 |
87 | // read lang attribute
88 | Language = null;
89 | XAttribute xLang = xElement.Attribute(XNamespace.Xml + "lang");
90 | if (xLang != null && string.IsNullOrEmpty(xLang.Value))
91 | {
92 | Language = xLang.Value;
93 | }
94 | }
95 |
96 | public XElement ToXML()
97 | {
98 | XElement xSequence = new XElement(Fb2Const.fb2DefaultNamespace + SequenceElementName);
99 | if (!string.IsNullOrEmpty(Name))
100 | {
101 | xSequence.Add(new XAttribute(NameAttributeName, Name));
102 | }
103 | if (Number != null)
104 | {
105 | xSequence.Add(new XAttribute(NumberAttributeName, Number));
106 | }
107 | if (!string.IsNullOrEmpty(Language))
108 | {
109 | xSequence.Add(new XAttribute(XNamespace.Xml + "lang", Language));
110 | }
111 | foreach (SequenceType subSequence in _content)
112 | {
113 | xSequence.Add(subSequence.ToXML());
114 | }
115 |
116 | return xSequence;
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/Elements/StyleElement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Linq;
6 |
7 | namespace FB2Library.Elements
8 | {
9 | ///
10 | /// Represents FB2 stylesheet element
11 | ///
12 | public class StyleElement
13 | {
14 | public const string StyleElementName = "stylesheet";
15 | ///
16 | /// Get/Set Style Value
17 | ///
18 | public string Value { get; set; }
19 |
20 | ///
21 | /// Get/Set type attribute
22 | ///
23 | public string Type { get; set; }
24 |
25 | ///
26 | /// Load element data from the node
27 | ///
28 | ///
29 | public void Load(XElement xElement)
30 | {
31 | if (xElement == null)
32 | {
33 | throw new ArgumentNullException("xElement");
34 | }
35 | if (xElement.Name.LocalName != StyleElementName)
36 | {
37 | throw new ArgumentException(string.Format("The element is of type {0} while StyleElement accepts only {1} types",xElement.Name.LocalName,StyleElementName));
38 | }
39 |
40 | Value = string.Empty;
41 | if (!string.IsNullOrEmpty(xElement.Value))
42 | {
43 | Value = xElement.Value;
44 | }
45 |
46 | Type = string.Empty;
47 | XAttribute xType = xElement.Attribute("type");
48 | if (xType == null || string.IsNullOrEmpty(xType.Value))
49 | {
50 | throw new Exception("Type attribute is rewuired by standard");
51 | }
52 | Type = xType.Value;
53 | }
54 |
55 | public XElement ToXML()
56 | {
57 | if (Type == null || string.IsNullOrEmpty(Type))
58 | {
59 | throw new Exception("Type attribute is rewuired by standard");
60 | }
61 | XElement xstyle = new XElement(Fb2Const.fb2DefaultNamespace + StyleElementName, new XAttribute("type", Type));
62 | if (!string.IsNullOrEmpty(Value))
63 | {
64 | xstyle.Value = Value;
65 | }
66 | return xstyle;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Elements/SubTitleItem.cs:
--------------------------------------------------------------------------------
1 | namespace FB2Library.Elements
2 | {
3 | public class SubTitleItem : ParagraphItem
4 | {
5 | internal const string Fb2SubtitleElementName = "subtitle";
6 |
7 | protected override string GetElementName()
8 | {
9 | return Fb2SubtitleElementName;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Elements/Table/BaseCellElement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml.Linq;
7 |
8 | //Добавить для атрибута style и ID засунуть вместо текста SimplText;
9 | namespace FB2Library.Elements.Table
10 | {
11 | public enum TableAlignmentsEnum
12 | {
13 | Left,
14 | Right,
15 | Center,
16 | }
17 |
18 | public enum TableVAlignmentsEnum
19 | {
20 | Top,
21 | Middle,
22 | Bottom,
23 | }
24 |
25 | public interface ICellElement
26 | {
27 | TableAlignmentsEnum Align { get; set; }
28 | TableVAlignmentsEnum VAlign { get; set; }
29 | int? ColSpan { get; set; }
30 | int? RowSpan { get; set; }
31 | }
32 |
33 | public class BaseCellElement : ParagraphItem, ICellElement
34 | {
35 | #region ICellElement Members
36 |
37 | private TableAlignmentsEnum align = TableAlignmentsEnum.Left;
38 | private TableVAlignmentsEnum vAlign = TableVAlignmentsEnum.Top;
39 |
40 | protected override string GetElementName()
41 | {
42 | return "";
43 | }
44 |
45 | public TableAlignmentsEnum Align
46 | {
47 | get { return align; }
48 | set { align = value; }
49 | }
50 |
51 | public TableVAlignmentsEnum VAlign
52 | {
53 | get { return vAlign; }
54 | set { vAlign = value; }
55 | }
56 |
57 | public int? ColSpan {get; set; }
58 |
59 | public int? RowSpan { get; set; }
60 |
61 | #endregion
62 |
63 | protected void LoadAlign(XElement xCell)
64 | {
65 | XAttribute xAlign = xCell.Attribute("align");
66 | if ((xAlign != null) && (xAlign.Value != null))
67 | {
68 | switch (xAlign.Value)
69 | {
70 | case "left":
71 | align = TableAlignmentsEnum.Left;
72 | break;
73 | case "right":
74 | align = TableAlignmentsEnum.Right;
75 | break;
76 | case "center":
77 | align = TableAlignmentsEnum.Center;
78 | break;
79 | default:
80 | Debug.WriteLine(string.Format("TableRowItem.Load - Unknown alignment {0}"), xAlign.Value);
81 | break;
82 | }
83 | }
84 | }
85 |
86 | protected void LoadVAlign(XElement xCell)
87 | {
88 | XAttribute xVAlign = xCell.Attribute("valign");
89 | if ((xVAlign != null) && (xVAlign.Value != null))
90 | {
91 | switch (xVAlign.Value)
92 | {
93 | case "top":
94 | vAlign = TableVAlignmentsEnum.Top;
95 | break;
96 | case "middle":
97 | vAlign = TableVAlignmentsEnum.Middle;
98 | break;
99 | case "bottom":
100 | vAlign = TableVAlignmentsEnum.Bottom;
101 | break;
102 | default:
103 | Debug.WriteLine(string.Format("TableRowItem.Load - Unknown alignment {0}"), xVAlign.Value);
104 | break;
105 | }
106 | }
107 | }
108 |
109 | protected string GetAlign()
110 | {
111 | switch (align)
112 | {
113 | case TableAlignmentsEnum.Right:
114 | return "right";
115 | case TableAlignmentsEnum.Center:
116 | return "center";
117 | default:
118 | return "left";
119 | }
120 | }
121 |
122 | protected string GetVAlign()
123 | {
124 | switch (vAlign)
125 | {
126 | case TableVAlignmentsEnum.Middle:
127 | return "middle";
128 | case TableVAlignmentsEnum.Bottom:
129 | return "bottom";
130 | default:
131 | return "top";
132 | }
133 | }
134 |
135 | public new XNode ToXML()
136 | {
137 | //XElement xCell = new XElement(Fb2Const.fb2DefaultNamespace + GetElementName());
138 | XElement xCell = (XElement)base.ToXML();
139 | xCell.Add(new XAttribute("align", GetAlign()));
140 | xCell.Add(new XAttribute("valign", GetVAlign()));
141 | if (ColSpan != null)
142 | {
143 | xCell.Add(new XAttribute("colspan", ColSpan.ToString()));
144 | }
145 | if (RowSpan != null)
146 | {
147 | xCell.Add(new XAttribute("rowspan", RowSpan.ToString()));
148 | }
149 |
150 | return xCell;
151 | }
152 |
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/Elements/Table/TableCellItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Linq;
6 |
7 | namespace FB2Library.Elements.Table
8 | {
9 | public class TableCellItem : BaseCellElement
10 | {
11 | internal const string Fb2TableCellElementName = "td";
12 |
13 | protected override string GetElementName()
14 | {
15 | return Fb2TableCellElementName;
16 | }
17 |
18 | internal new string Fb2ParagraphElementName = Fb2TableCellElementName;
19 |
20 | internal new void Load(XElement xCell)
21 | {
22 | if (xCell == null)
23 | {
24 | throw new ArgumentNullException("xCell");
25 | }
26 |
27 | if (xCell.Name.LocalName != Fb2TableCellElementName)
28 | {
29 | throw new ArgumentException("Element of wrong type passed", "xCell");
30 | }
31 |
32 | LoadData(xCell);
33 |
34 | LoadAlign(xCell);
35 | LoadVAlign(xCell);
36 |
37 | ColSpan = null;
38 | XAttribute xColSpan = xCell.Attribute("colspan");
39 | if ((xColSpan != null) && (xColSpan.Value != null))
40 | {
41 | int res;
42 | if (int.TryParse(xColSpan.Value, out res))
43 | {
44 | ColSpan = res;
45 | }
46 | }
47 |
48 | RowSpan = null;
49 | XAttribute xRowSpan = xCell.Attribute("rowspan");
50 | if ((xRowSpan != null) && (xRowSpan.Value != null))
51 | {
52 | int res;
53 | if (int.TryParse(xRowSpan.Value, out res))
54 | {
55 | RowSpan = res;
56 | }
57 | }
58 |
59 | }
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Elements/Table/TableHeadingItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Linq;
6 |
7 | namespace FB2Library.Elements.Table
8 | {
9 | public class TableHeadingItem : BaseCellElement
10 | {
11 | internal const string Fb2TableHeadingElementName = "th";
12 |
13 | protected override string GetElementName()
14 | {
15 | return Fb2TableHeadingElementName;
16 | }
17 |
18 | internal new void Load(XElement xHeadingCell)
19 | {
20 | if (xHeadingCell == null)
21 | {
22 | throw new ArgumentNullException("xHeadingCell");
23 | }
24 |
25 | if (xHeadingCell.Name.LocalName != Fb2TableHeadingElementName)
26 | {
27 | throw new ArgumentException("Element of wrong type passed", "xHeadingCell");
28 | }
29 |
30 | LoadData(xHeadingCell);
31 |
32 | LoadAlign(xHeadingCell);
33 | LoadVAlign(xHeadingCell);
34 |
35 | ColSpan = null;
36 | XAttribute xColSpan = xHeadingCell.Attribute("colspan");
37 | if ((xColSpan != null)&&(xColSpan.Value != null))
38 | {
39 | int res;
40 | if(int.TryParse(xColSpan.Value,out res))
41 | {
42 | ColSpan = res;
43 | }
44 | }
45 |
46 | RowSpan = null;
47 | XAttribute xRowSpan = xHeadingCell.Attribute("rowspan");
48 | if ((xRowSpan != null) && (xRowSpan.Value != null))
49 | {
50 | int res;
51 | if (int.TryParse(xRowSpan.Value, out res))
52 | {
53 | RowSpan = res;
54 | }
55 | }
56 |
57 | }
58 |
59 |
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Elements/Table/TableItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml.Linq;
7 |
8 | namespace FB2Library.Elements.Table
9 | {
10 | public class TableItem : IFb2TextItem
11 | {
12 | private List rows = new List();
13 |
14 | public string ID { get; set; }
15 | public string Style { get; set; }
16 | public List Rows { get { return rows; } }
17 |
18 |
19 |
20 | internal const string Fb2TableElementName = "table";
21 |
22 | internal void Load(XElement xTable)
23 | {
24 | rows.Clear();
25 | if (xTable == null)
26 | {
27 | throw new ArgumentNullException("xTable");
28 | }
29 |
30 | if (xTable.Name.LocalName != Fb2TableElementName)
31 | {
32 | throw new ArgumentException("Element of wrong type passed", "xTable");
33 | }
34 |
35 | IEnumerable xRows = xTable.Elements(xTable.Name.Namespace + TableRowItem.Fb2TableRowElementName);
36 | foreach (var row in xRows)
37 | {
38 | TableRowItem rowItem = new TableRowItem();
39 | try
40 | {
41 | rowItem.Load(row);
42 | Rows.Add(rowItem);
43 | }
44 | catch (Exception)
45 | {
46 | continue;
47 | }
48 | }
49 |
50 | Style = null;
51 | XAttribute xStyle = xTable.Attribute("style");
52 | if ((xStyle != null) && (xStyle.Value != null))
53 | {
54 | Style = xStyle.Value;
55 | }
56 |
57 | ID = null;
58 | XAttribute xID = xTable.Attribute("id");
59 | if ((xID != null) && (xID.Value != null))
60 | {
61 | ID = xID.Value;
62 | }
63 |
64 |
65 |
66 | }
67 |
68 | public XNode ToXML()
69 | {
70 | XElement xTable = new XElement(Fb2Const.fb2DefaultNamespace + Fb2TableElementName);
71 | if (!string.IsNullOrEmpty(ID))
72 | {
73 | xTable.Add(new XAttribute("id", ID));
74 | }
75 | if (!string.IsNullOrEmpty(Style))
76 | {
77 | xTable.Add(new XAttribute("style", Style));
78 | }
79 | foreach (TableRowItem RowItem in rows)
80 | {
81 | xTable.Add(RowItem.ToXML());
82 | }
83 | return xTable;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Elements/Table/TableRowItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml.Linq;
7 |
8 | namespace FB2Library.Elements.Table
9 | {
10 |
11 | public class TableRowItem
12 | {
13 |
14 | private List cells = new List();
15 |
16 |
17 | public string ID { get; set; }
18 | public List Cells { get { return cells; } }
19 | public string Align { get; set; }
20 | public string Style { get; set; }
21 |
22 |
23 | internal const string Fb2TableRowElementName = "tr";
24 |
25 | internal void Load(XElement xRow)
26 | {
27 | if (xRow == null)
28 | {
29 | throw new ArgumentNullException("xRow");
30 | }
31 |
32 | if (xRow.Name.LocalName != Fb2TableRowElementName)
33 | {
34 | throw new ArgumentException("Element of wrong type passed", "xRow");
35 | }
36 |
37 | IEnumerable xCells = xRow.Elements();
38 | foreach (var cell in xCells)
39 | {
40 | switch (cell.Name.LocalName)
41 | {
42 | case TableHeadingItem.Fb2TableHeadingElementName:
43 | TableHeadingItem heading = new TableHeadingItem();
44 | try
45 | {
46 | heading.Load(cell);
47 | cells.Add(heading);
48 |
49 | }
50 | catch (Exception)
51 | {
52 |
53 | }
54 | break;
55 | case TableCellItem.Fb2TableCellElementName:
56 | TableCellItem tableCell = new TableCellItem();
57 | try
58 | {
59 | tableCell.Load(cell);
60 | cells.Add(tableCell);
61 | }
62 | catch (Exception)
63 | {
64 |
65 | }
66 | break;
67 | default:
68 | Debug.WriteLine(string.Format("TableRowItem.Load - Unknown cell type {0}"), cell.Name.LocalName);
69 | break;
70 | }
71 | }
72 |
73 |
74 | ID = null;
75 | XAttribute xID = xRow.Attribute("id");
76 | if ((xID != null) && (xID.Value != null))
77 | {
78 | ID = xID.Value;
79 | }
80 |
81 |
82 | Style = null;
83 | XAttribute xStyle = xRow.Attribute("style");
84 | if ((xStyle != null) && (xStyle.Value != null))
85 | {
86 | Style = xStyle.Value;
87 | }
88 |
89 | Align = null;
90 | XAttribute xAlign = xRow.Attribute("align");
91 | if ((xAlign != null) && (xAlign.Value != null))
92 | {
93 | Align = xAlign.Value;
94 | }
95 | }
96 |
97 | public XElement ToXML()
98 | {
99 | XElement xRow = new XElement(Fb2Const.fb2DefaultNamespace + Fb2TableRowElementName);
100 | if (!string.IsNullOrEmpty(ID))
101 | {
102 | xRow.Add(new XAttribute("id", ID));
103 | }
104 | if (!string.IsNullOrEmpty(Style))
105 | {
106 | xRow.Add(new XAttribute("style", Style));
107 | }
108 | if (!string.IsNullOrEmpty(Align))
109 | {
110 | xRow.Add(new XAttribute("align", Align));
111 | }
112 | foreach (ICellElement cellItem in cells)
113 | {
114 | xRow.Add(((ParagraphItem)cellItem).ToXML());
115 | }
116 |
117 | return xRow;
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/Elements/TextAuthorItem.cs:
--------------------------------------------------------------------------------
1 | namespace FB2Library.Elements
2 | {
3 | public class TextAuthorItem : ParagraphItem
4 | {
5 | internal const string Fb2TextAuthorElementName = "text-author";
6 |
7 | protected override string GetElementName()
8 | {
9 | return Fb2TextAuthorElementName;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Elements/TextFieldType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library.Elements
5 | {
6 | public class TextFieldType
7 | {
8 | public TextFieldType()
9 | {
10 | Text = string.Empty;
11 | }
12 |
13 | ///
14 | /// Get/Set text value
15 | ///
16 | public string Text { get; set; }
17 |
18 | ///
19 | /// Get/Set language
20 | ///
21 | public string Language { get; set; }
22 |
23 | public override string ToString()
24 | {
25 | return Text;
26 | }
27 |
28 | public virtual void Load(XElement xElement)
29 | {
30 | if (xElement == null)
31 | {
32 | throw new ArgumentNullException(nameof(xElement));
33 | }
34 | Text = string.Empty;
35 | if (!string.IsNullOrEmpty(xElement.Value))
36 | {
37 | Text = xElement.Value;
38 | }
39 |
40 | Language = null;
41 | // TODO: глянуть
42 | XAttribute xLang = xElement.Attribute(XNamespace.Xml + "lang");
43 | if (xLang != null && string.IsNullOrEmpty(xLang.Value))
44 | {
45 | Language = xLang.Value;
46 | }
47 | }
48 |
49 | public virtual XElement ToXML(string nameElement)
50 | {
51 | XElement xText = new XElement(Fb2Const.fb2DefaultNamespace + nameElement, Text);
52 | if (Language != null)
53 | {
54 | xText.Add(new XAttribute(XNamespace.Xml + "lang",Language));
55 | }
56 | return xText;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Elements/TitleItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Text;
5 | using System.Xml.Linq;
6 |
7 | namespace FB2Library.Elements
8 | {
9 | public class TitleItem : IFb2TextItem
10 | {
11 | internal const string Fb2TitleElementName = "title";
12 |
13 | private readonly List _titleData = new List();
14 |
15 | public List TitleData => _titleData;
16 |
17 | ///
18 | /// Language attribute
19 | ///
20 | public string LangAttribute { get; set; }
21 |
22 | public override string ToString()
23 | {
24 | StringBuilder builder = new StringBuilder();
25 | foreach (var textItem in TitleData)
26 | {
27 | builder.Append(textItem.ToString());
28 | builder.Append(" ");
29 | }
30 | return builder.ToString();
31 | }
32 |
33 | internal void Load(XElement xTitle)
34 | {
35 | _titleData.Clear();
36 | if (xTitle == null)
37 | {
38 | throw new ArgumentNullException(nameof(xTitle));
39 | }
40 |
41 | if (xTitle.Name.LocalName != Fb2TitleElementName)
42 | {
43 | throw new ArgumentException("Element of wrong type passed", nameof(xTitle));
44 | }
45 |
46 | IEnumerable subElements = xTitle.Elements();
47 | foreach (var element in subElements)
48 | {
49 | switch (element.Name.LocalName)
50 | {
51 | case EmptyLineItem.Fb2EmptyLineElementName:
52 | _titleData.Add(new EmptyLineItem());
53 | break;
54 | case ParagraphItem.Fb2ParagraphElementName:
55 | ParagraphItem paragraph = new ParagraphItem();
56 | try
57 | {
58 | paragraph.Load(element);
59 | _titleData.Add(paragraph);
60 | }
61 | catch (Exception ex)
62 | {
63 | Debug.WriteLine($"Failed to load paragraph: {ex.Message}.");
64 | }
65 | break;
66 | default:
67 | Debug.WriteLine(
68 | $"TitleItem:Load - invalid element <{element.Name.LocalName}> encountered in title .");
69 | break;
70 | }
71 | }
72 |
73 | LangAttribute = null;
74 | XAttribute xLang = xTitle.Attribute(XNamespace.Xml + "lang");
75 | if (xLang != null && !string.IsNullOrEmpty(xLang.Value))
76 | {
77 | LangAttribute = xLang.Value;
78 | }
79 | }
80 | public XNode ToXML()
81 | {
82 | XElement xTitle = new XElement(Fb2Const.fb2DefaultNamespace + Fb2TitleElementName);
83 | if (!string.IsNullOrEmpty(LangAttribute))
84 | {
85 | xTitle.Add(new XAttribute(XNamespace.Xml + "lang", LangAttribute));
86 | }
87 |
88 | foreach (IFb2TextItem titleItem in _titleData)
89 | {
90 | xTitle.Add(titleItem.ToXML());
91 | }
92 | return xTitle;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/FB2Library.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | netstandard1.0;netstandard2.1;net6.0
6 | False
7 |
8 | FB2Library
9 | 1.3.2
10 | Cross-Platform .NET library for read .FB2 ebook files
11 | This project provides .Net standard library to help developers load .FB2 ebook files. This ebook files format is widely acceptable in Russia. If you doing some converter, reader or editor for ebooks and you using one of the .Net languages - this project for you.
12 | lordkiron, Yauheni Pakala
13 | netstandard;dotnet6;fb2;ebook;windows;uwp;android;ios;linux;macos;xamarin;xamarin.forms;maui
14 | icon.png
15 | https://github.com/wcoder/FB2Library
16 | master
17 | LICENSE.md
18 | README.md
19 | Add more target frameworks
20 | Copyright (c) 2009-2015 lordkiron / 2022 Yauheni Pakala
21 |
22 | true
23 | true
24 | true
25 | snupkg
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/FB2Reader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 | using System.Xml;
5 | using System.Xml.Linq;
6 |
7 | namespace FB2Library
8 | {
9 | ///
10 | /// Simple class for reading Fb2 file.
11 | ///
12 | public class FB2Reader : IFB2Reader
13 | {
14 | ///
15 | /// Read Fb2 file from Stream.
16 | ///
17 | /// Fb2 file as a stream.
18 | /// Settings for reading fb2 file.
19 | ///
20 | public Task ReadAsync(Stream stream, XmlLoadSettings settings)
21 | {
22 | if (settings == null)
23 | throw new ArgumentNullException(nameof(settings));
24 |
25 | return Task.Factory.StartNew(() =>
26 | {
27 | var file = new FB2File();
28 | using (var reader = XmlReader.Create(stream, settings.ReaderSettings))
29 | {
30 | var fb2Document = XDocument.Load(reader, settings.Options);
31 | file.Load(fb2Document, false);
32 | }
33 | return file;
34 | });
35 | }
36 |
37 | ///
38 | /// Read Fb2 file from string.
39 | ///
40 | /// Fb2 file content as a string.
41 | ///
42 | public Task ReadAsync(string xml)
43 | {
44 | return Task.Factory.StartNew(() =>
45 | {
46 | var file = new FB2File();
47 | var fb2Document = XDocument.Parse(xml);
48 | file.Load(fb2Document, false);
49 | return file;
50 | });
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/HeaderItems/CoverPage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Xml.Linq;
4 | using FB2Library.Elements;
5 |
6 | namespace FB2Library.HeaderItems
7 | {
8 | public class CoverPage
9 | {
10 | internal const string Fb2CoverPageImageElementName = "coverpage";
11 |
12 | private readonly List _coverImages = new List();
13 |
14 | private XNamespace _fileNameSpace = XNamespace.None;
15 |
16 | protected string GetElementName()
17 | {
18 | return Fb2CoverPageImageElementName;
19 | }
20 |
21 | public List CoverpageImages => _coverImages;
22 |
23 | public bool HasImages() => _coverImages.Count > 0;
24 |
25 | ///
26 | /// XML namespace used to read the document
27 | ///
28 | public XNamespace Namespace
29 | {
30 | set { _fileNameSpace = value; }
31 | get { return _fileNameSpace; }
32 | }
33 |
34 |
35 | internal void Load(XElement xCoverPage)
36 | {
37 | if (xCoverPage == null)
38 | {
39 | throw new ArgumentNullException(nameof(xCoverPage));
40 | }
41 |
42 | if (xCoverPage.Name.LocalName != GetElementName())
43 | {
44 | throw new ArgumentException("Element of wrong type passed", nameof(xCoverPage));
45 | }
46 |
47 | _coverImages.Clear();
48 | IEnumerable xImages = xCoverPage.Elements(_fileNameSpace +InlineImageItem.Fb2InlineImageElementName);
49 | foreach (var xImage in xImages)
50 | {
51 | InlineImageItem image = new InlineImageItem();
52 | try
53 | {
54 | image.Load(xImage);
55 | _coverImages.Add(image);
56 | }
57 | catch (Exception)
58 | {
59 | // ignore
60 | }
61 | }
62 | }
63 |
64 | public XElement ToXML()
65 | {
66 | XElement xCover = new XElement(Fb2Const.fb2DefaultNamespace + Fb2CoverPageImageElementName);
67 | foreach (InlineImageItem imageItem in _coverImages)
68 | {
69 | xCover.Add(imageItem.ToXML());
70 | }
71 |
72 | return xCover;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/HeaderItems/CustomInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 | using FB2Library.Elements;
4 |
5 | namespace FB2Library.HeaderItems
6 | {
7 | public class ItemCustomInfo : CustomTextFieldType
8 | {
9 | public const string CustomInfoElementName = "custom-info";
10 |
11 | private XNamespace fileNameSpace = XNamespace.None;
12 |
13 | ///
14 | /// XML namespace used to read the document
15 | ///
16 | public XNamespace Namespace
17 | {
18 | set { fileNameSpace = value; }
19 | get { return fileNameSpace; }
20 | }
21 |
22 |
23 | public override void Load(XElement xElement)
24 | {
25 | if (xElement == null)
26 | {
27 | throw new ArgumentNullException("xElement");
28 | }
29 | base.Load(xElement);
30 | }
31 |
32 | public XElement ToXML()
33 | {
34 | XElement xCustomInfo = new XElement(Fb2Const.fb2DefaultNamespace + CustomInfoElementName);
35 | xCustomInfo.Add(new XAttribute("info-type",InfoType));
36 | xCustomInfo.Value = Text;
37 | return xCustomInfo;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/HeaderItems/ItemInfoBase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Xml.Linq;
3 | using FB2Library.Elements;
4 |
5 | namespace FB2Library.HeaderItems
6 | {
7 | public class ItemInfoBase
8 | {
9 | protected readonly List ItemSequences = new List();
10 |
11 | protected XNamespace FileNameSpace = XNamespace.None;
12 |
13 | ///
14 | /// Get list of sequences
15 | ///
16 | public List Sequences => ItemSequences;
17 |
18 | ///
19 | /// XML namespace used to read the document
20 | ///
21 | public XNamespace Namespace
22 | {
23 | set { FileNameSpace = value; }
24 | get { return FileNameSpace; }
25 | }
26 |
27 | ///
28 | /// Book Title
29 | ///
30 | public TextFieldType BookTitle { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/HeaderItems/ItemPublishInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Xml.Linq;
4 | using FB2Library.Elements;
5 |
6 | namespace FB2Library.HeaderItems
7 | {
8 | ///
9 | /// Information about some paper/outher published document, that was used as a source of this xml document
10 | ///
11 | public class ItemPublishInfo : ItemInfoBase
12 | {
13 | private const string BookNameElementName = "book-name";
14 | private const string PublisherElementName = "publisher";
15 | private const string CityElementName = "city";
16 | private const string YearElementName = "year";
17 | private const string ISBNElementName = "isbn";
18 |
19 | public const string PublishInfoElementName = "publish-info";
20 |
21 | ///
22 | /// ISBN of original book
23 | ///
24 | public TextFieldType ISBN { get; set; }
25 |
26 | ///
27 | /// Year of the original (paper) publication
28 | ///
29 | public int? Year { get; set; }
30 |
31 | ///
32 | /// City where the original (paper) book was published
33 | ///
34 | public TextFieldType City { get; set; }
35 |
36 | ///
37 | /// Original (paper) book publisher
38 | ///
39 | public TextFieldType Publisher { get; set; }
40 |
41 | internal void Load(XElement xPublishInfo)
42 | {
43 | if (xPublishInfo == null)
44 | {
45 | throw new ArgumentNullException(nameof(xPublishInfo));
46 | }
47 |
48 | // Load book name
49 | BookTitle = null;
50 | XElement xBookName = xPublishInfo.Element(FileNameSpace + BookNameElementName);
51 | if (xBookName != null)
52 | {
53 | BookTitle = new TextFieldType();
54 | try
55 | {
56 | BookTitle.Load(xBookName);
57 | }
58 | catch (Exception ex)
59 | {
60 | Debug.WriteLine($"Error reading publisher book name : {ex.Message}");
61 | }
62 | }
63 |
64 | // Load publisher
65 | Publisher = null;
66 | XElement xPublisher = xPublishInfo.Element(FileNameSpace + PublisherElementName);
67 | if (xPublisher != null)
68 | {
69 | Publisher = new TextFieldType();
70 | try
71 | {
72 | Publisher.Load(xPublisher);
73 | }
74 | catch (Exception ex)
75 | {
76 | Debug.WriteLine($"Error reading publishers : {ex.Message}");
77 | }
78 | }
79 |
80 | // Load city
81 | City = null;
82 | XElement xCity = xPublishInfo.Element(FileNameSpace + CityElementName);
83 | if (xCity != null)
84 | {
85 | City = new TextFieldType();
86 | try
87 | {
88 | City.Load(xCity);
89 | }
90 | catch (Exception ex)
91 | {
92 | Debug.WriteLine($"Error reading publishers' City: {ex.Message}");
93 | }
94 | }
95 |
96 | // Load year
97 | Year = null;
98 | XElement xYear = xPublishInfo.Element(FileNameSpace + YearElementName);
99 | if (xYear != null)
100 | {
101 | if (int.TryParse( xYear.Value, out var year))
102 | {
103 | Year = year;
104 | }
105 | }
106 |
107 | // Load ISBN
108 | ISBN = null;
109 | XElement xISBN = xPublishInfo.Element(FileNameSpace + ISBNElementName);
110 | if (xISBN != null)
111 | {
112 | ISBN = new TextFieldType();
113 | try
114 | {
115 | ISBN.Load(xISBN);
116 | }
117 | catch (Exception ex)
118 | {
119 | Debug.WriteLine($"Error reading publishers' ISBN: {ex.Message}");
120 | }
121 | }
122 |
123 | // Load sequence here
124 | ItemSequences.Clear();
125 | foreach (var xSequence in xPublishInfo.Elements(FileNameSpace + SequenceType.SequenceElementName))
126 | {
127 | var sec = new SequenceType();
128 | try
129 | {
130 | sec.Load(xSequence);
131 | ItemSequences.Add(sec);
132 | }
133 | catch (Exception ex)
134 | {
135 | Debug.WriteLine($"Error reading publisher sequence data: {ex.Message}");
136 | }
137 | }
138 | }
139 |
140 | public XElement ToXML()
141 | {
142 | var xPublishInfo = new XElement(Fb2Const.fb2DefaultNamespace + PublishInfoElementName);
143 |
144 | if (BookTitle != null)
145 | {
146 | xPublishInfo.Add(BookTitle.ToXML(BookNameElementName));
147 | }
148 | if (Publisher != null)
149 | {
150 | xPublishInfo.Add(Publisher.ToXML(PublisherElementName));
151 | }
152 | if (City != null)
153 | {
154 | xPublishInfo.Add(City.ToXML(CityElementName));
155 | }
156 | if (Year != null)
157 | {
158 | xPublishInfo.Add(new XElement(Fb2Const.fb2DefaultNamespace + YearElementName, Year.ToString()));
159 | }
160 | if (ISBN != null)
161 | {
162 | xPublishInfo.Add(ISBN.ToXML(ISBNElementName));
163 | }
164 | foreach (SequenceType sec in ItemSequences)
165 | {
166 | xPublishInfo.Add(sec.ToXML());
167 | }
168 |
169 | return xPublishInfo;
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/src/IFB2Reader.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Threading.Tasks;
3 |
4 | namespace FB2Library
5 | {
6 | public interface IFB2Reader
7 | {
8 | ///
9 | /// Read Fb2 file from Stream.
10 | ///
11 | /// Fb2 file as a stream.
12 | /// Settings for reading fb2 file.
13 | ///
14 | Task ReadAsync(Stream stream, XmlLoadSettings settings);
15 |
16 | ///
17 | /// Read Fb2 file from string.
18 | ///
19 | /// Fb2 file content as a string.
20 | ///
21 | Task ReadAsync(string xml);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/XmlLoadSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 | using System.Xml.Linq;
3 |
4 | namespace FB2Library
5 | {
6 | public class XmlLoadSettings
7 | {
8 | public XmlReaderSettings ReaderSettings { get; }
9 | public LoadOptions Options { get; }
10 |
11 | public static XmlLoadSettings Default => new XmlLoadSettings(null);
12 |
13 | public XmlLoadSettings(XmlReaderSettings readerSettings, LoadOptions loadOptions = LoadOptions.PreserveWhitespace)
14 | {
15 | ReaderSettings = readerSettings;
16 | Options = loadOptions;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------