def parseargs(request, args, defpagename, defyear, defmonth, defoffset, defoffset2, defheight6, defanniversary, deftemplate):
    """ parse macro arguments """
    args = wikiutil.parse_quoted_separated(args, name_value=False)
    args += [None] * 8 # fill up with None to trigger defaults
    parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, parmanniversary, parmtemplate = args[:8]
    parmpagename = wikiutil.get_unicode(request, parmpagename, 'pagename', defpagename)
    parmyear = wikiutil.get_int(request, parmyear, 'year', defyear)
    parmmonth = wikiutil.get_int(request, parmmonth, 'month', defmonth)
    parmoffset = wikiutil.get_int(request, parmoffset, 'offset', defoffset)
    parmoffset2 = wikiutil.get_int(request, parmoffset2, 'offset2', defoffset2)
    parmheight6 = wikiutil.get_bool(request, parmheight6, 'height6', defheight6)
    parmanniversary = wikiutil.get_bool(request, parmanniversary, 'anniversary', defanniversary)
    parmtemplate = wikiutil.get_unicode(request, parmtemplate, 'template', deftemplate)

    # multiple pagenames separated by "*" - split into list of pagenames
    parmpagename = re.split(r'\*', parmpagename)

    return parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, parmanniversary, parmtemplate
Example #2
0
 def testLimited(self):
     tests = [
               # regular and quoting tests
               (u'd = 4,c=3,b=2,a= 1 ',    ([], {u'd': u'4',
                                                 u'c': u'3,b=2,a= 1'}, [])),
               (u'a,b,c,d',                ([u'a', u'b,c,d'], {}, [])),
               (u'a=b,b,c,d',              ([], {u'a': u'b'}, [u'b,c,d'])),
             ]
     for args, expected in tests:
         result = wikiutil.parse_quoted_separated(args, seplimit=1)
         assert expected == result
         for val in result[0]:
             assert val is None or isinstance(val, unicode)
         for val in result[1].keys():
             assert val is None or isinstance(val, unicode)
         for val in result[1].values():
             assert val is None or isinstance(val, unicode)
         for val in result[2]:
             assert val is None or isinstance(val, unicode)
Example #3
0
 def testNoNameValue(self):
     abcd = [u'a', u'b', u'c', u'd']
     tests = [
               # regular and quoting tests
               (u'd = 4,c=3,b=2,a= 1 ',    [u'd = 4', u'c=3',
                                            u'b=2', u'a= 1']),
               (u'a,b,c,d',                abcd),
               (u' a , b , c , d ',        abcd),
               (u'   a   ',                [u'a']),
               (u'"  a  "',                [u'  a  ']),
               (u'a,b,c,d, "a,b,c,d"',     abcd + [u'a,b,c,d']),
               (u'quote " :), b',          [u'quote " :)', u'b']),
               (u'"quote "" :)", b',       [u'quote " :)', u'b']),
               (u'"unended quote',         [u'"unended quote']),
               (u'"',                      [u'"']),
               (u'd=d,e="a,b,c,d"',        [u'd=d', u'e="a', u'b',
                                            u'c', u'd"']),
             ]
     for args, expected in tests:
         result = wikiutil.parse_quoted_separated(args, name_value=False)
         assert expected == result
         for val in result:
             assert val is None or isinstance(val, unicode)
