예제 #1
0
def instance(xc, p, args, i=0):
    if len(args[i]) != 1:
        raise XPathContext.FunctionArgType(i + 1, "xbrl:xbrl")
    modelXbrl = xc.modelInstance(anytypeArg(xc, args, i, "xbrli:xbrl"))
    if modelXbrl:
        return modelXbrl
    raise XPathContext.FunctionArgType(i + 1, "xbrl:xbrl")
예제 #2
0
def fact_explicit_dimension_value_value(xc, p, args):
    context = item_context(xc, args)
    if context:
        qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=())
        if qn == (): raise XPathContext.FunctionArgType(2, "xbrl:QName")
        dimConcept = xc.modelXbrl.qnameConcepts.get(
            qn)  # check qname is explicit dimension
        if not dimConcept or not dimConcept.isExplicitDimension:
            raise XPathContext.XPathException(
                p, 'xfie:invalidExplicitDimensionQName',
                _('dimension does not specify an explicit dimension'))
        dimValue = context.dimValue(qn)
        if isinstance(dimValue,
                      ModelObject.ModelDimensionValue) and dimValue.isExplicit:
            return dimValue.memberQname  # known to be valid given instance is valid
        elif isinstance(dimValue, QName):  #default, check if this is valid
            ''' removed 2011-03-01 FWG clarification that default always applies
            modelItem = xc.modelItem(args[0][0])
            itemConcept = modelItem.concept
            from arelle.ValidateXbrlDimensions import checkPriItemDimValueValidity
            memConcept = xc.modelXbrl.qnameConcepts.get(dimValue)
            # remove check for pri item validity per FWG meeting notes 2011-01-13
            if itemConcept: # and checkPriItemDimValueValidity(xc, itemConcept, dimConcept, memConcept):
                return dimValue
            '''
            return dimValue
        return ()  # not an applicable primary item for default dimension
    raise XPathContext.FunctionArgType(1, "xbrl:item")
예제 #3
0
def is_period_type(args, periodElement):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:period")
    period = args[0][0]
    if isinstance(period,xml.dom.Node) and period.nodeType == 1 and \
       period.localName == "period" and period.namespaceURI == XbrlConst.xbrli:
        return XmlUtil.hasChild(period, XbrlConst.xbrli, periodElement)
    raise XPathContext.FunctionArgType(1, "xbrl:period")
