1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AiScriptで書いた自作関数類

Posted at

前書き

実際の動作に関して不具合があっても責任は取りません。
動作の確認を行わず関数の編集を行う場合があります。
動作が適当でない場合などは教えていただけると助かります。

自作関数

str

@findURLs(text: str): arr

textからURLを検出し、URLの配列を返す。

@findURLs(text){
  let result = []
  let urlChars = "!#$%&()+,-./0123456789:=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"
  var strBegin = 0
  let strEnd = text.len
  loop {
    let subText = text.slice(strBegin, strEnd)
    let httpIndex = subText.index_of("http://")
    let httpsIndex = subText.index_of("https://")
    let d = if (httpIndex < 0) httpsIndex else if (httpsIndex < 0) httpIndex else Math:min(httpIndex, httpsIndex)
    if (d < 0) break
    let urlBegin = strBegin + d
    var urlEnd = urlBegin
    var urlEndTemp = urlEnd
    var parenthesesCount = 0
    loop {
      let pickChar = text.pick(urlEndTemp)
      if (pickChar == null || !urlChars.incl(pickChar)) break
      if (pickChar == "(") parenthesesCount += 1
      elif (pickChar == ")") parenthesesCount -= 1
      if (parenthesesCount < 0) break
      urlEndTemp += 1
      if (parenthesesCount == 0) urlEnd = urlEndTemp
    }
    result.push(text.slice(urlBegin,urlEnd))
    strBegin = urlEnd
  }
  return result
}

arr

@randomSelect(list :arr, rand: @(min: num, max: num){ num }): value

listからrand関数を用いて無作為に要素を選択し、選択された要素を返す。

@randomSelect(list, rand){
  return list[rand(0, list.len - 1)]
}

@shuffle(list: arr, rand: @(min: num, max: num){ num }): null

listrand関数を用いて無作為にシャッフルする。

@shuffle(list, rand){
  let swap = @(list, i, j){
    let a = list[i]
    list[i] = list[j]
    list[j] = a
  }
  let right = list.len - 1 
  for let left right {swap(list, left, rand(left, right))}
}

非推奨(短くかける代わりに偏りが激しく、出現頻度に2倍程度差が出ることもある。)

@shuffle(list, rand){ list.sort(@(){ rand(0, 1) - 0.5 }) }

@drop(list: arr, index: num): value

listからindex番目の要素を削除し、削除された要素を返す。

@drop(list, index){
  let leng = list.len
  let item = list[index]
  for let i (leng - 1) if (index <= i) list[i] = list[i + 1]
  list.pop()
  return index
}

obj

@obj2yaml(obj: obj): str

objを受け取り、yaml形式の文字列として返す。

@obj2yaml(obj){
  let func = @(obj, nest){
    var yaml = ""
    let nextNest = `{nest}  `
    if (Core:type(obj) == "obj") {
      let keys = Obj:keys(obj)
      each let key keys yaml = `{yaml}\n{nest}{key}: {func(Obj:get(obj key), nextNest)}`
      return yaml
    }
    if (Core:type(obj) == "arr") {
      each let item obj yaml = `{yaml}\n{nest}- {func(item, nextNest)}`
      return yaml
    }
    return `{obj}`
  }
  return func(obj, "")
}

Note

@getNotes(userId: str, limit: num): arr

userIdに応じて、新しいものから最大limit個までのノートの配列を返す。

@getNotes(userId, limit){
  let getNoteFunc = @(limit, params){
    if (params.limit <= 0) return []
    let notes = Mk:api("users/notes" params)
    if (notes.len < params.limit) return notes
    limit -= params.limit
    return notes.concat(getNoteFunc(limit, {userId: userId, limit: Math:min(limit, 100), untilId: notes[notes.len - 1].id}))
  }
  return getNoteFunc(limit, {userId: userId, limit: Math:min(limit, 100)})
}

@countReactions(note: Note): num

noteについたリアクションの数を返す。

@countReactions(note){
  let reactions = note.reactions
  var count = 0
  each let reaction Obj:keys(reactions) count += Obj:get(reactions, reaction)
  return count
}

User

@getUsers(limit: num): arr

古いものからユーザーを最大limit個までのユーザーの配列を返す。