Example #4
0
def parseargs(request, args, defpagename, defyear, defmonth, defoffset,
              defoffset2, defheight6, defanniversary, deftemplate):
    """ parse macro arguments """
    args = wikiutil.parse_quoted_separated(args, name_value=False)
    args += [None] * 8  # fill up with None to trigger defaults
    parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, parmanniversary, parmtemplate = args[:
                                                                                                                  8]
    parmpagename = wikiutil.get_unicode(request, parmpagename, 'pagename',
                                        defpagename)
    parmyear = wikiutil.get_int(request, parmyear, 'year', defyear)
    parmmonth = wikiutil.get_int(request, parmmonth, 'month', defmonth)
    parmoffset = wikiutil.get_int(request, parmoffset, 'offset', defoffset)
    parmoffset2 = wikiutil.get_int(request, parmoffset2, 'offset2', defoffset2)
    parmheight6 = wikiutil.get_bool(request, parmheight6, 'height6',
                                    defheight6)
    parmanniversary = wikiutil.get_bool(request, parmanniversary,
                                        'anniversary', defanniversary)
    parmtemplate = wikiutil.get_unicode(request, parmtemplate, 'template',
                                        deftemplate)

    # multiple pagenames separated by "*" - split into list of pagenames
    parmpagename = re.split(r'\*', parmpagename)

    return parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, parmanniversary, parmtemplate
Example #5
0
 def _check(a, e):
     r = wikiutil.parse_quoted_separated(a)
     assert r == e
Example #6
0
 def testMacroArgs(self):
     abcd = [u'a', u'b', u'c', u'd']
     abcd_dict = {u'a': u'1', u'b': u'2', u'c': u'3', u'd': u'4'}
     tests = [
               # regular and quoting tests
               (u'd = 4,c=3,b=2,a= 1 ',    ([], abcd_dict, [])),
               (u'a,b,c,d',                (abcd, {}, [])),
               (u' a , b , c , d ',        (abcd, {}, [])),
               (u'   a   ',                ([u'a'], {}, [])),
               (u'"  a  "',                ([u'  a  '], {}, [])),
               (u'a,b,c,d, "a,b,c,d"',     (abcd+[u'a,b,c,d'], {}, [])),
               (u'quote " :), b',          ([u'quote " :)', u'b'], {}, [])),
               (u'"quote "" :)", b',       ([u'quote " :)', u'b'], {}, [])),
               (u'=7',                     ([], {u'': u'7'}, [])),
               (u',,',                     ([None, None, None], {}, [])),
               (u',"",',                   ([None, u'', None], {}, [])),
               (u',"", ""',                ([None, u'', u''], {}, [])),
               (u'  ""  ,"", ""',          ([u'', u'', u''], {}, [])),
               # some name=value test
               (u'd = 4,c=3,b=2,a= 1 ',    ([], abcd_dict, [])),
               (u'd=d,e="a,b,c,d"',        ([], {u'd': u'd',
                                                 u'e': u'a,b,c,d'}, [])),
               (u'd = d,e = "a,b,c,d"',    ([], {u'd': u'd',
                                                 u'e': u'a,b,c,d'}, [])),
               (u'd = d, e = "a,b,c,d"',   ([], {u'd': u'd',
                                                 u'e': u'a,b,c,d'}, [])),
               (u'd = , e = "a,b,c,d"',    ([], {u'd': None,
                                                 u'e': u'a,b,c,d'}, [])),
               (u'd = "", e = "a,b,c,d"',  ([], {u'd': u'',
                                                 u'e': u'a,b,c,d'}, [])),
               (u'd = "", e = ',           ([], {u'd': u'', u'e': None},
                                            [])),
               (u'd=""',                   ([], {u'd': u''}, [])),
               (u'd = "", e = ""',         ([], {u'd': u'', u'e': u''},
                                            [])),
               # no, None as key isn't accepted
               (u' = "",  e = ""',         ([], {u'': u'', u'e': u''},
                                            [])),
               # can quote both name and value:
               (u'd = d," e "= "a,b,c,d"', ([], {u'd': u'd',
                                                 u' e ': u'a,b,c,d'}, [])),
               # trailing args
               (u'1,2,a=b,3,4',            ([u'1', u'2'], {u'a': u'b'},
                                            [u'3', u'4'])),
               # can quote quotes:
               (u'd = """d"',              ([], {u'd': u'"d'}, [])),
               (u'd = """d"""',            ([], {u'd': u'"d"'}, [])),
               (u'd = "d"" ", e=7',        ([], {u'd': u'd" ', u'e': u'7'},
                                            [])),
               (u'd = "d""", e=8',         ([], {u'd': u'd"', u'e': u'8'},
                                            [])),
             ]
     for args, expected in tests:
         result = wikiutil.parse_quoted_separated(args)
         assert expected == result
         for val in result[0]:
             assert val is None or isinstance(val, unicode)
         for val in result[1].keys():
             assert val is None or isinstance(val, unicode)
         for val in result[1].values():
             assert val is None or isinstance(val, unicode)
         for val in result[2]:
             assert val is None or isinstance(val, unicode)
