import is from "is" ; import Immutable from "immutable" ; import error from "../utils/error" ; import LocationUtils from "../utils/location" ; import File from "./file" ; import SummaryPart from "./summaryPart" ; import SummaryArticle from "./summaryArticle" ; import parsers from "../parsers" ; type Parts = Immutable . List < any > ; class Summary extends Immutable . Record ( { file : new File ( ) , parts : Immutable . List ( ) , } , "Summary" ) { getFile ( ) { return this . get ( "file" ) ; } getParts ( ) { return this . get ( "parts" ) ; } /**
     Return a part by its index
     */ getPart ( i ) { const parts = this . getParts ( ) ; return parts . get ( i ) ; } param { Function } iter param { Function } partIter return { Article | Part } getArticle ( iter , partIter ? ) { const parts = this . getParts ( ) ; return parts . reduce ( ( result , part ) => { if ( result ) return result ; if ( partIter && partIter ( part ) ) return part ; return SummaryArticle . findArticle ( part , iter ) ; } , null ) ; } param { string } level return { Article | Part } getByLevel ( level ) { function iterByLevel ( article ) { return article . getLevel ( ) === level ; } return this . getArticle ( iterByLevel , iterByLevel ) ; } param { string } filePath return { Article } getByPath ( filePath ) { return this . getArticle ( ( article ) => { const articlePath = article . getPath ( ) ; return articlePath && LocationUtils . areIdenticalPaths ( articlePath , filePath ) ; } ) ; } return { Article } getFirstArticle ( ) { return this . getArticle ( ( article ) => { return true ; } ) ; } /**
     Return next article of an article

     */ getNextArticle ( current ) { const level = typeof current === "string" ? current : current . getLevel ( ) ; let wasPrev = false ; return this . getArticle ( ( article ) => { if ( wasPrev && ! article . hasAnchor ( ) ) { return true ; } if ( ! wasPrev ) { wasPrev = article . getLevel ( ) === level ; } return false ; } ) ; } param { Article } current return { Article } getPrevArticle ( current ) { const level = is . string ( current ) ? current : current . getLevel ( ) ; let prev = undefined ; this . getArticle ( ( article ) => { if ( article . getLevel ( ) == level ) { return true ; } if ( ! article . hasAnchor ( ) ) { prev = article ; } return false ; } ) ; return prev ; } param { String | Article } current return { Article | Part | Null } getParent ( level ) { level = is . string ( level ) ? level : level . getLevel ( ) ; const parentLevel = getParentLevel ( level ) ; if ( ! parentLevel ) { return null ; } const parentArticle = this . getByLevel ( parentLevel ) ; return parentArticle || null ; } param { string } parseExt return { Promise < String > } toText ( parseExt ) { const file = this . getFile ( ) ; const parts = this . getParts ( ) ; const parser = parseExt ? parsers . getByExt ( parseExt ) : file . getParser ( ) ; if ( ! parser ) { throw error . FileNotParsableError ( { filename : file . getPath ( ) , } ) ; } return parser . renderSummary ( { parts : parts . toJS ( ) , } ) ; } return { List < Article > } getArticlesAsList ( ) { const accu = [ ] ; this . getArticle ( ( article ) => { accu . push ( article ) ; } ) ; return Immutable . List ( accu ) ; } param { Lust | Array } parts return { Summary } static createFromParts ( file , parts ) { parts = parts . map ( ( part , i ) => { if ( part instanceof SummaryPart ) { return part ; } return SummaryPart . create ( part , i + 1 ) ; } ) ; return new Summary ( { file : file , parts : new Immutable . List ( parts ) , } ) ; } } param { string } level return { string } function getParentLevel ( level ) { const parts = level . split ( "." ) ; return parts . slice ( 0 , - 1 ) . join ( "." ) ; } export default Summary ;