@getUsers(limit){
  let getUserFunc = @(limit, params){
    if (params.limit <= 0) return []
    let users = Mk:api("users" params)
    if (users.len < params.limit) return users
    limit -= params.limit
    return users.concat(getUserFunc(limit, {limit: Math:min(limit, 100), offset: (params.offset+100)}))
  }
  return getUserFunc(limit, {limit: Math:min(limit, 100), offset: 0})
}

Pages

@getPages(limit: num): arr

古いものからユーザーを最大limit個までのユーザーが作ったページのリストを返す。
ただし、1ユーザーが100ページ以上作った場合などに対応していない。

@getPages(limit){
  let users = getUsers(limit)
  var pageList = []
  each let user users pageList = pageList.concat(Mk:api("users/pages" {userId: user.id, limit: 100}))
  return pageList
}

@getPageContentData(pageId: str, contentName: str): str

pageIdで指し示されるページが、ある構造を保つ時、contentNameを用いて、その内容を返す。

@getPageContentData(pageId, contentName){
  let contents = Mk:api("pages/show" {pageId: pageId}).content.filter(@(content){content.title==contentName})
  if ((contents.len < 1) || (contents[0].type != "section")) return null
  let childrens = contents[0].children
  if ((childrens.len < 1) || (childrens[0].type != "text")) return null
  return childrens[0].text
}

@md2page(title: str, name: str, markdown: str): obj

titlenamemarkdownを用いて、ページを作成できるオブジェクトを返す。

@md2page(title,name,markdown){
  let s2f = @(str){
    let markdown = `{Str:lf}{str}{Str:lf}`
    let mdEnd = markdown.len
    let markdownList = []
    let codeBlockList = {}
    var mdStart = 0
    loop {
      let startPoint = markdown.slice(mdStart,mdEnd).index_of(`{Str:lf}\`\`\``) + mdStart
      let endPoint = markdown.slice(startPoint + 1,mdEnd).index_of(`{Str:lf}\`\`\`{Str:lf}`) + startPoint + 1
      if (endPoint <= startPoint) {
        markdownList.push(markdown.slice(mdStart,mdEnd))
        break
      }
      if (mdStart + 1 < startPoint) markdownList.push(markdown.slice(mdStart + 1,startPoint))
      let uuid = Util:uuid()
      markdownList.push(`{Str:lf}{uuid}`)
      codeBlockList[uuid] = markdown.slice(startPoint + 1,endPoint + 4)
      mdStart = endPoint + 4
    }
    let result = `{Str:lf}{markdownList.join("")}`
    return {
      markdown: result.slice(0, result.len - 1)
      codeBlockList: codeBlockList
    }
  }
  let hfn = @(format, splitKey){
    let contentArray = []
    let splittedMarkdown = format.markdown.split(`{Str:lf}{splitKey} `)
    let initContent = splittedMarkdown.shift()
    if (initContent != "") {
      let splittedInitContent = initContent.split(Str:lf)
      splittedInitContent.shift()
      var lines = []
      let lfn = @(lines, contentArray){
        var textBlock = lines.join(Str:lf)
        let uuidKeys = Obj:keys(format.codeBlockList)
        each let key uuidKeys textBlock = textBlock.replace(key format.codeBlockList[key])
        if (lines.len > 0) contentArray.push({type: "text", text: textBlock})        
        return []
      }
      each let line splittedInitContent {
        if (`{Str:lf}{line}`.incl(`{Str:lf}?note `)) {
          lfn(lines,contentArray)
          contentArray.push({type: "note", note: line.replace("?note ", "")})
        }
        else {
          lines.push(line)
        }
      }
      lfn(lines,contentArray)
    }
    let subContents = splittedMarkdown.map(@(pieceOfMarkdown){
      let splittedPieceOfMarkdown = pieceOfMarkdown.split(Str:lf)
      return {
        type: "section"
        title: splittedPieceOfMarkdown.shift()
        children: hfn({markdown: `{Str:lf}{splittedPieceOfMarkdown.join(Str:lf)}`, codeBlockList: format.codeBlockList},`{splitKey}#`)
      }
    })
    return contentArray.concat(subContents)
  }
  return {
    title: title
    name: name
    content: hfn(s2f(markdown),"#")
    variables: []
    script: ""
  }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?