Example #7
0
def execute(macro, args):

    """
    Execute the 'macro' with the given 'args': an optional list of selected
    category names (categories whose pages are to be shown).
    """

    request = macro.request
    fmt = macro.formatter
    page = fmt.page

    # Interpret the arguments.

    try:
        selected_category_names = args and wikiutil.parse_quoted_separated(args, name_value=False) or []
    except AttributeError:
        selected_category_names = args.split(",")

    selected_category_names = [arg for arg in selected_category_names if arg]

    # Get the categories.

    categories = getCategoryMapping(getCategories(request), request)

    # Generate a menu with the categories, together with expanded submenus for
    # the categories employed by the current page, the category represented by
    # the current page, or for those categories specified in the macro
    # arguments.

    output = []
    output.append(fmt.bullet_list(on=1, attr={"class" : "category-menu"}))

    for category in categories:
        category_name, category_pagename = category

        # Work out whether the current page belongs to this category.

        page_is_category = page.page_name == category_pagename
        category_membership_regexp = re.compile(category_membership_regexp_str % category_pagename)
        page_is_in_category = category_membership_regexp.search(page.get_raw_body())

        # Generate the submenu where appropriate.

        if selected_category_names and category_name in selected_category_names or \
            not selected_category_names and (page_is_category or page_is_in_category):

            if page_is_category:
                output.append(fmt.listitem(on=1, attr={"class" : "selected current"}))
                output.append(fmt.text(category_name))
            else:
                output.append(fmt.listitem(on=1, attr={"class" : "selected"}))
                output.append(fmt.pagelink(on=1, pagename=category_pagename))
                output.append(fmt.text(category_name))
                output.append(fmt.pagelink(on=0, pagename=category_pagename))

            output.append(fmt.bullet_list(on=1, attr={"class" : "category-submenu"}))

            # Get the pages and page names in the category.

            pages_in_category = getPages(category_pagename, request)

            # Visit each page in the category.

            last_parts = []

            for page_in_category in pages_in_category:
                pagename = page_in_category.page_name

                # Get a real page, not a result page.

                real_page_in_category = Page(request, pagename)

                # Get a pretty version of the page name.

                pretty_pagename = getPrettyPageName(real_page_in_category)

                if page.page_name == pagename:
                    output.append(fmt.listitem(on=1, attr={"class" : "selected"}))
                else:
                    output.append(fmt.listitem(on=1))

                # Abbreviate long hierarchical names.

                parts = pretty_pagename.split(u" ?")
                common = 0
                for last, current in map(None, last_parts, parts):
                    if last == current:
                        common += 1
                    else:
                        break

                # Use the arrows to indicate subpages.

                prefix = u" ?" * common
                suffix = u" ?".join(parts[common:])

                output.append(fmt.text(prefix))

                # Link to the page using the pretty name.

                output.append(linkToPage(request, real_page_in_category, suffix))
                output.append(fmt.listitem(on=0))

                last_parts = parts

            output.append(fmt.bullet_list(on=0))
            output.append(fmt.listitem(on=0))

        # Otherwise generate a simple link.

        else:
            output.append(fmt.listitem(on=1))
            output.append(fmt.pagelink(on=1, pagename=category_pagename))
            output.append(fmt.text(category_name))
            output.append(fmt.pagelink(on=0, pagename=category_pagename))
            output.append(fmt.listitem(on=0))

    output.append(fmt.bullet_list(on=0))

    return ''.join(output)
