Scan NWS forecast discussion blocks once
This commit is contained in:
@@ -121,22 +121,30 @@ func ParseForecastDiscussionText(text string) (ForecastDiscussion, error) {
|
||||
IssuedAt: issuedAt.UTC(),
|
||||
}
|
||||
|
||||
if block, ok := extractForecastDiscussionSection(lines, forecastDiscussionSectionForRole(forecastDiscussionSectionRoleKeyMessages)); ok {
|
||||
out.KeyMessages = parseForecastDiscussionKeyMessages(block.body)
|
||||
}
|
||||
if block, ok := extractForecastDiscussionSection(lines, forecastDiscussionSectionForRole(forecastDiscussionSectionRoleShortTerm)); ok {
|
||||
section, err := parseForecastDiscussionTextSection(block)
|
||||
if err != nil {
|
||||
return ForecastDiscussion{}, fmt.Errorf("parse %s: %w", block.heading.section, err)
|
||||
seenRoles := make(map[forecastDiscussionSectionRole]bool, len(forecastDiscussionSectionRoles))
|
||||
for _, block := range parseForecastDiscussionSectionBlocks(lines) {
|
||||
role, ok := forecastDiscussionSectionRoles[block.heading.section]
|
||||
if !ok || seenRoles[role] {
|
||||
continue
|
||||
}
|
||||
out.ShortTerm = §ion
|
||||
}
|
||||
if block, ok := extractForecastDiscussionSection(lines, forecastDiscussionSectionForRole(forecastDiscussionSectionRoleLongTerm)); ok {
|
||||
section, err := parseForecastDiscussionTextSection(block)
|
||||
if err != nil {
|
||||
return ForecastDiscussion{}, fmt.Errorf("parse %s: %w", block.heading.section, err)
|
||||
seenRoles[role] = true
|
||||
|
||||
switch role {
|
||||
case forecastDiscussionSectionRoleKeyMessages:
|
||||
out.KeyMessages = parseForecastDiscussionKeyMessages(block.body)
|
||||
case forecastDiscussionSectionRoleShortTerm:
|
||||
section, err := parseForecastDiscussionTextSection(block)
|
||||
if err != nil {
|
||||
return ForecastDiscussion{}, fmt.Errorf("parse %s: %w", block.heading.section, err)
|
||||
}
|
||||
out.ShortTerm = §ion
|
||||
case forecastDiscussionSectionRoleLongTerm:
|
||||
section, err := parseForecastDiscussionTextSection(block)
|
||||
if err != nil {
|
||||
return ForecastDiscussion{}, fmt.Errorf("parse %s: %w", block.heading.section, err)
|
||||
}
|
||||
out.LongTerm = §ion
|
||||
}
|
||||
out.LongTerm = §ion
|
||||
}
|
||||
|
||||
return out, nil
|
||||
@@ -500,36 +508,42 @@ func isForecastDiscussionHorizontalWhitespace(b byte) bool {
|
||||
return b == ' ' || b == '\t'
|
||||
}
|
||||
|
||||
func forecastDiscussionSectionForRole(role forecastDiscussionSectionRole) string {
|
||||
for section, registeredRole := range forecastDiscussionSectionRoles {
|
||||
if registeredRole == role {
|
||||
return section
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func parseForecastDiscussionSectionBlocks(lines []string) []forecastDiscussionSectionBlock {
|
||||
var blocks []forecastDiscussionSectionBlock
|
||||
var active *forecastDiscussionSectionBlock
|
||||
|
||||
func extractForecastDiscussionSection(lines []string, section string) (forecastDiscussionSectionBlock, bool) {
|
||||
for i, raw := range lines {
|
||||
heading, ok := parseForecastDiscussionSectionHeading(raw)
|
||||
if !ok || heading.section != section {
|
||||
finish := func() {
|
||||
if active == nil {
|
||||
return
|
||||
}
|
||||
blocks = append(blocks, *active)
|
||||
active = nil
|
||||
}
|
||||
|
||||
for _, raw := range lines {
|
||||
line := strings.TrimSpace(raw)
|
||||
if line == "$$" {
|
||||
finish()
|
||||
break
|
||||
}
|
||||
if line == "&&" || strings.Contains(line, "WATCHES/WARNINGS/ADVISORIES") {
|
||||
finish()
|
||||
continue
|
||||
}
|
||||
|
||||
block := forecastDiscussionSectionBlock{heading: heading}
|
||||
for j := i + 1; j < len(lines); j++ {
|
||||
next := strings.TrimSpace(lines[j])
|
||||
if next == "&&" || next == "$$" || strings.Contains(next, "WATCHES/WARNINGS/ADVISORIES") {
|
||||
break
|
||||
}
|
||||
if _, ok := parseForecastDiscussionSectionHeading(next); ok {
|
||||
break
|
||||
}
|
||||
block.body = append(block.body, lines[j])
|
||||
heading, ok := parseForecastDiscussionSectionHeading(raw)
|
||||
if ok {
|
||||
finish()
|
||||
active = &forecastDiscussionSectionBlock{heading: heading}
|
||||
continue
|
||||
}
|
||||
if active != nil {
|
||||
active.body = append(active.body, raw)
|
||||
}
|
||||
return block, true
|
||||
}
|
||||
return forecastDiscussionSectionBlock{}, false
|
||||
finish()
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
func parseForecastDiscussionKeyMessages(body []string) []string {
|
||||
|
||||
Reference in New Issue
Block a user