diff --git a/README.md b/README.md index dd5c934..4c0d0bf 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,15 @@ If EPUBCheck is installed locally, it will be run alongside the Go tests. To ins 1. Download and extract EPUBCheck in the root directory of this project, e.g. ``` - wget https://github.com/IDPF/epubcheck/releases/download/v4.2.5/epubcheck-4.2.5.zip - unzip epubcheck-4.2.5.zip + wget https://github.com/IDPF/epubcheck/releases/download/v5.1.0/epubcheck-5.1.0.zip + unzip epubcheck-5.1.0.zip + ``` + + You can use this command to download and extract the latest versions of EPUBCheck (recommended). + + ``` + curl -s https://api.github.com/repos/w3c/epubcheck/releases/latest | awk -F': "' '/browser_download_url/ && /epubcheck/ {gsub(/"$/, "", $2); print $2}' | xargs curl -Lo epubcheck.zip + unzip epubcheck.zip ``` If you do not wish to install EPUBCheck locally, you can manually validate the EPUB: diff --git a/epub.go b/epub.go index 35d4a43..95a3daa 100644 --- a/epub.go +++ b/epub.go @@ -31,6 +31,8 @@ Basic usage: package epub import ( + "bytes" + "encoding/xml" "fmt" "io/fs" "log" @@ -156,9 +158,10 @@ type epubCover struct { } type epubSection struct { - filename string - xhtml *xhtml - children []*epubSection + filename string + xhtml *xhtml + children []*epubSection + properties string } // NewEpub returns a new Epub. @@ -377,9 +380,10 @@ func (e *Epub) addSection(parentFilename string, body string, sectionTitle strin } s := &epubSection{ - filename: internalFilename, - xhtml: x, - children: nil, + filename: internalFilename, + xhtml: x, + children: nil, + properties: propertiesFromBody(body), } // section have parentIndex -1 and subsection have parrentindex != -1 @@ -397,6 +401,40 @@ func (e *Epub) addSection(parentFilename string, body string, sectionTitle strin return internalFilename, nil } +// supports mathml, svg, scripted +// does not support remote-sources, switch (deprecated) +func propertiesFromBody(body string) string { + prop := map[string]bool{} + + decoder := xml.NewDecoder(bytes.NewBufferString(body)) + for { + t, _ := decoder.Token() + if t == nil { + break + } + switch se := t.(type) { + case xml.StartElement: + switch strings.ToUpper(se.Name.Local) { + case "SVG": + prop["svg"] = true + case "MATH": + if se.Name.Space == "http://www.w3.org/1998/Math/MathML" { + prop["mathml"] = true + } + case "SCRIPT", "FORM": + prop["scripted"] = true + } + default: + } + } + + ret := []string{} + for k := range prop { + ret = append(ret, k) + } + return strings.Join(ret, " ") +} + // Author returns the author of the EPUB. func (e *Epub) Author() string { return e.author diff --git a/epub_test.go b/epub_test.go index f2ab888..0f25e85 100644 --- a/epub_test.go +++ b/epub_test.go @@ -1480,3 +1480,56 @@ func TestAddSubSectionWithCustomFilename(t *testing.T) { cleanup(testEpubFilename, tempDir) } + +func TestSectionProperties(t *testing.T) { + e, err := NewEpub(testEpubTitle) + if err != nil { + t.Error(err) + } + + _, err = e.AddSection("