Example #8
0
def execute(macro, args):

    """
    Execute the 'macro' with the given 'args': an optional list of selected
    category names (categories whose pages are to be shown), together with
    optional named arguments of the following forms:

      start=YYYY-MM     shows event details starting from the specified month
      start=current-N   shows event details relative to the current month
      end=YYYY-MM       shows event details ending at the specified month
      end=current+N     shows event details relative to the current month

      mode=calendar     shows a calendar view of events
      mode=list         shows a list of events by month
      mode=table        shows a table of events

      names=daily       shows the name of an event on every day of that event
      names=weekly      shows the name of an event once per week

      calendar=NAME     uses the given NAME to provide request parameters which
                        can be used to control the calendar view

      template=PAGE     uses the given PAGE as the default template for new
                        events (or the default template from the configuration
                        if not specified)

      parent=PAGE       uses the given PAGE as the parent of any new event page
    """

    request = macro.request
    fmt = macro.formatter
    page = fmt.page
    _ = request.getText

    # Interpret the arguments.

    try:
        parsed_args = args and wikiutil.parse_quoted_separated(args, name_value=False) or []
    except AttributeError:
        parsed_args = args.split(",")

    parsed_args = [arg for arg in parsed_args if arg]

    # Get special arguments.

    category_names = []
    raw_calendar_start = None
    raw_calendar_end = None
    calendar_start = None
    calendar_end = None
    mode = None
    name_usage = "weekly"
    calendar_name = None
    template_name = getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate")
    parent_name = None

    for arg in parsed_args:
        if arg.startswith("start="):
            raw_calendar_start = arg[6:]

        elif arg.startswith("end="):
            raw_calendar_end = arg[4:]

        elif arg.startswith("mode="):
            mode = arg[5:]

        elif arg.startswith("names="):
            name_usage = arg[6:]

        elif arg.startswith("calendar="):
            calendar_name = arg[9:]

        elif arg.startswith("template="):
            template_name = arg[9:]

        elif arg.startswith("parent="):
            parent_name = arg[7:]

        else:
            category_names.append(arg)

    original_calendar_start = calendar_start = EventAggregatorSupport.getParameterMonth(raw_calendar_start)
    original_calendar_end = calendar_end = EventAggregatorSupport.getParameterMonth(raw_calendar_end)

    # Find request parameters to override settings.

    calendar_start = EventAggregatorSupport.getFormMonth(request, calendar_name, "start") or calendar_start
    calendar_end = EventAggregatorSupport.getFormMonth(request, calendar_name, "end") or calendar_end

    mode = EventAggregatorSupport.getQualifiedParameter(request, calendar_name, "mode", mode or "calendar")

    # Get the events.

    events, shown_events, all_shown_events, earliest, latest = \
        EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end)

    # Get a concrete period of time.

    first, last = EventAggregatorSupport.getConcretePeriod(calendar_start, calendar_end, earliest, latest)

    # Define a view of the calendar, retaining useful navigational information.

    view = View(page, calendar_name, raw_calendar_start, raw_calendar_end,
        original_calendar_start, original_calendar_end, calendar_start, calendar_end,
        first, last, category_names, template_name, parent_name, mode, name_usage)

    # Make a calendar.

    output = []

    # Output download controls.

    output.append(fmt.div(on=1, css_class="event-controls"))
    output.append(view.writeDownloadControls())
    output.append(fmt.div(on=0))

    # Output a table.

    if mode == "table":

        # Start of table view output.

        output.append(fmt.table(on=1, attrs={"tableclass" : "event-table"}))

        output.append(fmt.table_row(on=1))
        output.append(fmt.table_cell(on=1, attrs={"class" : "event-table-heading"}))
        output.append(fmt.text(_("Event dates")))
        output.append(fmt.table_cell(on=0))
        output.append(fmt.table_cell(on=1, attrs={"class" : "event-table-heading"}))
        output.append(fmt.text(_("Event location")))
        output.append(fmt.table_cell(on=0))
        output.append(fmt.table_cell(on=1, attrs={"class" : "event-table-heading"}))
        output.append(fmt.text(_("Event details")))
        output.append(fmt.table_cell(on=0))
        output.append(fmt.table_row(on=0))

        # Get the events in order.

        ordered_events = EventAggregatorSupport.getOrderedEvents(all_shown_events)

        # Show the events in order.

        for event in ordered_events:
            event_page = event.getPage()
            event_summary = event.getSummary(parent_name)
            event_details = event.getDetails()

            # Prepare CSS classes with category-related styling.

            css_classes = ["event-table-details"]

            for topic in event_details.get("topics") or event_details.get("categories") or []:

                # Filter the category text to avoid illegal characters.

                css_classes.append("event-table-category-%s" % "".join(filter(lambda c: c.isalnum(), topic)))

            attrs = {"class" : " ".join(css_classes)}

            output.append(fmt.table_row(on=1))

            # Start and end dates.

            output.append(fmt.table_cell(on=1, attrs=attrs))
            output.append(fmt.span(on=1))
            output.append(fmt.text(str(event_details["start"])))
            output.append(fmt.span(on=0))

            if event_details["start"] != event_details["end"]:
                output.append(fmt.text(" - "))
                output.append(fmt.span(on=1))
                output.append(fmt.text(str(event_details["end"])))
                output.append(fmt.span(on=0))

            output.append(fmt.table_cell(on=0))

            # Location.

            output.append(fmt.table_cell(on=1, attrs=attrs))

            if event_details.has_key("location"):
                output.append(fmt.text(event_details["location"]))

            output.append(fmt.table_cell(on=0))

            # Link to the page using the summary.

            output.append(fmt.table_cell(on=1, attrs=attrs))
            output.append(event_page.linkToPage(request, event_summary))
            output.append(fmt.table_cell(on=0))

            output.append(fmt.table_row(on=0))

        # End of table view output.

        output.append(fmt.table(on=0))

    # Output a list or calendar.

    elif mode in ("list", "calendar"):

        # Output top-level information.

        # Start of list view output.

        if mode == "list":
            output.append(fmt.bullet_list(on=1, attr={"class" : "event-listings"}))

        # Visit all months in the requested range, or across known events.

        for month in first.months_until(last):

            # Either output a calendar view...

            if mode == "calendar":

                # Output a month.

                output.append(fmt.table(on=1, attrs={"tableclass" : "event-month"}))

                output.append(fmt.table_row(on=1))
                output.append(fmt.table_cell(on=1, attrs={"class" : "event-month-heading", "colspan" : "21"}))

                # Either write a month heading or produce links for navigable
                # calendars.

                output.append(view.writeMonthHeading(month))

                output.append(fmt.table_cell(on=0))
                output.append(fmt.table_row(on=0))

                # Weekday headings.

                output.append(fmt.table_row(on=1))

                for weekday in range(0, 7):
                    output.append(fmt.table_cell(on=1, attrs={"class" : "event-weekday-heading", "colspan" : "3"}))
                    output.append(fmt.text(_(EventAggregatorSupport.getDayLabel(weekday))))
                    output.append(fmt.table_cell(on=0))

                output.append(fmt.table_row(on=0))

                # Process the days of the month.

                start_weekday, number_of_days = month.month_properties()

                # The start weekday is the weekday of day number 1.
                # Find the first day of the week, counting from below zero, if
                # necessary, in order to land on the first day of the month as
                # day number 1.

                first_day = 1 - start_weekday

                while first_day <= number_of_days:

                    # Find events in this week and determine how to mark them on the
                    # calendar.

                    week_start = month.as_date(max(first_day, 1))
                    week_end = month.as_date(min(first_day + 6, number_of_days))

                    full_coverage, week_slots = EventAggregatorSupport.getCoverage(
                        week_start, week_end, shown_events.get(month, []))

                    # Output a week, starting with the day numbers.

                    output.append(view.writeDayNumbers(first_day, number_of_days, month, full_coverage))

                    # Either generate empty days...

                    if not week_slots:
                        output.append(view.writeEmptyWeek(first_day, number_of_days))

                    # Or generate each set of scheduled events...

                    else:
                        output.append(view.writeWeekSlots(first_day, number_of_days, month, week_end, week_slots))

                    # Process the next week...

                    first_day += 7

                # End of month.

                output.append(fmt.table(on=0))

            # Or output a summary view...

            elif mode == "list":

                # Output a list.

                output.append(fmt.listitem(on=1, attr={"class" : "event-listings-month"}))
                output.append(fmt.div(on=1, attr={"class" : "event-listings-month-heading"}))

                # Either write a month heading or produce links for navigable
                # calendars.

                output.append(view.writeMonthHeading(month))

                output.append(fmt.div(on=0))

                output.append(fmt.bullet_list(on=1, attr={"class" : "event-month-listings"}))

                # Get the events in order.

                ordered_events = EventAggregatorSupport.getOrderedEvents(shown_events.get(month, []))

                # Show the events in order.

                for event in ordered_events:
                    event_page = event.getPage()
                    event_details = event.getDetails()
                    event_summary = event.getSummary(parent_name)

                    output.append(fmt.listitem(on=1, attr={"class" : "event-listing"}))

                    # Link to the page using the summary.

                    output.append(fmt.paragraph(on=1))
                    output.append(event_page.linkToPage(request, event_summary))
                    output.append(fmt.paragraph(on=0))

                    # Start and end dates.

                    output.append(fmt.paragraph(on=1))
                    output.append(fmt.span(on=1))
                    output.append(fmt.text(str(event_details["start"])))
                    output.append(fmt.span(on=0))
                    output.append(fmt.text(" - "))
                    output.append(fmt.span(on=1))
                    output.append(fmt.text(str(event_details["end"])))
                    output.append(fmt.span(on=0))
                    output.append(fmt.paragraph(on=0))

                    # Location.

                    if event_details.has_key("location"):
                        output.append(fmt.paragraph(on=1))
                        output.append(fmt.text(event_details["location"]))
                        output.append(fmt.paragraph(on=1))

                    # Topics.

                    if event_details.has_key("topics") or event_details.has_key("categories"):
                        output.append(fmt.bullet_list(on=1, attr={"class" : "event-topics"}))

                        for topic in event_details.get("topics") or event_details.get("categories") or []:
                            output.append(fmt.listitem(on=1))
                            output.append(fmt.text(topic))
                            output.append(fmt.listitem(on=0))

                        output.append(fmt.bullet_list(on=0))

                    output.append(fmt.listitem(on=0))

                output.append(fmt.bullet_list(on=0))

        # Output top-level information.

        # End of list view output.

        if mode == "list":
            output.append(fmt.bullet_list(on=0))

    # Output view controls.

    output.append(fmt.div(on=1, css_class="event-controls"))
    output.append(view.writeViewControls())
    output.append(fmt.div(on=0))

    return ''.join(output)
