import type { AttributeToken , TagToken , Token } from 'pug-lexer' ; import { findIndexFrom } from './index' ; param tokens param index returns export function previousTagToken ( tokens , index ) { for ( let i = index - 1 ; i >= 0 ; i -- ) { const token = tokens [ i ] ; if ( ! token ) { return ; } if ( token . type === 'tag' ) { return token ; } } return ; } param tokens param index returns export function previousNormalAttributeToken ( tokens , index ) { for ( let i = index - 1 ; i > 0 ; i -- ) { const token = tokens [ i ] ; if ( ! token || token . type === 'start-attributes' ) { return ; } if ( token . type === 'attribute' ) { if ( token . name !== 'class' && token . name !== 'id' ) { return token ; } } } return ; } param tokens param index returns export function previousTypeAttributeToken ( tokens , index ) { for ( let i = index - 1 ; i > 0 ; i -- ) { const token = tokens [ i ] ; if ( ! token || token . type === 'start-attributes' || token . type === 'tag' ) { return ; } if ( token . type === 'attribute' ) { if ( token . name === 'type' ) { return token ; } } } return ; } export function getAttributeTokens ( tag , tokens ) { const tagIndex = tokens . indexOf ( tag ) ; const startAttributesIndex = findIndexFrom ( tokens , ( { type } ) => type === 'start-attributes' , tagIndex ) ; if ( startAttributesIndex === - 1 || tokens . slice ( tagIndex + 1 , startAttributesIndex ) . some ( ( { type } ) => type === 'tag' ) ) { return [ ] ; } const endAttributesIndex = findIndexFrom ( tokens , ( { type } ) => type === 'end-attributes' , startAttributesIndex ) ; return tokens . slice ( startAttributesIndex + 1 , endAttributesIndex ) as AttributeToken [ ] ; } export function hasAttributeTokens ( tag , tokens , condition ) { return getAttributeTokens ( tag , tokens ) . some ( ( attributeToken ) => condition ( attributeToken ) ) ; } export function getChildTags ( tag , tokens ) { const tagIndex = tokens . indexOf ( tag ) ; const children = [ ] ; let indentLevel = 0 ; for ( let index = tagIndex + 1 ; index < tokens . length ; index ++ ) { const token = tokens [ index ] ! ; if ( token . type === 'tag' ) { children . push ( token ) ; } if ( token . type === 'indent' ) { indentLevel ++ ; } else if ( token . type === 'outdent' ) { indentLevel -- ; if ( indentLevel <= 0 ) { break ; } } } return children ; } param name param val returns export function isStyleAttribute ( name , val ) { return name === 'style' && isQuoted ( val ) ; } param val param start param end param offset returns export function isWrappedWith ( val , start , end , offset = 0 ) { return val . startsWith ( start , offset ) && val . endsWith ( end , val . length - offset ) ; } param val returns export function isQuoted ( val ) { if ( /^(["'`])(.*)\1$/ . test ( val ) ) { const regex = new RegExp ( `${ val [ 0 ] }(?<!\\\\${ val [ 0 ] })` ) ; return ! regex . test ( val . slice ( 1 , - 1 ) ) ; } return false ; } param val returns export function isSingleLineWithInterpolation ( val ) { return /^`[\s\S]*`$/ . test ( val ) && val . includes ( '${' ) ; } param val returns export function isMultilineInterpolation ( val ) { return /^`[\s\S]*`$/m . test ( val ) && val . includes ( '\n' ) ; }