예제 #4
0
def measure_name(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:measure")
    unit = args[0][0]
    if isinstance(unit,xml.dom.Node) and unit.nodeType == 1 and \
       unit.localName == "measure" and unit.namespaceURI == XbrlConst.xbrli:
        return qname(unit, XmlUtil.text(unit))
    raise XPathContext.FunctionArgType(1, "xbrl:unit")
예제 #5
0
def item(xc, args, i=0):
    if len(args[i]) != 1:
        raise XPathContext.FunctionArgType(i + 1, "xbrl:item")
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:item")
    modelItem = xc.modelItem(args[i][0])
    if modelItem:
        return modelItem
    raise XPathContext.FunctionArgType(i + 1, "xbrl:item")
예제 #6
0
def unit(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:item")
    modelItem = xc.modelItem(args[0][0])
    if modelItem:
        modelConcept = modelItem.concept
        if modelConcept.isNumeric and not modelConcept.isFraction:
            return modelItem.unit
        return []
    raise XPathContext.FunctionArgType(1, "xbrl:item")
예제 #7
0
def unit_denominator(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:unit")
    unit = args[0][0]
    if isinstance(unit, ModelObject.ModelObject): unit = unit.element
    if isinstance(unit,xml.dom.Node) and unit.nodeType == 1 and \
       unit.localName == "unit" and unit.namespaceURI == XbrlConst.xbrli:
        measuresParent = XmlUtil.descendant(unit, XbrlConst.xbrli,
                                            "unitDenominator")
        if measuresParent is None: return []
        return XmlUtil.descendants(measuresParent, XbrlConst.xbrli, "measure")
    raise XPathContext.FunctionArgType(1, "xbrl:unit")
예제 #8
0
def fact_typed_dimension_value(xc, p, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    context = item_context(xc, args)
    if context:
        qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=())
        if qn == (): raise XPathContext.FunctionArgType(2, "xbrl:QName")
        modelConcept = xc.modelXbrl.qnameConcepts.get(
            qn)  # check qname is explicit dimension
        if not modelConcept or not modelConcept.isTypedDimension:
            raise XPathContext.XPathException(
                p, 'xfie:invalidTypedDimensionQName',
                _('dimension does not specify a typed dimension'))
        result = context.dimValue(qn)
        return result.typedMember if result else ()
    raise XPathContext.FunctionArgType(1, "xbrl:item")
예제 #9
0
def seconds_from_duration(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    d = anytypeArg(xc, args, 0, 'duration', missingArgFallback=())
    if d == (): return d
    if isinstance(d, DayTimeDuration): return 0
    if isinstance(d, YearMonthDuration): return d.dayHrsMinsSecs[2]
    raise XPathContext.FunctionArgType(1,"xs:duration")    
예제 #10
0
def fn_sum(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    addends = xc.atomize(p, args[0])
    try:
        if len(addends) == 0:
            return 0  # xpath allows empty sequence argument
        hasFloat = False
        hasDecimal = False
        for a in addends:
            if math.isnan(a):
                return NaN
            if isinstance(a, float):
                hasFloat = True
            elif isinstance(a, Decimal):
                hasDecimal = True
        if hasFloat and hasDecimal:  # promote decimals to float
            addends = [
                float(a) if isinstance(a, Decimal) else a for a in addends
            ]
        return sum(addends)
    except TypeError:
        raise XPathContext.FunctionArgType(1,
                                           "summable sequence",
                                           addends,
                                           errCode='err:FORG0001')
예제 #11
0
def dateyearmonthcjk(arg):
    m = yearmonthcjkPattern.match(jpDigitsToNormal(arg))
    if m and m.lastindex == 2:
        _mo = z2(m.group(2))
        if "01" <= _mo <= "12":
            return "{0}-{1}".format(yr(m.group(1)), _mo)
    raise XPathContext.FunctionArgType(1, "xs:date")
예제 #12
0
def datemonthdayShortEnTR1(arg):
    m = monthdayShortEnTR1Pattern.match(arg)
    if m and m.lastindex == 2:
        _mo = monthnumber[m.group(1)]
        _day = z2(m.group(2))
        return "--{0:02}-{1}".format(_mo, _day)
    raise XPathContext.FunctionArgType(1, "xs:gMonthDay")
예제 #13
0
def datedaymonthyear(arg):
    m = daymonthyearPattern.match(arg)
    if m and m.lastindex == 3 and checkDate(yr(m.group(3)), m.group(2),
                                            m.group(1)):
        return "{0}-{1}-{2}".format(yr(m.group(3)), z2(m.group(2)),
                                    z2(m.group(1)))
    raise XPathContext.FunctionArgType(1, "xs:date")
예제 #14
0
def numcommadecimal(arg):
    if numCommaDecimalPattern.match(arg):
        return arg.replace('.',
                           '').replace(',',
                                       '.').replace(' ',
                                                    '').replace('\u00A0', '')
    raise XPathContext.FunctionArgType(1, "ixt:nonNegativeDecimalType")
예제 #15
0
def datemonthdaySlashTR1(arg):
    m = monthdayslashPattern.match(arg)
    if m and m.lastindex == 2:
        mo = z2(m.group(1))
        day = z2(m.group(2))
        return "--{0}-{1}".format(mo, day)
    raise XPathContext.FunctionArgType(1, "xs:gMonthDay")
예제 #16
0
def numunitdecimalin(arg):
    m = numUnitDecimalInPattern.match(arg)
    if m:
        m2 = [g for g in m.groups() if g is not None]
        return m2[0].replace(',', '').replace(' ', '').replace(
            '\xa0', '') + '.' + z2(m2[-2])
    raise XPathContext.FunctionArgType(1, "ixt:numunitdecimalinType")
예제 #17
0
def xfxc_element(xc, p, contextItem, args):
    if not 2 <= len(args) <= 4: raise XPathContext.FunctionNumArgs()
    qn = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None)
    attrArg = args[1] if isinstance(args[1], (list, tuple)) else (args[1], )
    # attributes have to be pairs
    if attrArg:
        if len(attrArg) & 1 or any(
                not isinstance(attrArg[i], (QName, _STR_BASE))
                for i in range(0, len(attrArg), 2)):
            raise XPathContext.FunctionArgType(
                1,
                "((xs:qname|xs:string),xs:anyAtomicValue)",
                errCode="xfxce:AttributesNotNameValuePairs")
        else:
            attrParam = [
                (attrArg[i], attrArg[i + 1]
                 )  # need name-value pairs for XmlUtil function
                for i in range(0, len(attrArg), 2)
            ]
    else:
        attrParam = None

    value = atomicArg(xc, p, args, 2, "xs:anyAtomicType", emptyFallback='')
    if not value:  # be sure '' is None so no text node is created
        value = None
    if len(args) < 4:
        childElements = None
    else:
        childElements = xc.flattenSequence(args[3])

    # scratchpad instance document emulates fn:doc( ) to hold XML nodes
    scratchpadXmlDocUrl = "http://www.xbrl.org/2012/function/creation/xml_scratchpad.xml"
    if scratchpadXmlDocUrl in xc.modelXbrl.urlDocs:
        modelDocument = xc.modelXbrl.urlDocs[scratchpadXmlDocUrl]
    else:
        # create scratchpad xml document
        # this will get the fake instance document in the list of modelXbrl docs so that it is garbage collected
        from arelle import ModelDocument
        modelDocument = ModelDocument.create(
            xc.modelXbrl,
            ModelDocument.Type.UnknownXML,
            scratchpadXmlDocUrl,
            initialXml=
            "<xfc:dummy xmlns:xfc='http://www.xbrl.org/2012/function/creation'/>"
        )

    newElement = XmlUtil.addChild(modelDocument.xmlRootElement,
                                  qn,
                                  attributes=attrParam,
                                  text=value)
    if childElements:
        for element in childElements:
            if isinstance(element, etree.ElementBase):
                newElement.append(element)

    # node myst be validated for use in instance creation (typed dimension references)
    XmlValidate.validate(xc.modelXbrl, newElement)

    return newElement
예제 #18
0
def dateerayearmonthjp(arg):
    m = erayearmonthjpPattern.match(jpDigitsToNormal(arg))
    if m and m.lastindex == 3:
        _yr = eraYear(m.group(1), m.group(2))
        _mo = z2(m.group(3))
        if "01" <= _mo <= "12":
            return "{0}-{1}".format(_yr, _mo)
    raise XPathContext.FunctionArgType(1, "xs:gYearMonth")
예제 #19
0
def datemonthyearin(arg):
    m = monthyearInPattern.match(arg)
    try:
        return "{0}-{1}".format(yr(devanagariDigitsToNormal(m.group(2))),
                                gregorianHindiMonthNumber[m.group(1)])
    except (AttributeError, IndexError, KeyError):
        pass
    raise XPathContext.FunctionArgType(1, "xs:gYearMonth")
예제 #20
0
def period_datetime(p, args, periodElement, addOneDay):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:period")
    period = args[0][0]
    if (isinstance(period, xml.dom.Node) and period.nodeType == 1
            and period.localName == "period"
            and period.namespaceURI == XbrlConst.xbrli):
        child = XmlUtil.child(period, XbrlConst.xbrli, periodElement)
        if child:
            return dateTime(child, addOneDay=addOneDay, type=DATETIME)
        elif periodElement == "instant":
            raise XPathContext.XPathException(p, 'xfie:PeriodIsNotInstant',
                                              _('Period is not instant'))
        else:
            raise XPathContext.XPathException(p, 'xfie:PeriodIsForever',
                                              _('Period is forever'))
    raise XPathContext.FunctionArgType(1, "xbrl:period")
예제 #21
0
def datemonthyear(arg):
    m = monthyearPattern.match(
        arg)  # "(M)M*(Y)Y(YY)", with non-numeric separator,
    if m and m.lastindex == 2:
        _mo = z2(m.group(1))
        if "01" <= _mo <= "12":
            return "{0}-{1:2}".format(yr(m.group(2)), _mo)
    raise XPathContext.FunctionArgType(1, "xs:gYearMonth")
예제 #22
0
def element_name(xc, p, args, elementParent=False):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    modelRel = anytypeArg(xc, args, 0, "arelle:ModelRelationship", None)
    if not modelRel:
        raise XPathContext.FunctionArgType(1, "arelle:modelRelationship")
    element = modelRel.element
    if elementParent: element = element.parentNode
    return qname(element)
예제 #23
0
def datemonthdayen(arg):
    m = monthdayEnPattern.match(arg)
    if m and m.lastindex == 2:
        _mo = monthnumber[m.group(1)]
        _day = z2(m.group(2))
        if "01" <= _day <= maxDayInMo.get(_mo, "00"):
            return "--{0:02}-{1}".format(_mo, _day)
    raise XPathContext.FunctionArgType(1, "xs:gMonthDay")
예제 #24
0
def datemonthday(arg):
    m = monthdayPattern.match(arg)
    if m and m.lastindex == 2:
        mo = z2(m.group(1))
        day = z2(m.group(2))
        if "01" <= day <= maxDayInMo.get(mo, "00"):
            return "--{0}-{1}".format(mo, day)
    raise XPathContext.FunctionArgType(1, "xs:gMonthDay")
예제 #25
0
def call(xc, p, localname, args):
    try:
        if localname not in ixtFunctions: raise ixtFunctionNotAvailable
        if len(args) != 1: raise XPathContext.FunctionNumArgs()
        if len(args[0]) != 1: raise XPathContext.FunctionArgType(1,"xs:string")
        return ixtFunctions[localname](str(args[0][0]))
    except ixtFunctionNotAvailable:
        raise XPathContext.FunctionNotAvailable("xfi:{0}".format(localname))
예제 #26
0
def call(xc, p, qn, args):
    try:
        _ixtFunction = ixtNamespaceFunctions[qn.namespaceURI][qn.localName]
    except KeyError:
        raise XPathContext.FunctionNotAvailable(str(qn))
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xs:string")
    return _ixtFunction(str(args[0][0]))
예제 #27
0
def parent_child(args, parentName, descendantName):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1:
        raise XPathContext.FunctionArgType(1, "xbrl:" + parentName)
    parent = args[0][0]
    if isinstance(parent, ModelObject.ModelObject): parent = parent.element
    if isinstance(parent,xml.dom.Node) and parent.nodeType == 1 and \
       parent.localName == parentName and parent.namespaceURI == XbrlConst.xbrli:
        if descendantName.startswith('@'):
            return parent.getAttribute(descendantName[1:])
        elif descendantName == 'text()':
            return XmlUtil.text(parent)
        elif descendantName == 'strip-text()':
            return XmlUtil.text(parent).strip()
        else:
            return XmlUtil.child(parent, XbrlConst.xbrli, descendantName)
    raise XPathContext.FunctionArgType(1, "xbrl:" + parentName)
예제 #28
0
def numunitdecimal(arg):
    # remove comma (normal), full-width comma, and stops (periods)
    m = numUnitDecimalPattern.match(jpDigitsToNormal(arg))
    if m and m.lastindex > 1:
        return m.group(1).replace('.', '').replace(',', '').replace(
            '\uFF0C', '').replace('\uFF0E', '') + '.' + z2(m.group(
                m.lastindex))
    raise XPathContext.FunctionArgType(1, "ixt:nonNegativeDecimalType")
예제 #29
0
def datemonthdayyearen(arg):
    m = monthdayyearEnPattern.match(arg)
    if m and m.lastindex == 3:
        _yr = yr(m.group(3))
        _mo = monthnumber[m.group(1)]
        _day = z2(m.group(2))
        if checkDate(_yr, _mo, _day):
            return "{0}-{1:02}-{2}".format(_yr, _mo, _day)
    raise XPathContext.FunctionArgType(1, "xs:date")
예제 #30
0
def dateyearmonthdaycjk(arg):
    m = yearmonthdaycjkPattern.match(jpDigitsToNormal(arg))
    if m and m.lastindex == 3:
        _yr = yr(m.group(1))
        _mo = z2(m.group(2))
        _day = z2(m.group(3))
        if checkDate(_yr, _mo, _day):
            return "{0}-{1}-{2}".format(_yr, _mo, _day)
    raise XPathContext.FunctionArgType(1, "xs:date")