Example #9
0
def execute(macro, args):

    """
    Execute the 'macro' with the given 'args': an optional list of selected
    category names (categories whose pages are to be shown), together with
    optional named arguments of the following forms:

      start=YYYY-MM     shows event details starting from the specified month
      start=YYYY-MM-DD  shows event details starting from the specified day
      start=current-N   shows event details relative to the current month
                        (or relative to the current day in "day" mode)
      end=YYYY-MM       shows event details ending at the specified month
      end=YYYY-MM-DD    shows event details ending on the specified day
      end=current+N     shows event details relative to the current month
                        (or relative to the current day in "day" mode)

      mode=calendar     shows a calendar view of events
      mode=day          shows a calendar day view of events
      mode=list         shows a list of events by month
      mode=table        shows a table of events
      mode=map          shows a map of events

      calendar=NAME     uses the given NAME to provide request parameters which
                        can be used to control the calendar view

      template=PAGE     uses the given PAGE as the default template for new
                        events (or the default template from the configuration
                        if not specified)

      parent=PAGE       uses the given PAGE as the parent of any new event page

    Calendar view options:

      names=daily       shows the name of an event on every day of that event
      names=weekly      shows the name of an event once per week

    Map view options:

      map=NAME          uses the given NAME as the map image, where an entry for
                        the map must be found in the EventMaps page (or another
                        page specified in the configuration by the
                        'event_aggregator_maps_page' setting) along with an
                        attached map image
    """

    request = macro.request
    fmt = macro.formatter
    page = fmt.page

    # Interpret the arguments.

    try:
        parsed_args = args and wikiutil.parse_quoted_separated(args, name_value=False) or []
    except AttributeError:
        parsed_args = args.split(",")

    parsed_args = [arg for arg in parsed_args if arg]

    # Get special arguments.

    category_names = []
    remote_sources = []
    search_pattern = None
    raw_calendar_start = None
    raw_calendar_end = None
    calendar_start = None
    calendar_end = None
    raw_mode = None
    mode = None
    name_usage = "weekly"
    calendar_name = None
    template_name = getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate")
    parent_name = None
    map_name = None

    for arg in parsed_args:
        if arg.startswith("start="):
            raw_calendar_start = arg[6:]

        elif arg.startswith("end="):
            raw_calendar_end = arg[4:]

        elif arg.startswith("mode="):
            raw_mode = arg[5:]

        elif arg.startswith("names="):
            name_usage = arg[6:]

        elif arg.startswith("calendar="):
            calendar_name = arg[9:]

        elif arg.startswith("template="):
            template_name = arg[9:]

        elif arg.startswith("parent="):
            parent_name = arg[7:]

        elif arg.startswith("map="):
            map_name = arg[4:]

        elif arg.startswith("source="):
            remote_sources.append(arg[7:])

        elif arg.startswith("search="):
            search_pattern = arg[7:]

        else:
            category_names.append(arg)

    # Find request parameters to override settings.

    mode = getQualifiedParameter(request, calendar_name, "mode", raw_mode or "calendar")

    # Different modes require different levels of precision by default.

    raw_resolution = raw_mode == "day" and "date" or "month"

    resolution = getQualifiedParameter(request, calendar_name, "resolution", mode == "day" and "date" or "month")
    resolution = mode == "calendar" and "month" or resolution

    # Determine the limits of the calendar.

    get_date, get_form_date = get_date_functions(raw_resolution)

    original_calendar_start = calendar_start = get_date(raw_calendar_start)
    original_calendar_end = calendar_end = get_date(raw_calendar_end)

    wider_calendar_start = getFormMonth(request, calendar_name, "wider-start")
    wider_calendar_end = getFormMonth(request, calendar_name, "wider-end")

    get_date, get_form_date = get_date_functions(resolution)

    calendar_start = get_form_date(request, calendar_name, "start") or calendar_start
    calendar_end = get_form_date(request, calendar_name, "end") or calendar_end

    # Get the events according to the resolution of the calendar.

    all_shown_events, first, last = getEventsUsingParameters(
        category_names, search_pattern, remote_sources, calendar_start, calendar_end,
        resolution, request)

    # Define a view of the calendar, retaining useful navigational information.

    view = View(page, calendar_name,
        raw_calendar_start, raw_calendar_end,
        original_calendar_start, original_calendar_end,
        calendar_start, calendar_end,
        wider_calendar_start, wider_calendar_end,
        first, last, category_names, remote_sources, search_pattern, template_name,
        parent_name, mode, raw_resolution, resolution, name_usage, map_name)

    return view.render(all_shown_events)