ifcraftcorpus 1.3.0__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/PKG-INFO +1 -1
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/pyproject.toml +1 -1
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/index.py +120 -43
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/mcp_server.py +18 -3
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/.gitignore +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/LICENSE +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/LICENSE-CONTENT +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/README.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/agent-design/agent_prompt_engineering.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/agent-design/multi_agent_patterns.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/audience-and-access/accessibility_guidelines.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/audience-and-access/audience_targeting.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/audience-and-access/localization_considerations.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/audio_visual_integration.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/collaborative_if_writing.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/creative_workflow_pipeline.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/diegetic_design.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/idea_capture_and_hooks.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/if_platform_tools.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/player_analytics_metrics.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/quality_standards_if.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/research_and_verification.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/testing_interactive_fiction.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/emotional-design/conflict_patterns.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/emotional-design/emotional_beats.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/game-design/mechanics_design_patterns.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/children_and_ya_conventions.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/fantasy_conventions.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/historical_fiction.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/horror_conventions.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/mystery_conventions.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/sci_fi_conventions.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/branching_narrative_construction.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/branching_narrative_craft.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/endings_patterns.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/episodic_serialized_if.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/nonlinear_structure.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/pacing_and_tension.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/romance_and_relationships.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/scene_structure_and_beats.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/scene_transitions.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/character_voice.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/dialogue_craft.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/exposition_techniques.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/narrative_point_of_view.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/prose_patterns.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/subtext_and_implication.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/voice_register_consistency.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/scope-and-planning/scope_and_length.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/world-and-setting/canon_management.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/world-and-setting/setting_as_character.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/world-and-setting/worldbuilding_patterns.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/__init__.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/cli.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/embeddings.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/logging_utils.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/parser.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/providers.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/py.typed +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/src/ifcraftcorpus/search.py +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/README.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/if_genre_consultant.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/if_platform_advisor.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/if_prose_writer.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/if_quality_reviewer.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/if_story_architect.md +0 -0
- {ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/subagents/if_world_curator.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ifcraftcorpus
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Interactive fiction craft corpus with search library and MCP server
|
|
5
5
|
Project-URL: Homepage, https://pvliesdonk.github.io/if-craft-corpus
|
|
6
6
|
Project-URL: Repository, https://github.com/pvliesdonk/if-craft-corpus
|
|
@@ -56,21 +56,58 @@ from ifcraftcorpus.parser import Document, parse_directory
|
|
|
56
56
|
def _sanitize_fts_query(query: str) -> str:
|
|
57
57
|
"""Sanitize a query string for the FTS5 MATCH clause.
|
|
58
58
|
|
|
59
|
-
This function replaces
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
This function replaces special characters that could cause FTS5 syntax
|
|
60
|
+
errors with spaces. This is intended to correctly handle natural language
|
|
61
|
+
queries from LLMs and users, for example transforming:
|
|
62
|
+
- "haunted-house" into "haunted house" (hyphen as NOT operator)
|
|
63
|
+
- "dialogue, subtext" into "dialogue subtext" (comma syntax error)
|
|
63
64
|
|
|
64
65
|
It also collapses any resulting multiple spaces into a single space.
|
|
65
66
|
|
|
67
|
+
Note: This is used as a fallback when raw FTS5 queries fail. The search
|
|
68
|
+
method first tries the raw query to support advanced FTS5 syntax, then
|
|
69
|
+
falls back to sanitized query on syntax errors.
|
|
70
|
+
See https://github.com/pvliesdonk/if-craft-corpus/issues/10
|
|
71
|
+
|
|
66
72
|
Args:
|
|
67
73
|
query: Raw query string from user input.
|
|
68
74
|
|
|
69
75
|
Returns:
|
|
70
76
|
Sanitized query safe for FTS5 MATCH.
|
|
71
77
|
"""
|
|
72
|
-
# Replace
|
|
73
|
-
|
|
78
|
+
# Replace problematic characters with spaces:
|
|
79
|
+
# - hyphen: FTS5 interprets as NOT operator
|
|
80
|
+
# - comma: FTS5 column list syntax
|
|
81
|
+
# - parentheses: FTS5 grouping syntax
|
|
82
|
+
# - curly braces: FTS5 column filter syntax
|
|
83
|
+
# - caret: FTS5 position marker
|
|
84
|
+
# - plus: FTS5 column weight
|
|
85
|
+
# - colon after words could affect column queries, but we preserve it
|
|
86
|
+
# to allow intentional column:value syntax
|
|
87
|
+
# Using str.translate is more efficient for replacing multiple single characters.
|
|
88
|
+
translation_table = str.maketrans("-,(){}^+", " " * 8)
|
|
89
|
+
sanitized = query.translate(translation_table)
|
|
90
|
+
# Collapse whitespace
|
|
91
|
+
return " ".join(sanitized.split())
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _is_fts5_query_error(error: sqlite3.OperationalError) -> bool:
|
|
95
|
+
"""Check if an OperationalError is an FTS5 query parsing error.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
error: The SQLite OperationalError to check.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
True if this is an FTS5 query error that might be recoverable
|
|
102
|
+
by sanitizing the query.
|
|
103
|
+
"""
|
|
104
|
+
msg = str(error).lower()
|
|
105
|
+
# FTS5 syntax errors (e.g., "fts5: syntax error near ','")
|
|
106
|
+
if "fts5" in msg and "syntax error" in msg:
|
|
107
|
+
return True
|
|
108
|
+
# Column errors from FTS5 query parsing (e.g., "no such column: voice")
|
|
109
|
+
# This can happen when hyphens are interpreted as column filters
|
|
110
|
+
return "no such column" in msg
|
|
74
111
|
|
|
75
112
|
|
|
76
113
|
@dataclass
|
|
@@ -359,51 +396,25 @@ class CorpusIndex:
|
|
|
359
396
|
self.add_document(doc)
|
|
360
397
|
return len(documents)
|
|
361
398
|
|
|
362
|
-
def
|
|
399
|
+
def _execute_fts_query(
|
|
363
400
|
self,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
limit: int = 10,
|
|
401
|
+
fts_query: str,
|
|
402
|
+
cluster: str | None,
|
|
403
|
+
limit: int,
|
|
368
404
|
) -> list[SearchResult]:
|
|
369
|
-
"""
|
|
370
|
-
|
|
371
|
-
Performs a keyword search using SQLite FTS5 with BM25 ranking.
|
|
372
|
-
Supports the full FTS5 query syntax for advanced searches.
|
|
405
|
+
"""Execute an FTS5 query and return results.
|
|
373
406
|
|
|
374
407
|
Args:
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
- Phrases: ``"character voice"``
|
|
379
|
-
- Boolean: ``tension AND suspense``, ``horror NOT comedy``
|
|
380
|
-
- Prefix: ``narrat*``
|
|
381
|
-
- Column-specific: ``title:craft``
|
|
382
|
-
|
|
383
|
-
cluster: Optional cluster name to filter results. Only returns
|
|
384
|
-
matches from the specified cluster.
|
|
385
|
-
limit: Maximum number of results to return. Default 10.
|
|
408
|
+
fts_query: The FTS5 query string.
|
|
409
|
+
cluster: Optional cluster filter.
|
|
410
|
+
limit: Maximum results to return.
|
|
386
411
|
|
|
387
412
|
Returns:
|
|
388
|
-
List of
|
|
389
|
-
score in descending order (best matches first).
|
|
413
|
+
List of SearchResult objects.
|
|
390
414
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
>>> results = index.search("dialogue")
|
|
394
|
-
|
|
395
|
-
>>> # Phrase search
|
|
396
|
-
>>> results = index.search('"character voice"')
|
|
397
|
-
|
|
398
|
-
>>> # Boolean with cluster filter
|
|
399
|
-
>>> results = index.search("tension OR suspense",
|
|
400
|
-
... cluster="emotional-design",
|
|
401
|
-
... limit=5)
|
|
415
|
+
Raises:
|
|
416
|
+
sqlite3.OperationalError: If the query has invalid FTS5 syntax.
|
|
402
417
|
"""
|
|
403
|
-
# Build FTS5 query - sanitize to handle special characters
|
|
404
|
-
fts_query = _sanitize_fts_query(query)
|
|
405
|
-
|
|
406
|
-
# Add cluster filter if specified
|
|
407
418
|
where_clause = ""
|
|
408
419
|
params: list[str | int] = [fts_query]
|
|
409
420
|
if cluster:
|
|
@@ -447,6 +458,72 @@ class CorpusIndex:
|
|
|
447
458
|
|
|
448
459
|
return results
|
|
449
460
|
|
|
461
|
+
def search(
|
|
462
|
+
self,
|
|
463
|
+
query: str,
|
|
464
|
+
*,
|
|
465
|
+
cluster: str | None = None,
|
|
466
|
+
limit: int = 10,
|
|
467
|
+
) -> list[SearchResult]:
|
|
468
|
+
"""Search the corpus using FTS5 full-text search.
|
|
469
|
+
|
|
470
|
+
Performs a keyword search using SQLite FTS5 with BM25 ranking.
|
|
471
|
+
Supports the full FTS5 query syntax for advanced searches.
|
|
472
|
+
|
|
473
|
+
The search first attempts to execute the query as-is to support
|
|
474
|
+
advanced FTS5 syntax. If that fails with a syntax error, it falls
|
|
475
|
+
back to a sanitized version of the query that treats special
|
|
476
|
+
characters as word separators.
|
|
477
|
+
|
|
478
|
+
Args:
|
|
479
|
+
query: Search query. Supports FTS5 syntax:
|
|
480
|
+
|
|
481
|
+
- Simple keywords: ``dialogue``
|
|
482
|
+
- Phrases: ``"character voice"``
|
|
483
|
+
- Boolean: ``tension AND suspense``, ``horror NOT comedy``
|
|
484
|
+
- Prefix: ``narrat*``
|
|
485
|
+
- Column-specific: ``title:craft``
|
|
486
|
+
|
|
487
|
+
Natural language queries with punctuation (e.g., "dialogue,
|
|
488
|
+
subtext") are also supported - they will be automatically
|
|
489
|
+
sanitized if they cause syntax errors.
|
|
490
|
+
|
|
491
|
+
cluster: Optional cluster name to filter results. Only returns
|
|
492
|
+
matches from the specified cluster.
|
|
493
|
+
limit: Maximum number of results to return. Default 10.
|
|
494
|
+
|
|
495
|
+
Returns:
|
|
496
|
+
List of :class:`SearchResult` objects, sorted by BM25 relevance
|
|
497
|
+
score in descending order (best matches first).
|
|
498
|
+
|
|
499
|
+
Example:
|
|
500
|
+
>>> # Simple search
|
|
501
|
+
>>> results = index.search("dialogue")
|
|
502
|
+
|
|
503
|
+
>>> # Phrase search
|
|
504
|
+
>>> results = index.search('"character voice"')
|
|
505
|
+
|
|
506
|
+
>>> # Boolean with cluster filter
|
|
507
|
+
>>> results = index.search("tension OR suspense",
|
|
508
|
+
... cluster="emotional-design",
|
|
509
|
+
... limit=5)
|
|
510
|
+
|
|
511
|
+
>>> # Natural language (auto-sanitized)
|
|
512
|
+
>>> results = index.search("dialogue, subtext")
|
|
513
|
+
"""
|
|
514
|
+
# Try raw query first to support advanced FTS5 syntax
|
|
515
|
+
try:
|
|
516
|
+
return self._execute_fts_query(query, cluster, limit)
|
|
517
|
+
except sqlite3.OperationalError as e:
|
|
518
|
+
if not _is_fts5_query_error(e):
|
|
519
|
+
raise
|
|
520
|
+
|
|
521
|
+
# Fallback to sanitized query for natural language input
|
|
522
|
+
sanitized = _sanitize_fts_query(query)
|
|
523
|
+
if not sanitized:
|
|
524
|
+
return []
|
|
525
|
+
return self._execute_fts_query(sanitized, cluster, limit)
|
|
526
|
+
|
|
450
527
|
def list_documents(self) -> list[dict[str, str]]:
|
|
451
528
|
"""List all indexed documents with their metadata.
|
|
452
529
|
|
|
@@ -194,9 +194,24 @@ def search_corpus(
|
|
|
194
194
|
worldbuilding, and genre conventions.
|
|
195
195
|
|
|
196
196
|
Args:
|
|
197
|
-
query: Search query
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
query: Search query. Supports natural language or FTS5 syntax:
|
|
198
|
+
|
|
199
|
+
Natural language examples:
|
|
200
|
+
- "dialogue subtext"
|
|
201
|
+
- "branching narrative"
|
|
202
|
+
- "pacing action scenes"
|
|
203
|
+
|
|
204
|
+
FTS5 advanced syntax:
|
|
205
|
+
- Exact phrases: '"character voice"'
|
|
206
|
+
- Boolean NOT: "dialogue NOT comedy"
|
|
207
|
+
- Boolean OR: "tension OR suspense"
|
|
208
|
+
- Boolean AND: "dialogue AND subtext"
|
|
209
|
+
- Prefix search: "narrat*"
|
|
210
|
+
- Column filter: "title:craft", "cluster:genre-conventions"
|
|
211
|
+
|
|
212
|
+
Natural language queries with punctuation are automatically
|
|
213
|
+
sanitized, so both styles work seamlessly.
|
|
214
|
+
|
|
200
215
|
cluster: Optional topic cluster to filter by. Valid clusters:
|
|
201
216
|
narrative-structure, prose-and-language, genre-conventions,
|
|
202
217
|
audience-and-access, world-and-setting, emotional-design,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/audience-and-access/accessibility_guidelines.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/audience-and-access/audience_targeting.md
RENAMED
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/audio_visual_integration.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/collaborative_if_writing.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/creative_workflow_pipeline.md
RENAMED
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/idea_capture_and_hooks.md
RENAMED
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/player_analytics_metrics.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/quality_standards_if.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/research_and_verification.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/craft-foundations/testing_interactive_fiction.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/genre-conventions/children_and_ya_conventions.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/branching_narrative_craft.md
RENAMED
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/episodic_serialized_if.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/nonlinear_structure.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/pacing_and_tension.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/romance_and_relationships.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/narrative-structure/scene_structure_and_beats.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/exposition_techniques.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/narrative_point_of_view.md
RENAMED
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/subtext_and_implication.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/prose-and-language/voice_register_consistency.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/world-and-setting/setting_as_character.md
RENAMED
|
File without changes
|
{ifcraftcorpus-1.3.0 → ifcraftcorpus-1.4.0}/corpus/world-and-setting/worldbuilding_patterns.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|