// http://stackoverflow.com/questions/14480345/how-to-get-the-nth-occurrence-in-a-string functiongetPosition(str, m, i) { return str.split(m, i).join(m).length; }
var version = String(hexo.version).split('.'); hexo.extend.filter.register('after_post_render', function(data){ var config = hexo.config; if(config.post_asset_folder){ var link = data.permalink; if(version.length > 0 && Number(version[0]) == 3) var beginPos = getPosition(link, '/', 1) + 1; else var beginPos = getPosition(link, '/', 3) + 1; // In hexo 3.1.1, the permalink of "about" page is like ".../about/index.html". var endPos = link.lastIndexOf('/') + 1; link = link.substring(beginPos, endPos);
var toprocess = ['excerpt', 'more', 'content']; for(var i = 0; i < toprocess.length; i++){ var key = toprocess[i]; var $ = cheerio.load(data[key], { ignoreWhitespace: false, xmlMode: false, lowerCaseTags: false, decodeEntities: false });
$('img').each(function(){ if ($(this).attr('src')){ // For windows style path, we replace '\' to '/'. var src = $(this).attr('src').replace('\\', '/'); if(!/http[s]*.*|\/\/.*/.test(src) && !/^\s*\//.test(src)) { // For "about" page, the first part of "src" can't be removed. // In addition, to support multi-level local directory. var linkArray = link.split('/').filter(function(elem){ return elem != ''; }); var srcArray = src.split('/').filter(function(elem){ return elem != '' && elem != '.'; }); if(srcArray.length > 1) srcArray.shift(); src = srcArray.join('/'); $(this).attr('src', config.root + link + src); console.info&&console.info("update link as:-->"+config.root + link + src); } }else{ console.info&&console.info("no src attr, skipped..."); console.info&&console.info($(this)); } }); data[key] = $.html(); } } });
出现的界面中有两个文件,同时选中,就会在窗口右侧出现Edit and Continue按钮,此时点击这个按钮,就会出现一个界面,这个界面是上面是音频,下面是音素时间戳,每个音素时间戳占用1格(格子有大有小,跟duration有关),我们点击这个格子,就能提到这段格子所对应的音频,假设这个格子上标注的是 ang,但听到的声音明显不仅仅包含ang,比如杨 i ang2,如果我们听到了 i的声音,那么我们就可以证明,这个音素时间戳太靠前了。
/** * Checks to see if any functions are bound to this multi-cast delegate * * @return True if any functions are bound */ inlinebool IsBound() const { UE_DELEGATES_MT_SCOPED_READ_ACCESS(AccessDetector);
return InvocationList.Num() > 0; }
/** * Checks whether a function delegate is already a member of this multi-cast delegate's invocation list * * @param InDelegate Delegate to check * @return True if the delegate is already in the list. */ boolContains( const TScriptDelegate<TWeakPtr>& InDelegate )const { UE_DELEGATES_MT_SCOPED_READ_ACCESS(AccessDetector);
return InvocationList.Contains( InDelegate ); }
/** * Checks whether a function delegate is already a member of this multi-cast delegate's invocation list * * @param InObject Object of the delegate to check * @param InFunctionName Function name of the delegate to check * @return True if the delegate is already in the list. */ boolContains( const UObject* InObject, FName InFunctionName )const { UE_DELEGATES_MT_SCOPED_READ_ACCESS(AccessDetector);
/** * Adds a function delegate to this multi-cast delegate's invocation list * * @param InDelegate Delegate to add */ voidAdd( const TScriptDelegate<TWeakPtr>& InDelegate ) { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
// First check for any objects that may have expired CompactInvocationList();
// Add the delegate AddInternal( InDelegate ); }
/** * Adds a function delegate to this multi-cast delegate's invocation list if a delegate with the same signature * doesn't already exist in the invocation list * * @param InDelegate Delegate to add */ voidAddUnique( const TScriptDelegate<TWeakPtr>& InDelegate ) { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
// Add the delegate, if possible AddUniqueInternal( InDelegate );
// Then check for any objects that may have expired CompactInvocationList(); }
/** * Removes a function from this multi-cast delegate's invocation list (performance is O(N)). Note that the * order of the delegates may not be preserved! * * @param InDelegate Delegate to remove */ voidRemove( const TScriptDelegate<TWeakPtr>& InDelegate ) { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
// Remove the delegate RemoveInternal( InDelegate );
// Check for any delegates that may have expired CompactInvocationList(); }
/** * Removes a function from this multi-cast delegate's invocation list (performance is O(N)). Note that the * order of the delegates may not be preserved! * * @param InObject Object of the delegate to remove * @param InFunctionName Function name of the delegate to remove */ voidRemove( const UObject* InObject, FName InFunctionName ) { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
// Remove the delegate RemoveInternal( InObject, InFunctionName );
// Check for any delegates that may have expired CompactInvocationList(); }
/** * Removes all delegate bindings from this multicast delegate's * invocation list that are bound to the specified object. * * This method also compacts the invocation list. * * @param InObject The object to remove bindings for. */ voidRemoveAll(const UObject* Object) { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
if (Binding.IsBoundToObject(Object) || Binding.IsCompactable()) { InvocationList.RemoveAtSwap(BindingIndex); } } }
/** * Removes all functions from this delegate's invocation list */ voidClear() { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
InvocationList.Empty(); }
/** * Converts this delegate to a string representation * * @return Delegate in string format */ template <typename UObjectTemplate> inline FString ToString()const { UE_DELEGATES_MT_SCOPED_READ_ACCESS(AccessDetector);
if (UnderlyingArchive.IsSaving()) { // When saving the delegate, clean up the list to make sure there are no bad object references D.CompactInvocationList(); }
Slot << D.InvocationList;
if (UnderlyingArchive.IsLoading()) { // After loading the delegate, clean up the list to make sure there are no bad object references D.CompactInvocationList(); } }
/** * Executes a multi-cast delegate by calling all functions on objects bound to the delegate. Always * safe to call, even if when no objects are bound, or if objects have expired. In general, you should * never call this function directly. Instead, call Broadcast() on a derived class. * * @param Params Parameter structure */ template <classUObjectTemplate> voidProcessMulticastDelegate(void* Parameters) const { UE_DELEGATES_MT_SCOPED_WRITE_ACCESS(AccessDetector);
if( InvocationList.Num() > 0 ) { // Create a copy of the invocation list, just in case the list is modified by one of the callbacks during the broadcast typedef TArray< TScriptDelegate<TWeakPtr>, TInlineAllocator< 4 > > FInlineInvocationList; FInlineInvocationList InvocationListCopy = FInlineInvocationList(InvocationList); // Invoke each bound function for( typename FInlineInvocationList::TConstIterator FunctionIt( InvocationListCopy ); FunctionIt; ++FunctionIt ) { if( FunctionIt->IsBound() ) { // Invoke this delegate! FunctionIt->template ProcessDelegate<UObjectTemplate>(Parameters); } elseif ( FunctionIt->IsCompactable() ) { // Function couldn't be executed, so remove it. Note that because the original list could have been modified by one of the callbacks, we have to search for the function to remove here. RemoveInternal( *FunctionIt ); } } } }
classFTestDelegate:public TBaseDynamicMulticastDelegate<FWeakObjectPtr, __VA_ARGS__> \ { \ public: \ /** Default constructor */ \ FTestDelegate() \ { \ } \ \ /** Construction from an FMulticastScriptDelegate must be explicit. This is really only used by UObject system internals. */ \ explicit FTestDelegate( const TMulticastScriptDelegate<>& InMulticastScriptDelegate ) \ : TBaseDynamicMulticastDelegate<TWeakPtr, __VA_ARGS__>( InMulticastScriptDelegate ) \ { \ } \ \ /** Broadcasts this delegate to all bound objects, except to those that may have expired */ \ void Broadcast( FuncParamList ) const \ { \ FTestDelegate_DelegateWrapper( FUNC_CONCAT( *this ) ); \ } \ };
classFTestDelegate:public TBaseDynamicMulticastDelegate<FWeakObjectPtr, *this> \ { \ public: \ /** Default constructor */ \ FTestDelegate() \ { \ } \ \ /** Construction from an FMulticastScriptDelegate must be explicit. This is really only used by UObject system internals. */ \ explicit FTestDelegate( const TMulticastScriptDelegate<>& InMulticastScriptDelegate ) \ : TBaseDynamicMulticastDelegate<TWeakPtr, __VA_ARGS__>( InMulticastScriptDelegate ) \ { \ } \ \ /** Broadcasts this delegate to all bound objects, except to those that may have expired */ \ void Broadcast( ) const \ { \ FTestDelegate_DelegateWrapper( *this ); \ } \ };